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
@@ -27,7 +27,7 @@ export const config: PluginConfig = {
27
27
  'convex/envList', 'convex/envGet', 'convex/logs', 'convex/insights',
28
28
  ],
29
29
  },
30
- docsUrl: null,
30
+ docsUrl: 'https://www.opencastle.dev/docs/plugins#convex',
31
31
  officialDocs: 'https://docs.convex.dev/',
32
32
  mcpPackage: 'convex',
33
33
  };
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: cypress-testing
3
+ description: "Cypress E2E and component testing patterns, commands, selectors, and CI configuration. Use when writing E2E tests, component tests, or configuring Cypress in CI pipelines."
4
+ ---
5
+
6
+ <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the .github/customizations/ directory instead. -->
7
+
8
+ # Cypress Testing
9
+
10
+ Cypress-specific E2E and component testing patterns. For project-specific test configuration and breakpoints, see [testing-config.md](../../customizations/stack/testing-config.md).
11
+
12
+ ## Commands
13
+
14
+ ```bash
15
+ npx cypress open # Open interactive test runner
16
+ npx cypress run # Run tests headlessly (CI)
17
+ npx cypress run --spec "cypress/e2e/auth/**" # Run specific specs
18
+ npx cypress run --browser chrome # Specify browser
19
+ npx cypress run --headed # Run with visible browser
20
+ npx cypress run --component # Run component tests only
21
+ npx cypress run --record # Record to Cypress Cloud
22
+ ```
23
+
24
+ ## Test Structure
25
+
26
+ ```
27
+ cypress/
28
+ ├── e2e/ # E2E test specs
29
+ │ ├── auth/
30
+ │ │ ├── login.cy.ts
31
+ │ │ └── signup.cy.ts
32
+ │ └── dashboard/
33
+ │ └── overview.cy.ts
34
+ ├── fixtures/ # Test data (JSON)
35
+ │ └── users.json
36
+ ├── support/
37
+ │ ├── commands.ts # Custom commands
38
+ │ ├── e2e.ts # E2E support file
39
+ │ └── component.ts # Component test support
40
+ └── downloads/ # Downloaded files during tests
41
+ ```
42
+
43
+ ## Writing Tests
44
+
45
+ ### E2E Test Pattern
46
+
47
+ ```typescript
48
+ // cypress/e2e/auth/login.cy.ts
49
+ describe('Login', () => {
50
+ beforeEach(() => {
51
+ cy.visit('/login');
52
+ });
53
+
54
+ it('should log in with valid credentials', () => {
55
+ cy.get('[data-testid="email-input"]').type('user@example.com');
56
+ cy.get('[data-testid="password-input"]').type('password123');
57
+ cy.get('[data-testid="login-button"]').click();
58
+
59
+ cy.url().should('include', '/dashboard');
60
+ cy.get('[data-testid="user-menu"]').should('be.visible');
61
+ });
62
+
63
+ it('should show error for invalid credentials', () => {
64
+ cy.get('[data-testid="email-input"]').type('wrong@example.com');
65
+ cy.get('[data-testid="password-input"]').type('wrong');
66
+ cy.get('[data-testid="login-button"]').click();
67
+
68
+ cy.get('[data-testid="error-message"]').should('contain', 'Invalid credentials');
69
+ });
70
+ });
71
+ ```
72
+
73
+ ### Custom Commands
74
+
75
+ ```typescript
76
+ // cypress/support/commands.ts
77
+ Cypress.Commands.add('login', (email: string, password: string) => {
78
+ cy.session([email, password], () => {
79
+ cy.visit('/login');
80
+ cy.get('[data-testid="email-input"]').type(email);
81
+ cy.get('[data-testid="password-input"]').type(password);
82
+ cy.get('[data-testid="login-button"]').click();
83
+ cy.url().should('include', '/dashboard');
84
+ });
85
+ });
86
+ ```
87
+
88
+ ## Selector Strategy
89
+
90
+ Priority order for selecting elements:
91
+
92
+ 1. `data-testid` attributes — most resilient to UI changes
93
+ 2. `aria-label` or `role` — accessible and meaningful
94
+ 3. Dedicated CSS classes — avoid styling classes
95
+ 4. **Never** use tag names, auto-generated classes, or fragile CSS paths
96
+
97
+ ## Best Practices
98
+
99
+ - Use `cy.intercept()` to stub/spy on API calls — don't depend on backend state
100
+ - Use `cy.session()` for authentication — avoid logging in before every test
101
+ - Avoid `cy.wait(ms)` — use `cy.intercept()` with aliases instead
102
+ - Assert on visible elements — Cypress auto-retries, so assertions are resilient
103
+ - Keep tests independent — each test should set up its own state
104
+ - Use fixtures for test data — avoid hardcoding values in tests
105
+ - Add `data-testid` attributes to components during development, not retroactively
106
+
107
+ ## CI Configuration
108
+
109
+ ```yaml
110
+ # GitHub Actions example
111
+ cypress:
112
+ runs-on: ubuntu-latest
113
+ steps:
114
+ - uses: actions/checkout@v4
115
+ - uses: cypress-io/github-action@v6
116
+ with:
117
+ build: npm run build
118
+ start: npm run start
119
+ wait-on: 'http://localhost:3000'
120
+ browser: chrome
121
+ ```
122
+
123
+ ## Configuration (cypress.config.ts)
124
+
125
+ ```typescript
126
+ import { defineConfig } from 'cypress';
127
+
128
+ export default defineConfig({
129
+ e2e: {
130
+ baseUrl: 'http://localhost:3000',
131
+ viewportWidth: 1280,
132
+ viewportHeight: 720,
133
+ video: false,
134
+ screenshotOnRunFailure: true,
135
+ defaultCommandTimeout: 10000,
136
+ retries: { runMode: 2, openMode: 0 },
137
+ },
138
+ component: {
139
+ devServer: {
140
+ framework: 'next',
141
+ bundler: 'webpack',
142
+ },
143
+ },
144
+ });
145
+ ```
@@ -0,0 +1,16 @@
1
+ import type { PluginConfig } from '../types.js';
2
+
3
+ export const config: PluginConfig = {
4
+ id: 'cypress',
5
+ name: 'Cypress',
6
+ category: 'tech',
7
+ subCategory: 'e2e-testing',
8
+ label: 'Cypress',
9
+ hint: 'E2E and component testing in the browser',
10
+ skillName: 'cypress-testing',
11
+ authType: 'none',
12
+ envVars: [],
13
+ agentToolMap: {},
14
+ docsUrl: 'https://www.opencastle.dev/docs/plugins#cypress',
15
+ officialDocs: 'https://docs.cypress.io',
16
+ };
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: figma-design
3
+ description: "Figma design-to-code workflows, design token extraction, component inspection, and asset export. Use when translating Figma designs into code, extracting design tokens, or referencing component specs."
4
+ ---
5
+
6
+ <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the .github/customizations/ directory instead. -->
7
+
8
+ # Figma Design
9
+
10
+ Figma-specific design-to-code patterns and MCP tool usage. For project-specific design system details, see the **frontend-design** skill.
11
+
12
+ ## MCP Tools
13
+
14
+ The Figma MCP server enables AI agents to inspect designs directly:
15
+
16
+ | Tool | Purpose | Primary Agents |
17
+ |------|---------|----------------|
18
+ | `figma/get_file` | Retrieve full Figma file structure | UI/UX Expert |
19
+ | `figma/get_file_nodes` | Get specific nodes/frames | UI/UX Expert, Developer |
20
+ | `figma/get_images` | Export nodes as images | UI/UX Expert |
21
+ | `figma/get_comments` | Read design review comments | UI/UX Expert |
22
+ | `figma/get_styles` | Extract color/text/effect styles | Developer |
23
+ | `figma/get_components` | List reusable components | Developer |
24
+
25
+ ## Design-to-Code Workflow
26
+
27
+ 1. **Identify the frame** — get the Figma file URL or node ID from the task
28
+ 2. **Inspect the design** — use `get_file_nodes` to retrieve layout, spacing, colors, typography
29
+ 3. **Extract tokens** — map Figma styles to CSS custom properties or design tokens
30
+ 4. **Build components** — translate Figma components to React/framework components
31
+ 5. **Verify** — compare the implementation against the original design visually
32
+
33
+ ## Design Token Extraction
34
+
35
+ ### From Figma Styles to CSS
36
+
37
+ ```css
38
+ /* Map Figma color styles to CSS custom properties */
39
+ :root {
40
+ /* Primary */
41
+ --color-primary-50: #eff6ff;
42
+ --color-primary-500: #3b82f6;
43
+ --color-primary-900: #1e3a8a;
44
+
45
+ /* Typography (from Figma text styles) */
46
+ --font-heading: 'Inter', sans-serif;
47
+ --font-body: 'Inter', sans-serif;
48
+ --font-size-sm: 0.875rem; /* 14px */
49
+ --font-size-base: 1rem; /* 16px */
50
+ --font-size-lg: 1.125rem; /* 18px */
51
+ --font-size-xl: 1.25rem; /* 20px */
52
+
53
+ /* Spacing (from Figma auto-layout) */
54
+ --space-xs: 4px;
55
+ --space-sm: 8px;
56
+ --space-md: 16px;
57
+ --space-lg: 24px;
58
+ --space-xl: 32px;
59
+ }
60
+ ```
61
+
62
+ ### Translation Rules
63
+
64
+ | Figma Concept | Code Equivalent |
65
+ |---------------|----------------|
66
+ | Auto Layout → horizontal | `display: flex; flex-direction: row` |
67
+ | Auto Layout → vertical | `display: flex; flex-direction: column` |
68
+ | Auto Layout gap | `gap: Npx` |
69
+ | Auto Layout padding | `padding: top right bottom left` |
70
+ | Fill → Hug contents | `width: auto` or `width: fit-content` |
71
+ | Fill → Fixed | `width: Npx` |
72
+ | Fill → Fill container | `flex: 1` or `width: 100%` |
73
+ | Corner radius | `border-radius: Npx` |
74
+ | Drop shadow | `box-shadow: x y blur spread color` |
75
+ | Opacity | `opacity: N` |
76
+
77
+ ## Best Practices
78
+
79
+ - Always extract design tokens systematically — don't hardcode values from visual inspection
80
+ - Use Figma's auto-layout values directly for flex/grid properties
81
+ - Match Figma's responsive breakpoints to the project's breakpoint system
82
+ - Export SVG assets directly from Figma via `get_images` — don't recreate manually
83
+ - Cross-reference Figma component names with the codebase component library
84
+ - When in doubt about values, inspect the Figma node — don't approximate
85
+ - Keep a mapping document between Figma styles and CSS custom properties
@@ -0,0 +1,32 @@
1
+ import type { PluginConfig } from '../types.js';
2
+
3
+ export const config: PluginConfig = {
4
+ id: 'figma',
5
+ name: 'Figma',
6
+ category: 'tech',
7
+ subCategory: 'design',
8
+ label: 'Figma',
9
+ hint: 'Design tokens, component specs, asset export',
10
+ skillName: 'figma-design',
11
+ mcpServerKey: 'Figma',
12
+ mcpConfig: {
13
+ type: 'stdio',
14
+ command: 'npx',
15
+ args: ['-y', '@anthropic/figma-mcp@latest'],
16
+ envFile: '${workspaceFolder}/.env'
17
+ },
18
+ authType: 'env-token',
19
+ envVars: [
20
+ {
21
+ name: 'FIGMA_ACCESS_TOKEN',
22
+ hint: 'Generate at figma.com → Settings → Personal access tokens',
23
+ },
24
+ ],
25
+ agentToolMap: {
26
+ 'ui-ux-expert': ['figma/*'],
27
+ 'developer': ['figma/*'],
28
+ },
29
+ docsUrl: 'https://www.opencastle.dev/docs/plugins#figma',
30
+ officialDocs: 'https://www.figma.com/developers/api',
31
+ mcpPackage: '@anthropic/figma-mcp',
32
+ };
@@ -11,6 +11,16 @@ import { config as jira } from './jira/config.js';
11
11
  import { config as slack } from './slack/config.js';
