opencastle 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +11 -77
  2. package/dist/cli/doctor.d.ts.map +1 -1
  3. package/dist/cli/doctor.js +13 -7
  4. package/dist/cli/doctor.js.map +1 -1
  5. package/dist/cli/init.d.ts.map +1 -1
  6. package/dist/cli/init.js +7 -2
  7. package/dist/cli/init.js.map +1 -1
  8. package/dist/cli/init.test.d.ts +17 -0
  9. package/dist/cli/init.test.d.ts.map +1 -0
  10. package/dist/cli/init.test.js +881 -0
  11. package/dist/cli/init.test.js.map +1 -0
  12. package/dist/cli/mcp.d.ts +9 -0
  13. package/dist/cli/mcp.d.ts.map +1 -1
  14. package/dist/cli/mcp.js +56 -0
  15. package/dist/cli/mcp.js.map +1 -1
  16. package/dist/cli/stack-config-update.test.d.ts +2 -0
  17. package/dist/cli/stack-config-update.test.d.ts.map +1 -0
  18. package/dist/cli/stack-config-update.test.js +185 -0
  19. package/dist/cli/stack-config-update.test.js.map +1 -0
  20. package/dist/cli/stack-config.d.ts +27 -0
  21. package/dist/cli/stack-config.d.ts.map +1 -1
  22. package/dist/cli/stack-config.js +80 -27
  23. package/dist/cli/stack-config.js.map +1 -1
  24. package/dist/cli/types.d.ts +1 -1
  25. package/dist/cli/types.d.ts.map +1 -1
  26. package/dist/cli/update.d.ts.map +1 -1
  27. package/dist/cli/update.js +184 -17
  28. package/dist/cli/update.js.map +1 -1
  29. package/dist/orchestrator/plugins/astro/config.d.ts +3 -0
  30. package/dist/orchestrator/plugins/astro/config.d.ts.map +1 -0
  31. package/dist/orchestrator/plugins/astro/config.js +27 -0
  32. package/dist/orchestrator/plugins/astro/config.js.map +1 -0
  33. package/dist/orchestrator/plugins/chrome-devtools/config.js +2 -2
  34. package/dist/orchestrator/plugins/chrome-devtools/config.js.map +1 -1
  35. package/dist/orchestrator/plugins/contentful/config.js +1 -1
  36. package/dist/orchestrator/plugins/contentful/config.js.map +1 -1
  37. package/dist/orchestrator/plugins/convex/config.js +1 -1
  38. package/dist/orchestrator/plugins/convex/config.js.map +1 -1
  39. package/dist/orchestrator/plugins/cypress/config.d.ts +3 -0
  40. package/dist/orchestrator/plugins/cypress/config.d.ts.map +1 -0
  41. package/dist/orchestrator/plugins/cypress/config.js +15 -0
  42. package/dist/orchestrator/plugins/cypress/config.js.map +1 -0
  43. package/dist/orchestrator/plugins/figma/config.d.ts +3 -0
  44. package/dist/orchestrator/plugins/figma/config.d.ts.map +1 -0
  45. package/dist/orchestrator/plugins/figma/config.js +31 -0
  46. package/dist/orchestrator/plugins/figma/config.js.map +1 -0
  47. package/dist/orchestrator/plugins/index.d.ts.map +1 -1
  48. package/dist/orchestrator/plugins/index.js +20 -0
  49. package/dist/orchestrator/plugins/index.js.map +1 -1
  50. package/dist/orchestrator/plugins/jira/config.d.ts.map +1 -1
  51. package/dist/orchestrator/plugins/jira/config.js +2 -3
  52. package/dist/orchestrator/plugins/jira/config.js.map +1 -1
  53. package/dist/orchestrator/plugins/linear/config.js +2 -2
  54. package/dist/orchestrator/plugins/linear/config.js.map +1 -1
  55. package/dist/orchestrator/plugins/netlify/config.d.ts +3 -0
  56. package/dist/orchestrator/plugins/netlify/config.d.ts.map +1 -0
  57. package/dist/orchestrator/plugins/netlify/config.js +30 -0
  58. package/dist/orchestrator/plugins/netlify/config.js.map +1 -0
  59. package/dist/orchestrator/plugins/nextjs/config.d.ts +3 -0
  60. package/dist/orchestrator/plugins/nextjs/config.d.ts.map +1 -0
  61. package/dist/orchestrator/plugins/nextjs/config.js +35 -0
  62. package/dist/orchestrator/plugins/nextjs/config.js.map +1 -0
  63. package/dist/orchestrator/plugins/nx/config.d.ts.map +1 -1
  64. package/dist/orchestrator/plugins/nx/config.js +2 -3
  65. package/dist/orchestrator/plugins/nx/config.js.map +1 -1
  66. package/dist/orchestrator/plugins/playwright/config.d.ts +3 -0
  67. package/dist/orchestrator/plugins/playwright/config.d.ts.map +1 -0
  68. package/dist/orchestrator/plugins/playwright/config.js +25 -0
  69. package/dist/orchestrator/plugins/playwright/config.js.map +1 -0
  70. package/dist/orchestrator/plugins/prisma/config.d.ts +3 -0
  71. package/dist/orchestrator/plugins/prisma/config.d.ts.map +1 -0
  72. package/dist/orchestrator/plugins/prisma/config.js +25 -0
  73. package/dist/orchestrator/plugins/prisma/config.js.map +1 -0
  74. package/dist/orchestrator/plugins/resend/config.d.ts +3 -0
  75. package/dist/orchestrator/plugins/resend/config.d.ts.map +1 -0
  76. package/dist/orchestrator/plugins/resend/config.js +46 -0
  77. package/dist/orchestrator/plugins/resend/config.js.map +1 -0
  78. package/dist/orchestrator/plugins/sanity/config.d.ts.map +1 -1
  79. package/dist/orchestrator/plugins/sanity/config.js +1 -2
  80. package/dist/orchestrator/plugins/sanity/config.js.map +1 -1
  81. package/dist/orchestrator/plugins/slack/config.js +1 -1
  82. package/dist/orchestrator/plugins/slack/config.js.map +1 -1
  83. package/dist/orchestrator/plugins/strapi/config.js +1 -1
  84. package/dist/orchestrator/plugins/strapi/config.js.map +1 -1
  85. package/dist/orchestrator/plugins/supabase/config.d.ts.map +1 -1
  86. package/dist/orchestrator/plugins/supabase/config.js +1 -2
  87. package/dist/orchestrator/plugins/supabase/config.js.map +1 -1
  88. package/dist/orchestrator/plugins/teams/config.d.ts.map +1 -1
  89. package/dist/orchestrator/plugins/teams/config.js +1 -2
  90. package/dist/orchestrator/plugins/teams/config.js.map +1 -1
  91. package/dist/orchestrator/plugins/turborepo/config.d.ts +3 -0
  92. package/dist/orchestrator/plugins/turborepo/config.d.ts.map +1 -0
  93. package/dist/orchestrator/plugins/turborepo/config.js +15 -0
  94. package/dist/orchestrator/plugins/turborepo/config.js.map +1 -0
  95. package/dist/orchestrator/plugins/types.d.ts +7 -7
  96. package/dist/orchestrator/plugins/types.d.ts.map +1 -1
  97. package/dist/orchestrator/plugins/vercel/config.d.ts.map +1 -1
  98. package/dist/orchestrator/plugins/vercel/config.js +2 -3
  99. package/dist/orchestrator/plugins/vercel/config.js.map +1 -1
  100. package/dist/orchestrator/plugins/vitest/config.d.ts +3 -0
  101. package/dist/orchestrator/plugins/vitest/config.d.ts.map +1 -0
  102. package/dist/orchestrator/plugins/vitest/config.js +15 -0
  103. package/dist/orchestrator/plugins/vitest/config.js.map +1 -0
  104. package/package.json +1 -1
  105. package/src/cli/doctor.ts +14 -7
  106. package/src/cli/init.test.ts +1141 -0
  107. package/src/cli/init.ts +8 -2
  108. package/src/cli/mcp.ts +77 -1
  109. package/src/cli/stack-config-update.test.ts +210 -0
  110. package/src/cli/stack-config.ts +110 -37
  111. package/src/cli/types.ts +1 -1
  112. package/src/cli/update.ts +230 -23
  113. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  114. package/src/orchestrator/agents/api-designer.agent.md +1 -11
  115. package/src/orchestrator/agents/architect.agent.md +1 -9
  116. package/src/orchestrator/agents/content-engineer.agent.md +1 -5
  117. package/src/orchestrator/agents/copywriter.agent.md +1 -9
  118. package/src/orchestrator/agents/data-expert.agent.md +2 -6
  119. package/src/orchestrator/agents/database-engineer.agent.md +1 -6
  120. package/src/orchestrator/agents/developer.agent.md +2 -12
  121. package/src/orchestrator/agents/devops-expert.agent.md +1 -5
  122. package/src/orchestrator/agents/documentation-writer.agent.md +1 -4
  123. package/src/orchestrator/agents/performance-expert.agent.md +1 -5
  124. package/src/orchestrator/agents/release-manager.agent.md +1 -11
  125. package/src/orchestrator/agents/researcher.agent.md +1 -4
  126. package/src/orchestrator/agents/security-expert.agent.md +2 -7
  127. package/src/orchestrator/agents/seo-specialist.agent.md +1 -10
  128. package/src/orchestrator/agents/testing-expert.agent.md +2 -11
  129. package/src/orchestrator/agents/ui-ux-expert.agent.md +3 -10
  130. package/src/orchestrator/customizations/README.md +2 -1
  131. package/src/orchestrator/customizations/agents/skill-matrix.json +106 -0
  132. package/src/orchestrator/customizations/agents/skill-matrix.md +58 -121
  133. package/src/orchestrator/instructions/general.instructions.md +1 -1
  134. package/src/orchestrator/plugins/astro/SKILL.md +288 -0
  135. package/src/orchestrator/plugins/astro/config.ts +28 -0
  136. package/src/orchestrator/plugins/chrome-devtools/config.ts +2 -2
  137. package/src/orchestrator/plugins/contentful/config.ts +1 -1
  138. package/src/orchestrator/plugins/convex/config.ts +1 -1
  139. package/src/orchestrator/plugins/cypress/SKILL.md +145 -0
  140. package/src/orchestrator/plugins/cypress/config.ts +16 -0
  141. package/src/orchestrator/plugins/figma/SKILL.md +85 -0
  142. package/src/orchestrator/plugins/figma/config.ts +32 -0
  143. package/src/orchestrator/plugins/index.ts +20 -0
  144. package/src/orchestrator/plugins/jira/config.ts +2 -3
  145. package/src/orchestrator/plugins/linear/config.ts +2 -2
  146. package/src/orchestrator/plugins/netlify/SKILL.md +134 -0
  147. package/src/orchestrator/plugins/netlify/config.ts +31 -0
  148. package/src/orchestrator/plugins/nextjs/SKILL.md +376 -0
  149. package/src/orchestrator/plugins/nextjs/config.ts +36 -0
  150. package/src/orchestrator/plugins/nx/config.ts +2 -3
  151. package/src/orchestrator/plugins/playwright/SKILL.md +191 -0
  152. package/src/orchestrator/plugins/playwright/config.ts +26 -0
  153. package/src/orchestrator/plugins/prisma/SKILL.md +137 -0
  154. package/src/orchestrator/plugins/prisma/config.ts +26 -0
  155. package/src/orchestrator/plugins/resend/SKILL.md +187 -0
  156. package/src/orchestrator/plugins/resend/config.ts +47 -0
  157. package/src/orchestrator/plugins/sanity/config.ts +1 -2
  158. package/src/orchestrator/plugins/slack/config.ts +1 -1
  159. package/src/orchestrator/plugins/strapi/config.ts +1 -1
  160. package/src/orchestrator/plugins/supabase/config.ts +1 -2
  161. package/src/orchestrator/plugins/teams/config.ts +1 -2
  162. package/src/orchestrator/plugins/turborepo/SKILL.md +121 -0
  163. package/src/orchestrator/plugins/turborepo/config.ts +16 -0
  164. package/src/orchestrator/plugins/types.ts +7 -7
  165. package/src/orchestrator/plugins/vercel/SKILL.md +99 -0
  166. package/src/orchestrator/plugins/vercel/config.ts +2 -3
  167. package/src/orchestrator/plugins/vitest/SKILL.md +166 -0
  168. package/src/orchestrator/plugins/vitest/config.ts +16 -0
  169. package/src/orchestrator/prompts/bootstrap-customizations.prompt.md +6 -4
  170. package/src/orchestrator/prompts/create-skill.prompt.md +6 -7
  171. package/src/orchestrator/skills/agent-hooks/SKILL.md +2 -2
  172. package/src/orchestrator/skills/memory-merger/SKILL.md +1 -1
  173. package/src/orchestrator/skills/nextjs-patterns/SKILL.md +0 -200