12
12
  import { config as teams } from './teams/config.js';
13
13
  import { config as chromeDevtools } from './chrome-devtools/config.js';
14
+ import { config as netlify } from './netlify/config.js';
15
+ import { config as turborepo } from './turborepo/config.js';
16
+ import { config as prisma } from './prisma/config.js';
17
+ import { config as cypress } from './cypress/config.js';
18
+ import { config as playwright } from './playwright/config.js';
19
+ import { config as vitest } from './vitest/config.js';
20
+ import { config as figma } from './figma/config.js';
21
+ import { config as resend } from './resend/config.js';
22
+ import { config as nextjs } from './nextjs/config.js';
23
+ import { config as astro } from './astro/config.js';
14
24
 
15
25
  export type { PluginConfig, McpServerConfig, McpInput, EnvVarRequirement } from './types.js';
16
26
 
@@ -24,6 +34,16 @@ export const PLUGINS: Record<string, PluginConfig> = {
24
34
  vercel,
25
35
  nx,
26
36
  'chrome-devtools': chromeDevtools,
37
+ netlify,
38
+ turborepo,
39
+ prisma,
40
+ cypress,
41
+ playwright,
42
+ vitest,
43
+ figma,
44
+ resend,
45
+ nextjs,
46
+ astro,
27
47
  linear,
28
48
  jira,
29
49
  slack,
@@ -4,7 +4,7 @@ export const config: PluginConfig = {
4
4
  id: 'jira',
5
5
  name: 'Jira',
6
6
  category: 'team',
7
- subCategory: 'tracker',
7
+ subCategory: 'task-management',
8
8
  label: 'Jira',
9
9
  hint: 'Atlassian issue tracking via Rovo MCP',
10
10
  skillName: 'jira-management',
@@ -24,7 +24,6 @@ export const config: PluginConfig = {
24
24
  'Jira/getAccessibleAtlassianResources',
25
25
  ],
26
26
  },
27
- docsUrl: null,
27
+ docsUrl: 'https://www.opencastle.dev/docs/plugins#jira',
28
28
  officialDocs: 'https://developer.atlassian.com/cloud/jira/platform/',
29
- mcpPackage: null,
30
29
  };
@@ -4,7 +4,7 @@ export const config: PluginConfig = {
4
4
  id: 'linear',
5
5
  name: 'Linear',
6
6
  category: 'team',
7
- subCategory: 'tracker',
7
+ subCategory: 'task-management',
8
8
  label: 'Linear',
9
9
  hint: 'Issue tracking with MCP integration',
10
10
  skillName: 'linear-task-management',
@@ -28,7 +28,7 @@ export const config: PluginConfig = {
28
28
  'linear/list_teams', 'linear/list_projects', 'linear/get_issue', 'linear/search_issues',
29
29
  ],
30
30
  },
31
- docsUrl: '/guides/linear-setup',
31
+ docsUrl: 'https://www.opencastle.dev/guides/linear-setup',
32
32
  officialDocs: 'https://linear.app/docs',
33
33
  mcpPackage: '@mseep/linear-mcp',
34
34
  };
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: netlify-deployment
3
+ description: "Netlify deployment workflows, serverless functions, edge functions, environment management, and build configuration. Use when deploying to Netlify, writing serverless/edge functions, or troubleshooting builds."
4
+ ---
5
+
6
+ <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the .github/customizations/ directory instead. -->
7
+
8
+ # Netlify Deployment
9
+
10
+ Netlify-specific deployment patterns and conventions. For project-specific deployment architecture, environment variables, and key files, see [deployment-config.md](../../customizations/stack/deployment-config.md).
11
+
12
+ ## Deployment Model
13
+
14
+ Netlify uses Git-based continuous deployment:
15
+
16
+ ```
17
+ main branch → Production deployment (auto)
18
+ feature/* → Deploy preview (auto, unique URL)
19
+ fix/* → Deploy preview (auto, unique URL)
20
+ ```
21
+
22
+ - Every push triggers a build — no manual deploys needed
23
+ - Deploy previews get unique URLs for PR-based testing
24
+ - Instant rollback to any previous deploy from the dashboard
25
+ - Branch deploys can be configured for specific branches beyond `main`
26
+
27
+ ## Build Configuration (netlify.toml)
28
+
29
+ ```toml
30
+ [build]
31
+ command = "npm run build"
32
+ publish = "dist" # or ".next", "out", "build"
33
+
34
+ [build.environment]
35
+ NODE_VERSION = "20"
36
+
37
+ [[redirects]]
38
+ from = "/*"
39
+ to = "/index.html"
40
+ status = 200
41
+ conditions = {Role = ["admin"]}
42
+
43
+ [[headers]]
44
+ for = "/*"
45
+ [headers.values]
46
+ X-Frame-Options = "DENY"
47
+ X-Content-Type-Options = "nosniff"
48
+ Referrer-Policy = "strict-origin-when-cross-origin"
49
+ ```
50
+
51
+ ## Serverless Functions
52
+
53
+ Place functions in `netlify/functions/`:
54
+
55
+ ```typescript
56
+ // netlify/functions/hello.ts
57
+ import type { Handler } from '@netlify/functions';
58
+
59
+ export const handler: Handler = async (event) => {
60
+ return {
61
+ statusCode: 200,
62
+ body: JSON.stringify({ message: 'Hello from Netlify Functions' }),
63
+ };
64
+ };
65
+ ```
66
+
67
+ - Functions are available at `/.netlify/functions/<name>`
68
+ - Supports TypeScript out of the box
69
+ - Default timeout: 10s (extendable to 26s on Pro)
70
+ - Use background functions for long-running tasks (up to 15 min)
71
+
72
+ ## Edge Functions
73
+
74
+ Place edge functions in `netlify/edge-functions/`:
75
+
76
+ ```typescript
77
+ // netlify/edge-functions/geolocation.ts
78
+ import type { Context } from '@netlify/edge-functions';
79
+
80
+ export default async (request: Request, context: Context) => {
81
+ const { country } = context.geo;
82
+ return new Response(`You're visiting from ${country}`);
83
+ };
84
+
85
+ export const config = { path: '/geo' };
86
+ ```
87
+
88
+ - Run at the CDN edge, sub-millisecond cold starts
89
+ - Use for personalization, A/B testing, geo-routing
90
+ - Deno runtime (not Node.js)
91
+
92
+ ## Environment Variables
93
+
94
+ ### Scoping
95
+
96
+ | Scope | When Applied | Use For |
97
+ |-------|-------------|---------|
98
+ | **Production** | `main` deploys | Live secrets, production API keys |
99
+ | **Deploy previews** | All PR/branch builds | Staging/test API keys |
100
+ | **Branch deploy** | Specific branch deploys | Branch-specific overrides |
101
+ | **Local** | `netlify dev` | Local development |
102
+
103
+ ### Best Practices
104
+
105
+ - Set secrets via Netlify UI or CLI (`netlify env:set`) — never commit them
106
+ - Use `netlify dev` to run locally with injected env vars
107
+ - Validate required vars at build time in `netlify.toml`
108
+
109
+ ## Scheduled Functions (Cron)
110
+
111
+ ```typescript
112
+ // netlify/functions/daily-task.ts
113
+ import type { Handler } from '@netlify/functions';
114
+
115
+ export const handler: Handler = async () => {
116
+ // Run daily task
117
+ return { statusCode: 200, body: 'OK' };
118
+ };
119
+
120
+ export const config = {
121
+ schedule: '0 0 * * *', // Daily at midnight UTC
122
+ };
123
+ ```
124
+
125
+ ## Build Troubleshooting
126
+
127
+ 1. **Check build logs** — Netlify UI → Deploys → click failed deploy
128
+ 2. **Common causes:**
129
+ - Missing environment variables
130
+ - Node.js version mismatch (set in `netlify.toml` or `.node-version`)
131
+ - Build command or publish directory mismatch
132
+ - Dependency install failures (check lockfile)
133
+ 3. **Local debugging** — run `netlify build` locally to reproduce
134
+ 4. **Clear cache** — Netlify UI → Deploys → Trigger deploy → Clear cache and deploy
@@ -0,0 +1,31 @@
1
+ import type { PluginConfig } from '../types.js';
2
+
3
+ export const config: PluginConfig = {
4
+ id: 'netlify',
5
+ name: 'Netlify',
6
+ category: 'tech',
7
+ subCategory: 'deployment',
8
+ label: 'Netlify',
9
+ hint: 'Deployment, serverless functions, edge config',
10
+ skillName: 'netlify-deployment',
11
+ mcpServerKey: 'Netlify',
12
+ mcpConfig: {
13
+ type: 'stdio',
14
+ command: 'npx',
15
+ args: ['-y', 'netlify-mcp@latest'],
16
+ },
17
+ authType: 'env-token',
18
+ envVars: [
19
+ {
20
+ name: 'NETLIFY_AUTH_TOKEN',
21
+ hint: 'Generate at app.netlify.com → User Settings → Applications → Personal access tokens',
22
+ },
23
+ ],
24
+ agentToolMap: {
25
+ 'devops-expert': ['netlify/*'],
26
+ 'release-manager': ['netlify/*'],
27
+ },
28
+ docsUrl: 'https://www.opencastle.dev/docs/plugins#netlify',
29
+ officialDocs: 'https://docs.netlify.com',
30
+ mcpPackage: 'netlify-mcp',
31
+ };