package/src/cli/update.ts CHANGED
@@ -1,10 +1,14 @@
1
1
  import { resolve } from 'node:path'
2
2
  import { readFile } from 'node:fs/promises'
3
3
  import { readManifest, writeManifest } from './manifest.js'
4
- import { confirm, closePrompts, c } from './prompt.js'
4
+ import { multiselect, confirm, closePrompts, c } from './prompt.js'
5
5
  import { isLegacyStack, migrateStackConfig, IDE_LABELS } from './types.js'
6
+ import { TECH_PLUGINS, TEAM_PLUGINS } from '../orchestrator/plugins/index.js'
6
7
  import { IDE_ADAPTERS, VALID_IDES } from './adapters/index.js'
7
- import type { CliContext, IdeChoice } from './types.js'
8
+ import { getRequiredMcpEnvVars, updateSkillMatrixFile } from './stack-config.js'
9
+ import { rebuildMcpConfig } from './mcp.js'
10
+ import { detectRepoInfo, mergeStackIntoRepoInfo } from './detect.js'
11
+ import type { CliContext, IdeChoice, TechTool, TeamTool, StackConfig } from './types.js'
8
12
 
9
13
  export default async function update({
10
14
  pkgRoot,
@@ -41,47 +45,193 @@ export default async function update({
41
45
  ) as { version: string }
42
46
 
43
47
  const dryRun = args.includes('--dry-run')
48
+ const forceFlag = args.includes('--force')
49
+ const reconfigureFlag = args.includes('--reconfigure')
44
50
 
45
- if (manifest.version === pkg.version && !args.includes('--force') && !dryRun) {
51
+ const hasVersionUpdate = manifest.version !== pkg.version || forceFlag
52
+ let wantsReconfigure = reconfigureFlag
53
+
54
+ // If no version update and no --reconfigure, offer reconfigure option
55
+ if (!hasVersionUpdate && !wantsReconfigure && !dryRun) {
46
56
  console.log(` Already up to date (v${pkg.version}).`)
57
+ wantsReconfigure = await confirm(
58
+ 'Would you like to change your stack selections?',
59
+ false
60
+ )
61
+ if (!wantsReconfigure) {
62
+ closePrompts()
63
+ return
64
+ }
65
+ }
66
+
67
+ // ── Detect repo info ────────────────────────────────────────────
68
+ const repoInfo = await detectRepoInfo(projectRoot)
69
+
70
+ // ── Reconfigure stack if requested ──────────────────────────────
71
+ const oldStack = manifest.stack
72
+ let newStack: StackConfig | undefined = manifest.stack
73
+ let stackChanged = false
74
+ let addedTools: string[] = []
75
+ let removedTools: string[] = []
76
+
77
+ if (wantsReconfigure) {
78
+ const detectedTools = new Set([
79
+ ...(repoInfo.cms ?? []),
80
+ ...(repoInfo.databases ?? []),
81
+ ...(repoInfo.deployment ?? []),
82
+ ...(repoInfo.monorepo ? [repoInfo.monorepo] : []),
83
+ ...((repoInfo.frameworks ?? []).map((f) => (f === 'next' ? 'nextjs' : f))),
84
+ ])
85
+
86
+ const currentTech = new Set(oldStack?.techTools ?? [])
87
+ const currentTeam = new Set(oldStack?.teamTools ?? [])
88
+
89
+ console.log(`\n ${c.bold('── Tech Tools ────────────────────────────────')}`)
90
+ const techTools = await multiselect(
91
+ 'Which tools does your project use?',
92
+ TECH_PLUGINS.map((p) => ({
93
+ label: p.label,
94
+ hint: p.hint,
95
+ value: p.id,
96
+ selected: oldStack
97
+ ? currentTech.has(p.id as TechTool)
98
+ : p.preselected || detectedTools.has(p.id),
99
+ }))
100
+ )
101
+
102
+ console.log(` ${c.bold('── Team Tools ────────────────────────────────')}`)
103
+ const teamTools = await multiselect(
104
+ 'Which team tools do you use?',
105
+ TEAM_PLUGINS.map((p) => ({
106
+ label: p.label,
107
+ hint: p.hint,
108
+ value: p.id,
109
+ selected: oldStack
110
+ ? currentTeam.has(p.id as TeamTool)
111
+ : !!p.preselected,
112
+ }))
113
+ )
114
+
115
+ newStack = {
116
+ ides: ides as IdeChoice[],
117
+ techTools: techTools as TechTool[],
118
+ teamTools: teamTools as TeamTool[],
119
+ }
120
+
121
+ // Compute diff
122
+ const newTechSet = new Set(techTools)
123
+ const newTeamSet = new Set(teamTools)
124
+ const techChanged = !sameSet(currentTech as Set<string>, newTechSet)
125
+ const teamChanged = !sameSet(currentTeam as Set<string>, newTeamSet)
126
+ stackChanged = techChanged || teamChanged
127
+
128
+ if (stackChanged) {
129
+ const oldAll: string[] = [
130
+ ...(oldStack?.techTools ?? []),
131
+ ...(oldStack?.teamTools ?? []),
132
+ ]
133
+ const newAll: string[] = [...techTools, ...teamTools]
134
+ addedTools = newAll.filter((t) => !oldAll.includes(t))
135
+ removedTools = oldAll.filter((t) => !newAll.includes(t))
136
+ }
137
+ }
138
+
139
+ // Nothing to do?
140
+ if (!hasVersionUpdate && !stackChanged) {
141
+ console.log(` No changes to apply.`)
142
+ closePrompts()
47
143
  return
48
144
  }
49
145
 
50
- const ideNames = ides.map((id) => IDE_LABELS[id as IdeChoice] ?? id).join(', ')
51
- console.log(
52
- `\n 🏰 ${c.bold('OpenCastle')} ${dryRun ? 'dry-run' : 'update'}: ${c.dim(`v${manifest.version}`)} → ${c.green(`v${pkg.version}`)}\n`
53
- )
146
+ // ── Summary ─────────────────────────────────────────────────────
147
+ const ideNames = ides
148
+ .map((id) => IDE_LABELS[id as IdeChoice] ?? id)
149
+ .join(', ')
150
+
151
+ if (hasVersionUpdate) {
152
+ console.log(
153
+ `\n 🏰 ${c.bold('OpenCastle')} ${dryRun ? 'dry-run' : 'update'}: ${c.dim(`v${manifest.version}`)} → ${c.green(`v${pkg.version}`)}\n`
154
+ )
155
+ } else {
156
+ console.log(
157
+ `\n 🏰 ${c.bold('OpenCastle')} ${dryRun ? 'dry-run' : 'reconfigure'} ${c.dim(`v${pkg.version}`)}\n`
158
+ )
159
+ }
160
+
54
161
  console.log(` IDEs: ${c.cyan(ideNames)}`)
55
- console.log(` ${c.dim('Framework files will be overwritten.')}`)
56
- console.log(` ${c.dim('Customization files will be preserved.')}\n`)
57
162
 
163
+ if (stackChanged) {
164
+ if (addedTools.length > 0) {
165
+ console.log(` ${c.green('+')} Adding: ${addedTools.join(', ')}`)
166
+ }
167
+ if (removedTools.length > 0) {
168
+ console.log(` ${c.red('−')} Removing: ${removedTools.join(', ')}`)
169
+ }
170
+ } else if (newStack) {
171
+ if (newStack.techTools.length > 0) {
172
+ console.log(` Tech: ${c.green(newStack.techTools.join(', '))}`)
173
+ }
174
+ if (newStack.teamTools.length > 0) {
175
+ console.log(` Team: ${c.green(newStack.teamTools.join(', '))}`)
176
+ }
177
+ }
178
+
179
+ if (hasVersionUpdate) {
180
+ console.log(` ${c.dim('Framework files will be overwritten.')}`)
181
+ console.log(` ${c.dim('Customization files will be preserved.')}`)
182
+ }
183
+ console.log()
184
+
185
+ // ── Dry run ─────────────────────────────────────────────────────
58
186
  if (dryRun) {
59
187
  console.log(` ${c.dim('[dry-run]')} Framework files that would be updated:\n`)
60
188
  for (const p of manifest.managedPaths?.framework ?? []) {
61
189
  console.log(` ${c.yellow('↻')} ${p}`)
62
190
  }
63
- console.log(`\n ${c.dim('[dry-run]')} Customization files that would be preserved:\n`)
191
+ console.log(
192
+ `\n ${c.dim('[dry-run]')} Customization files that would be preserved:\n`
193
+ )
64
194
  for (const p of manifest.managedPaths?.customizable ?? []) {
65
195
  console.log(` ${c.green('✓')} ${p}`)
66
196
  }
197
+ if (stackChanged) {
198
+ console.log()
199
+ if (addedTools.length > 0) {
200
+ console.log(
201
+ ` ${c.dim('[dry-run]')} Skills to add: ${addedTools.join(', ')}`
202
+ )
203
+ }
204
+ if (removedTools.length > 0) {
205
+ console.log(
206
+ ` ${c.dim('[dry-run]')} Skills to remove: ${removedTools.join(', ')}`
207
+ )
208
+ }
209
+ console.log(` ${c.dim('[dry-run]')} Skill matrix would be updated`)
210
+ console.log(` ${c.dim('[dry-run]')} MCP config would be rebuilt`)
211
+ }
67
212
  console.log(`\n ${c.dim('No files were written.')}\n`)
213
+ closePrompts()
68
214
  return
69
215
  }
70
216
 
71
- const proceed = await confirm('Proceed with update?')
217
+ const proceed = await confirm('Proceed?')
72
218
  if (!proceed) {
73
219
  console.log(' Aborted.')
220
+ closePrompts()
74
221
  return
75
222
  }
76
223
 
77
- // Update each IDE
224
+ // ── Update each IDE ─────────────────────────────────────────────
78
225
  let totalCopied = 0
79
226
  let totalCreated = 0
80
- const allManagedPaths = { framework: [] as string[], customizable: [] as string[] }
227
+ const allManagedPaths = {
228
+ framework: [] as string[],
229
+ customizable: [] as string[],
230
+ }
81
231
 
82
232
  for (const ide of ides) {
83
233
  const adapter = await IDE_ADAPTERS[ide]()
84
- const results = await adapter.update(pkgRoot, projectRoot, manifest.stack)
234
+ const results = await adapter.update(pkgRoot, projectRoot, newStack)
85
235
  totalCopied += results.copied.length
86
236
  totalCreated += results.created.length
87
237
 
@@ -90,23 +240,72 @@ export default async function update({
90
240
  allManagedPaths.customizable.push(...managed.customizable)
91
241
  }
92
242
 
93
- // Refresh repo research on update
94
- const { detectRepoInfo, mergeStackIntoRepoInfo } = await import('./detect.js')
95
- const repoInfo = await detectRepoInfo(projectRoot)
243
+ // ── Handle stack changes ────────────────────────────────────────
244
+ if (stackChanged && newStack) {
245
+ // Update skill matrix for each IDE
246
+ for (const ide of ides) {
247
+ await updateSkillMatrixFile(projectRoot, ide, newStack)
248
+ }
96
249
 
97
- // Update manifest
98
- manifest.version = pkg.version
250
+ // Rebuild MCP configs for each IDE
251
+ for (const ide of ides) {
252
+ await rebuildMcpConfig(projectRoot, ide as IdeChoice, newStack, repoInfo)
253
+ }
254
+ }
255
+
256
+ // ── Update manifest ─────────────────────────────────────────────
257
+ if (hasVersionUpdate) manifest.version = pkg.version
99
258
  manifest.ides = ides
100
259
  manifest.updatedAt = new Date().toISOString()
101
260
  manifest.managedPaths = allManagedPaths
102
- manifest.repoInfo = manifest.stack
103
- ? mergeStackIntoRepoInfo(repoInfo, manifest.stack)
261
+ if (newStack) manifest.stack = newStack
262
+ manifest.repoInfo = newStack
263
+ ? mergeStackIntoRepoInfo(repoInfo, newStack)
104
264
  : repoInfo
105
265
  await writeManifest(projectRoot, manifest)
106
266
 
107
- console.log(`\n ${c.green('✓')} Updated ${c.bold(String(totalCopied))} framework files`)
267
+ // ── Results ─────────────────────────────────────────────────────
268
+ console.log(
269
+ `\n ${c.green('✓')} Updated ${c.bold(String(totalCopied))} framework files`
270
+ )
108
271
  if (totalCreated > 0) {
109
- console.log(` ${c.green('+')} Created ${c.bold(String(totalCreated))} new files`)
272
+ console.log(
273
+ ` ${c.green('+')} Created ${c.bold(String(totalCreated))} new files`
274
+ )
275
+ }
276
+ if (stackChanged) {
277
+ console.log(` ${c.green('✓')} Updated skill matrix`)
278
+ console.log(` ${c.green('✓')} Rebuilt MCP config`)
279
+ }
280
+
281
+ // ── Env var notice for new tools ────────────────────────────────
282
+ if (stackChanged && newStack) {
283
+ const envVars = getRequiredMcpEnvVars(newStack, repoInfo)
284
+ if (envVars.length > 0) {
285
+ const oldEnvVars = oldStack
286
+ ? new Set(
287
+ getRequiredMcpEnvVars(oldStack, repoInfo).map((e) => e.envVar)
288
+ )
289
+ : new Set<string>()
290
+ const newEnvVars = envVars.filter((e) => !oldEnvVars.has(e.envVar))
291
+ if (newEnvVars.length > 0) {
292
+ console.log(`\n ${c.yellow('⚠')} New environment variables needed:\n`)
293
+ for (const { envVar, hint } of newEnvVars) {
294
+ console.log(` ${c.bold(envVar)}`)
295
+ console.log(` ${c.dim('└')} ${c.dim(hint)}\n`)
296
+ }
297
+ }
298
+ }
299
+
300
+ // Setup guides for newly added tools
301
+ if (addedTools.includes('slack')) {
302
+ console.log(
303
+ ` ${c.cyan('📖')} Slack MCP requires a Slack App with a bot token.`
304
+ )
305
+ console.log(
306
+ ` Setup guide: ${c.cyan('https://www.opencastle.dev/docs/plugins#slack')}\n`
307
+ )
308
+ }
110
309
  }
111
310
 
112
311
  // ── Reload window message ─────────────────────────────────────
@@ -128,3 +327,11 @@ export default async function update({
128
327
 
129
328
  closePrompts()
130
329
  }
330
+
331
+ function sameSet(a: Set<string>, b: Set<string>): boolean {
332
+ if (a.size !== b.size) return false
333
+ for (const item of a) {
334
+ if (!b.has(item)) return false
335
+ }
336
+ return true
337
+ }
@@ -1,25 +1,25 @@
1
1
  {
2
- "hash": "2334c6c2",
2
+ "hash": "aa158bc8",
3
3
  "configHash": "30f8ea04",
4
- "lockfileHash": "cf5af1b6",
5
- "browserHash": "31dc1dac",
4
+ "lockfileHash": "09e90d1c",
5
+ "browserHash": "2f7bb5ff",
6
6
  "optimized": {
7
7
  "astro > cssesc": {
8
8
  "src": "../../../../../node_modules/cssesc/cssesc.js",
9
9
  "file": "astro___cssesc.js",
10
- "fileHash": "432d0522",
10
+ "fileHash": "ea61e9a5",
11
11
  "needsInterop": true
12
12
  },
13
13
  "astro > aria-query": {
14
14
  "src": "../../../../../node_modules/aria-query/lib/index.js",
15
15
  "file": "astro___aria-query.js",
16
- "fileHash": "5d3ca12d",
16
+ "fileHash": "401c0a39",
17
17
  "needsInterop": true
18
18
  },
19
19
  "astro > axobject-query": {
20
20
  "src": "../../../../../node_modules/axobject-query/lib/index.js",
21
21
  "file": "astro___axobject-query.js",
22
- "fileHash": "4a0f4a6f",
22
+ "fileHash": "15390df2",
23
23
  "needsInterop": true
24
24
  }
25
25
  },
@@ -20,17 +20,7 @@ You are an API designer specializing in route architecture, endpoint conventions
20
20
 
21
21
  ## Skills
22
22
 
23
- ### Capability Slots
24
-
25
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
26
-
27
- - **api-layer** — Route handler patterns, server-side actions, validation libraries, search API architecture
28
- - **framework** — Framework routing conventions, middleware, request lifecycle
29
- - **security** — Input validation, authentication, authorization, rate limiting
30
-
31
- ## API Design Principles
32
-
33
- Load the **api-patterns** skill for comprehensive API design guidelines covering route architecture, request/response schemas, error handling, pagination, versioning, and rate limiting.
23
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
34
24
 
35
25
  ## Guidelines
36
26
 
@@ -32,15 +32,7 @@ When reviewing plans or proposals, **challenge assumptions before implementing**
32
32
 
33
33
  ## Skills
34
34
 
35
- ### Capability Slots
36
-
37
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
38
-
39
- - **monorepo** — Monorepo commands, task caching, affected builds, code generation, project graph
40
-
41
- ### Direct Skills
42
-
43
- - **documentation-standards** — ADR format, documentation templates
35
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
44
36
 
45
37
  ## Architecture Decision Records (ADRs)
46
38
 
@@ -19,11 +19,7 @@ You are a content engineer specializing in CMS schema design, content queries, c
19
19
 
20
20
  ## Skills
21
21
 
22
- ### Capability Slots
23
-
24
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
25
-
26
- - **cms** — Document types, query patterns, schema management, content modeling, search module architecture
22
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
27
23
 
28
24
  ## Guidelines
29
25
 
@@ -20,15 +20,7 @@ You are a copywriter specializing in user-facing text for web applications — U
20
20
 
21
21
  ## Skills
22
22
 
23
- ### Capability Slots
24
-
25
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
26
-
27
- - **cms** — Content model structure, document types, and field schemas for venue descriptions
28
-
29
- ### Direct Skills
30
-
31
- - **documentation-standards** — Writing guidelines and formatting rules
23
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
32
24
 
33
25
  ## Text Categories
34
26
 
@@ -13,11 +13,7 @@ You are an expert in building ETL pipelines, web scrapers, data processors, and
13
13
 
14
14
  ## Skills
15
15
 
16
- ### Capability Slots
17
-
18
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
19
-
20
- - **data-pipeline** — Pipeline architecture, scraper patterns, data format, enrichment workflows, CLI commands, quality standards
16
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
21
17
 
22
18
  ## Critical Rules
23
19
 
@@ -32,7 +28,7 @@ Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
32
28
  - Idempotent imports with `createOrReplace` and deterministic `_id`
33
29
  - Validate with Zod before importing — never import invalid data
34
30
  - Respect `robots.txt` and rate limit all scraping requests
35
- - Use the project's web crawling library for concurrent crawling (see the **data-pipeline** skill)
31
+ - Use the project's web crawling library for concurrent crawling (see the **data-engineering** skill)
36
32
  - Handle errors gracefully — skip bad records, don't halt pipeline
37
33
  - Preserve UTF-8 encoding for special characters and diacritics
38
34
  - Backup before bulk operations
@@ -20,12 +20,7 @@ You are a database engineer specializing in schema design, migrations, row-level
20
20
 
21
21
  ## Skills
22
22
 
23
- ### Capability Slots
24
-
25
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
26
-
27
- - **database** — Schema design, migrations, RLS policies, auth flow, role system, performance patterns
28
- - **security** — Security architecture, vulnerability management (database-specific concerns)
23
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
29
24
 
30
25
  ## Guidelines
31
26
 
@@ -13,21 +13,11 @@ You are a full-stack developer specializing in building pages, components, routi
13
13
 
14
14
  ## Skills
15
15
 
16
- ### Capability Slots
17
-
18
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
19
-
20
- - **framework** — Framework file conventions, rendering model, routing, metadata, project structure
21
- - **ui-library** — Component architecture, hooks, TypeScript integration, styling patterns
22
- - **api-layer** — Route handlers, server-side actions, input validation, external integrations
23
-
24
- ### Direct Skills
25
-
26
- - **validation-gates** — Validation gate definitions and checklist
16
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
27
17
 
28
18
  ## Mandatory Verification
29
19
 
30
- After code changes, always run lint, test, and build for affected projects. The **validation-gates** direct skill provides full gate definitions and checklist.
20
+ After code changes, always run lint, test, and build for affected projects.
31
21
 
32
22
  ## Critical Rules
33
23
 
@@ -19,11 +19,7 @@ You are a DevOps expert specializing in deployments, CI/CD pipelines, cron jobs,
19
19
 
20
20
  ## Skills
21
21
 
22
- ### Capability Slots
23
-
24
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
25
-
26
- - **deployment** — Hosting configuration, cron jobs, build process, environment variables, security headers, caching, middleware
22
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
27
23
 
28
24
  ## Guidelines
29
25
 
@@ -13,10 +13,7 @@ You are a technical documentation specialist. You maintain project documentation
13
13
 
14
14
  ## Skills
15
15
 
16
- ### Direct Skills
17
-
18
- - **documentation-standards** — Templates, directory structure, writing guidelines, markdown formatting rules
19
- - **code-commenting** — Self-documenting code patterns, annotation tags
16
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
20
17
 
21
18
  ## Critical Rules
22
19
 
@@ -19,11 +19,7 @@ You are an expert in frontend and backend performance optimization.
19
19
 
20
20
  ## Skills
21
21
 
22
- ### Capability Slots
23
-
24
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
25
-
26
- - **performance** — Bundle size, code splitting, rendering, data fetching, image optimization, Core Web Vitals, profiling
22
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
27
23
 
28
24
  ## Guidelines
29
25
 
@@ -20,17 +20,7 @@ You are a release manager responsible for pre-release verification, changelog ge
20
20
 
21
21
  ## Skills
22
22
 
23
- ### Capability Slots
24
-
25
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
26
-
27
- - **monorepo** — Affected commands, project dependencies, task execution across projects
28
- - **deployment** — Deployment status, build logs, rollback procedures
29
-
30
- ### Direct Skills
31
-
32
- - **validation-gates** — Full verification gate definitions (lint, test, build, browser checks)
33
- - **documentation-standards** — Changelog format, release notes structure
23
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
34
24
 
35
25
  ## Release Process
36
26
 
@@ -13,10 +13,7 @@ You are a codebase exploration specialist. Your job is to **find information, ma
13
13
 
14
14
  ## Skills
15
15
 
16
- ### Direct Skills
17
-
18
- - **context-map** — File dependency mapping and change impact analysis
19
- - **self-improvement** — Lessons-learned protocol, retry documentation
16
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
20
17
 
21
18
  ## Critical Rules
22
19
 
@@ -9,7 +9,7 @@ tools: ["search/changes", "search/codebase", "edit/editFiles", "web/fetch", "vsc
9
9
 
10
10
  # Security Expert
11
11
 
12
- You are a security expert specializing in authentication, authorization, security headers, input validation, API security, and vulnerability management. Resolve technology-specific details via the **security** and **database** capability slots in the skill matrix.
12
+ You are a security expert specializing in authentication, authorization, security headers, input validation, API security, and vulnerability management.
13
13
 
14
14
  ## Critical Rules
15
15
 
@@ -23,12 +23,7 @@ You are a security expert specializing in authentication, authorization, securit
23
23
 
24
24
  ## Skills
25
25
 
26
- ### Capability Slots
27
-
28
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
29
-
30
- - **security** — Security architecture, headers, CSP, auth, RLS patterns, API security, vulnerability management
31
- - **database** — Database-specific security (RLS policies, migrations, role system)
26
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
32
27
 
33
28
  ## Guidelines
34
29
 
@@ -20,16 +20,7 @@ You are an SEO specialist focused on technical SEO implementation — meta tags,
20
20
 
21
21
  ## Skills
22
22
 
23
- ### Capability Slots
24
-
25
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
26
-
27
- - **framework** — Framework metadata API, routing conventions, rendering model (SSR/SSG/ISR)
28
- - **cms** — Content model structure for generating structured data from venue documents
29
-
30
- ## Technical SEO Areas
31
-
32
- Load the **seo-patterns** skill for comprehensive technical SEO guidelines covering meta tags, structured data, sitemaps, URL strategy, and rendering.
23
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
33
24
 
34
25
  ## Guidelines
35
26
 
@@ -9,20 +9,11 @@ tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'rea
9
9
 
10
10
  # Testing Expert
11
11
 
12
- You are an expert tester who validates UI changes using browser automation (resolved via the **e2e-testing** capability slot) and writes E2E/integration test suites.
12
+ You are an expert tester who validates UI changes using browser automation and writes E2E/integration test suites.
13
13
 
14
14
  ## Skills
15
15
 
16
- ### Capability Slots
17
-
18
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
19
-
20
- - **e2e-testing** — Browser automation tool reference, validation checklist, regression testing, reporting patterns
21
- - **testing** — Test planning templates, coverage requirements, context management, common mistakes
22
-
23
- ### Direct Skills
24
-
25
- - **validation-gates** — Shared validation gate definitions (deterministic checks, cache clearing, regression checks)
16
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
26
17
 
27
18
  ## Context Management
28
19
 
@@ -9,24 +9,17 @@ tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'vsc
9
9
 
10
10
  # UI/UX Expert
11
11
 
12
- You are an expert UI/UX developer specializing in building accessible, visually consistent UI components based on a design system template. Resolve technology-specific details (component library, styling approach) via the **ui-library** capability slot in the skill matrix.
12
+ You are an expert UI/UX developer specializing in building accessible, visually consistent UI components based on a design system template.
13
13
 
14
14
  ## Critical Rules
15
15
 
16
16
  1. **Reference the project template** for design patterns and consistency
17
- 2. **Follow the project's styling approach** for component styles, co-located with components (see the **ui-library** skill)
17
+ 2. **Follow the project's styling approach** for component styles, co-located with components
18
18
  3. **Place shared components in the UI library** — never in app-specific directories
19
19
 
20
20
  ## Skills
21
21
 
22
- ### Capability Slots
23
-
24
- Resolve via [skill-matrix.md](.github/customizations/agents/skill-matrix.md).
25
-
26
- - **design-system** — Design thinking, typography, color/theme, motion, spatial composition, visual quality
27
- - **ui-library** — Component architecture, TypeScript patterns, hooks, styling, testing
28
- - **accessibility** — Keyboard navigation, screen reader semantics, contrast, forms, graphics, tables
29
- - **e2e-testing** — Viewport resize commands and per-breakpoint checklists
22
+ Resolve all skills (slots and direct) via [skill-matrix.json](.github/customizations/agents/skill-matrix.json).
30
23
 
31
24
  ## Guidelines
32
25
 
@@ -25,7 +25,8 @@ Skills reference these files with relative links like `../../customizations/stac
25
25
  | File | Purpose |
26
26
  |------|---------|
27
27
  | `agent-registry.md` | Specialist agents with model tier assignments and scope examples |
28
- | `skill-matrix.md` | Maps capability slots to concrete skill names per agent role |
28
+ | `skill-matrix.json` | Maps capability slots to concrete skill names per agent role (machine-readable) |
29
+ | `skill-matrix.md` | Documentation companion explaining the skill matrix concept |
29
30
 
30
31
  ### `stack/` — Tech stack config
31
32