opencastle 0.5.1 → 0.6.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 (63) hide show
  1. package/dist/cli/adapters/claude-code.d.ts +2 -2
  2. package/dist/cli/adapters/claude-code.d.ts.map +1 -1
  3. package/dist/cli/adapters/claude-code.js +2 -2
  4. package/dist/cli/adapters/claude-code.js.map +1 -1
  5. package/dist/cli/adapters/cursor.d.ts +2 -2
  6. package/dist/cli/adapters/cursor.d.ts.map +1 -1
  7. package/dist/cli/adapters/cursor.js +2 -2
  8. package/dist/cli/adapters/cursor.js.map +1 -1
  9. package/dist/cli/adapters/vscode.d.ts +2 -2
  10. package/dist/cli/adapters/vscode.d.ts.map +1 -1
  11. package/dist/cli/adapters/vscode.js +2 -2
  12. package/dist/cli/adapters/vscode.js.map +1 -1
  13. package/dist/cli/detect.d.ts +18 -0
  14. package/dist/cli/detect.d.ts.map +1 -0
  15. package/dist/cli/detect.js +428 -0
  16. package/dist/cli/detect.js.map +1 -0
  17. package/dist/cli/gitignore.d.ts.map +1 -1
  18. package/dist/cli/gitignore.js +0 -2
  19. package/dist/cli/gitignore.js.map +1 -1
  20. package/dist/cli/init.d.ts.map +1 -1
  21. package/dist/cli/init.js +17 -3
  22. package/dist/cli/init.js.map +1 -1
  23. package/dist/cli/mcp.d.ts +2 -2
  24. package/dist/cli/mcp.d.ts.map +1 -1
  25. package/dist/cli/mcp.js +2 -2
  26. package/dist/cli/mcp.js.map +1 -1
  27. package/dist/cli/prompt.d.ts +3 -0
  28. package/dist/cli/prompt.d.ts.map +1 -1
  29. package/dist/cli/prompt.js +96 -0
  30. package/dist/cli/prompt.js.map +1 -1
  31. package/dist/cli/stack-config.d.ts +3 -3
  32. package/dist/cli/stack-config.d.ts.map +1 -1
  33. package/dist/cli/stack-config.js +16 -5
  34. package/dist/cli/stack-config.js.map +1 -1
  35. package/dist/cli/types.d.ts +20 -1
  36. package/dist/cli/types.d.ts.map +1 -1
  37. package/dist/cli/update.d.ts.map +1 -1
  38. package/dist/cli/update.js +6 -0
  39. package/dist/cli/update.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/cli/adapters/claude-code.ts +5 -3
  42. package/src/cli/adapters/cursor.ts +5 -3
  43. package/src/cli/adapters/vscode.ts +5 -3
  44. package/src/cli/detect.ts +483 -0
  45. package/src/cli/gitignore.ts +0 -3
  46. package/src/cli/init.ts +18 -3
  47. package/src/cli/mcp.ts +4 -3
  48. package/src/cli/prompt.ts +123 -0
  49. package/src/cli/stack-config.ts +19 -6
  50. package/src/cli/types.ts +21 -1
  51. package/src/cli/update.ts +7 -0
  52. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  53. package/src/orchestrator/agents/api-designer.agent.md +1 -1
  54. package/src/orchestrator/agents/content-engineer.agent.md +1 -1
  55. package/src/orchestrator/agents/database-engineer.agent.md +1 -1
  56. package/src/orchestrator/agents/developer.agent.md +1 -1
  57. package/src/orchestrator/agents/performance-expert.agent.md +1 -1
  58. package/src/orchestrator/agents/researcher.agent.md +16 -0
  59. package/src/orchestrator/agents/reviewer.agent.md +2 -4
  60. package/src/orchestrator/agents/team-lead.agent.md +41 -63
  61. package/src/orchestrator/agents/ui-ux-expert.agent.md +1 -1
  62. package/src/orchestrator/mcp.json +16 -8
  63. package/src/orchestrator/prompts/bootstrap-customizations.prompt.md +53 -6
package/src/cli/prompt.ts CHANGED
@@ -2,6 +2,18 @@ import { createInterface, type Interface } from 'node:readline/promises';
2
2
  import { stdin, stdout } from 'node:process';
3
3
  import type { SelectOption } from './types.js';
4
4
 
5
+ // ── ANSI helpers ──────────────────────────────────────────────────
6
+
7
+ const ESC = '\x1B';
8
+ const CSI = `${ESC}[`;
9
+ const HIDE_CURSOR = `${CSI}?25l`;
10
+ const SHOW_CURSOR = `${CSI}?25h`;
11
+ const ERASE_LINE = `${CSI}2K`;
12
+
13
+ function moveUp(n: number): string {
14
+ return n > 0 ? `${CSI}${n}A` : '';
15
+ }
16
+
5
17
  // ── Line-buffered readline ────────────────────────────────────────
6
18
  // readline.question() drops lines that arrived between calls because
7
19
  // it only listens for the NEXT 'line' event. When piped input
@@ -70,10 +82,121 @@ export function closePrompts(): void {
70
82
 
71
83
  /**
72
84
  * Interactive single-choice selection prompt.
85
+ *
86
+ * TTY mode: arrow-key navigation (↑/↓) with Enter to confirm.
87
+ * Piped mode: falls back to number-based selection for scripts.
73
88
  */
74
89
  export async function select(
75
90
  message: string,
76
91
  options: SelectOption[]
92
+ ): Promise<string> {
93
+ if (stdin.isTTY) {
94
+ return selectInteractive(message, options);
95
+ }
96
+ return selectNumbered(message, options);
97
+ }
98
+
99
+ // ── Arrow-key selection (TTY) ─────────────────────────────────────
100
+
101
+ function renderOptions(
102
+ options: SelectOption[],
103
+ cursor: number,
104
+ initial: boolean
105
+ ): void {
106
+ // Move back up to overwrite previous render (skip on first draw)
107
+ if (!initial) {
108
+ stdout.write(moveUp(options.length));
109
+ }
110
+
111
+ for (let i = 0; i < options.length; i++) {
112
+ const active = i === cursor;
113
+ const marker = active ? '❯' : ' ';
114
+ const hint = options[i].hint ? ` — ${options[i].hint}` : '';
115
+ const label = active
116
+ ? `\x1B[36m${options[i].label}\x1B[0m${hint}`
117
+ : `${options[i].label}${hint}`;
118
+ stdout.write(`${ERASE_LINE}\r ${marker} ${label}\n`);
119
+ }
120
+ }
121
+
122
+ function selectInteractive(
123
+ message: string,
124
+ options: SelectOption[]
125
+ ): Promise<string> {
126
+ return new Promise<string>((resolve) => {
127
+ let cursor = 0;
128
+
129
+ // Pause the readline interface so raw mode can take over
130
+ if (_rl) _rl.pause();
131
+
132
+ stdout.write(`\n ${message}\n\n`);
133
+ stdout.write(HIDE_CURSOR);
134
+ renderOptions(options, cursor, true);
135
+
136
+ stdin.setRawMode(true);
137
+ stdin.resume();
138
+
139
+ const onData = (data: Buffer): void => {
140
+ const key = data.toString();
141
+
142
+ // Arrow up or k
143
+ if (key === `${ESC}[A` || key === 'k') {
144
+ cursor = (cursor - 1 + options.length) % options.length;
145
+ renderOptions(options, cursor, false);
146
+ return;
147
+ }
148
+
149
+ // Arrow down or j
150
+ if (key === `${ESC}[B` || key === 'j') {
151
+ cursor = (cursor + 1) % options.length;
152
+ renderOptions(options, cursor, false);
153
+ return;
154
+ }
155
+
156
+ // Enter
157
+ if (key === '\r' || key === '\n') {
158
+ cleanup();
159
+ // Re-render final state with the selected option highlighted
160
+ stdout.write(moveUp(options.length));
161
+ for (let i = 0; i < options.length; i++) {
162
+ const active = i === cursor;
163
+ const hint = options[i].hint ? ` — ${options[i].hint}` : '';
164
+ const label = active
165
+ ? `\x1B[36m${options[i].label}\x1B[0m${hint}`
166
+ : `\x1B[2m${options[i].label}${hint}\x1B[0m`;
167
+ const marker = active ? '✔' : ' ';
168
+ stdout.write(`${ERASE_LINE}\r ${marker} ${label}\n`);
169
+ }
170
+ stdout.write('\n');
171
+ resolve(options[cursor].value);
172
+ return;
173
+ }
174
+
175
+ // Ctrl+C
176
+ if (key === '\x03') {
177
+ cleanup();
178
+ stdout.write('\n');
179
+ process.exit(130);
180
+ }
181
+ };
182
+
183
+ function cleanup(): void {
184
+ stdin.removeListener('data', onData);
185
+ stdin.setRawMode(false);
186
+ stdout.write(SHOW_CURSOR);
187
+ // Resume readline for subsequent confirm() calls
188
+ if (_rl) _rl.resume();
189
+ }
190
+
191
+ stdin.on('data', onData);
192
+ });
193
+ }
194
+
195
+ // ── Number-based selection (piped / non-TTY) ──────────────────────
196
+
197
+ async function selectNumbered(
198
+ message: string,
199
+ options: SelectOption[]
77
200
  ): Promise<string> {
78
201
  console.log(`\n ${message}\n`);
79
202
  options.forEach((opt, i) => {
@@ -1,4 +1,4 @@
1
- import type { CmsChoice, DbChoice, PmChoice, NotifChoice, StackConfig, CopyDirOptions } from './types.js';
1
+ import type { CmsChoice, DbChoice, PmChoice, NotifChoice, StackConfig, CopyDirOptions, RepoInfo } from './types.js';
2
2
 
3
3
  // ── Skill / Technology labels ─────────────────────────────────
4
4
 
@@ -103,7 +103,12 @@ const NOTIF_MCP_MAP: Record<NotifChoice, string[]> = {
103
103
  };
104
104
 
105
105
  /** Always-included MCP servers */
106
- const CORE_MCP_SERVERS = ['chrome-devtools', 'Vercel'];
106
+ const CORE_MCP_SERVERS = ['chrome-devtools'];
107
+
108
+ /** MCP servers included only when detected in the repo */
109
+ const DETECTED_MCP_MAP: Record<string, string> = {
110
+ vercel: 'Vercel',
111
+ };
107
112
 
108
113
  // ── MCP environment variable requirements ─────────────────────
109
114
 
@@ -145,22 +150,30 @@ export function getExcludedAgents(stack: StackConfig): Set<string> {
145
150
  ]);
146
151
  }
147
152
 
148
- export function getIncludedMcpServers(stack: StackConfig): Set<string> {
149
- return new Set([
153
+ export function getIncludedMcpServers(stack: StackConfig, repoInfo?: RepoInfo): Set<string> {
154
+ const servers = new Set([
150
155
  ...CORE_MCP_SERVERS,
151
156
  ...CMS_MCP_MAP[stack.cms],
152
157
  ...DB_MCP_MAP[stack.db],
153
158
  ...PM_MCP_MAP[stack.pm ?? 'none'],
154
159
  ...NOTIF_MCP_MAP[stack.notifications ?? 'none'],
155
160
  ]);
161
+
162
+ // Add servers for detected deployment targets
163
+ for (const dep of repoInfo?.deployment ?? []) {
164
+ const server = DETECTED_MCP_MAP[dep];
165
+ if (server) servers.add(server);
166
+ }
167
+
168
+ return servers;
156
169
  }
157
170
 
158
171
  /**
159
172
  * Returns env var requirements for the MCP servers included in the stack.
160
173
  * Only returns entries for servers that actually need API keys.
161
174
  */
162
- export function getRequiredMcpEnvVars(stack: StackConfig): McpEnvRequirement[] {
163
- const included = getIncludedMcpServers(stack);
175
+ export function getRequiredMcpEnvVars(stack: StackConfig, repoInfo?: RepoInfo): McpEnvRequirement[] {
176
+ const included = getIncludedMcpServers(stack, repoInfo);
164
177
  return MCP_ENV_REQUIREMENTS.filter((req) => included.has(req.server));
165
178
  }
166
179
 
package/src/cli/types.ts CHANGED
@@ -37,6 +37,25 @@ export interface CopyDirOptions {
37
37
  ) => Promise<string | null> | string | null;
38
38
  }
39
39
 
40
+ /** Combined repository tooling info — auto-detected + user-declared. */
41
+ export interface RepoInfo {
42
+ packageManager?: string;
43
+ monorepo?: string;
44
+ language?: string;
45
+ frameworks?: string[];
46
+ databases?: string[];
47
+ cms?: string[];
48
+ deployment?: string[];
49
+ testing?: string[];
50
+ cicd?: string[];
51
+ styling?: string[];
52
+ auth?: string[];
53
+ pm?: string[];
54
+ notifications?: string[];
55
+ mcpConfig?: boolean;
56
+ configFiles?: string[];
57
+ }
58
+
40
59
  /** OpenCastle project manifest (.opencastle.json). */
41
60
  export interface Manifest {
42
61
  version: string;
@@ -45,6 +64,7 @@ export interface Manifest {
45
64
  updatedAt: string;
46
65
  managedPaths?: ManagedPaths;
47
66
  stack?: StackConfig;
67
+ repoInfo?: RepoInfo;
48
68
  }
49
69
 
50
70
  /** Framework vs customizable file paths. */
@@ -55,7 +75,7 @@ export interface ManagedPaths {
55
75
 
56
76
  /** IDE adapter interface (init/update commands). */
57
77
  export interface IdeAdapter {
58
- install(_pkgRoot: string, _projectRoot: string, _stack?: StackConfig): Promise<CopyResults>;
78
+ install(_pkgRoot: string, _projectRoot: string, _stack?: StackConfig, _repoInfo?: RepoInfo): Promise<CopyResults>;
59
79
  update(_pkgRoot: string, _projectRoot: string, _stack?: StackConfig): Promise<CopyResults>;
60
80
  getManagedPaths(): ManagedPaths;
61
81
  }
package/src/cli/update.ts CHANGED
@@ -74,10 +74,17 @@ export default async function update({
74
74
  const adapter = await ADAPTERS[manifest.ide]()
75
75
  const results = await adapter.update(pkgRoot, projectRoot, manifest.stack)
76
76
 
77
+ // Refresh repo research on update
78
+ const { detectRepoInfo, mergeStackIntoRepoInfo } = await import('./detect.js')
79
+ const repoInfo = await detectRepoInfo(projectRoot)
80
+
77
81
  // Update manifest
78
82
  manifest.version = pkg.version
79
83
  manifest.updatedAt = new Date().toISOString()
80
84
  manifest.managedPaths = adapter.getManagedPaths()
85
+ manifest.repoInfo = manifest.stack
86
+ ? mergeStackIntoRepoInfo(repoInfo, manifest.stack)
87
+ : repoInfo
81
88
  await writeManifest(projectRoot, manifest)
82
89
 
83
90
  console.log(`\n ✓ Updated ${results.copied.length} framework files`)
@@ -1,25 +1,25 @@
1
1
  {
2
- "hash": "5db781f7",
2
+ "hash": "b74383b1",
3
3
  "configHash": "30f8ea04",
4
- "lockfileHash": "5c8845d6",
5
- "browserHash": "7cd54590",
4
+ "lockfileHash": "280174fa",
5
+ "browserHash": "2ec9de9d",
6
6
  "optimized": {
7
7
  "astro > cssesc": {
8
8
  "src": "../../../../../node_modules/cssesc/cssesc.js",
9
9
  "file": "astro___cssesc.js",
10
- "fileHash": "4f4716d0",
10
+ "fileHash": "bb46d6fb",
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": "ceb80226",
16
+ "fileHash": "8270e9c7",
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": "1629d9e9",
22
+ "fileHash": "1cfcd59d",
23
23
  "needsInterop": true
24
24
  }
25
25
  },
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: 'API designer for route architecture, endpoint conventions, request/response schemas, versioning strategy, and API documentation.'
3
3
  name: 'API Designer'
4
- model: Gemini 3.1 Pro
4
+ model: Gemini 3.1 Pro (Preview)
5
5
  tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'read/problems', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search', 'execute/testFailure', 'search/usages']
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: 'Content engineer for CMS schema design, content queries, content modeling, releases, and studio customization.'
3
3
  name: 'Content Engineer'
4
- model: Gemini 3.1 Pro
4
+ model: Gemini 3.1 Pro (Preview)
5
5
  tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'read/problems', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search', 'execute/testFailure', 'search/usages', 'sanity/get_schema', 'sanity/get_sanity_rules', 'sanity/list_sanity_rules', 'sanity/query_documents', 'sanity/get_document', 'sanity/create_documents_from_json', 'sanity/create_documents_from_markdown', 'sanity/patch_document_from_json', 'sanity/patch_document_from_markdown', 'sanity/deploy_schema', 'sanity/publish_documents', 'sanity/unpublish_documents', 'sanity/discard_drafts', 'sanity/list_projects', 'sanity/list_datasets', 'sanity/list_workspace_schemas', 'sanity/list_embeddings_indices', 'sanity/search_docs', 'sanity/read_docs', 'sanity/semantic_search', 'sanity/migration_guide', 'sanity/create_version', 'sanity/generate_image', 'sanity/transform_image', 'sanity/add_cors_origin']
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: 'Database engineer for schema design, migrations, security policies, performance optimization, and auth integration.'
3
3
  name: 'Database Engineer'
4
- model: Gemini 3.1 Pro
4
+ model: Gemini 3.1 Pro (Preview)
5
5
  tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'read/problems', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search', 'execute/testFailure', 'search/usages', 'supabase/apply_migration', 'supabase/execute_sql', 'supabase/list_tables', 'supabase/list_migrations', 'supabase/list_extensions', 'supabase/get_logs', 'supabase/get_project', 'supabase/get_project_url', 'supabase/list_projects', 'supabase/search_docs', 'supabase/generate_typescript_types', 'supabase/get_advisors', 'supabase/create_branch', 'supabase/list_branches']
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: 'Full-stack developer for building pages, components, routing, layouts, API routes, server-side logic, and feature implementation.'
3
3
  name: 'Developer'
4
- model: Gemini 3.1 Pro
4
+ model: Gemini 3.1 Pro (Preview)
5
5
  tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'vscode/getProjectSetupInfo', 'vscode/installExtension', 'vscode/newWorkspace', 'vscode/runCommand', 'read/problems', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search', 'execute/testFailure', 'search/usages', 'nx-mcp-server/nx_project_details', 'nx-mcp-server/nx_workspace', 'nx-mcp-server/nx_generators']
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: 'Performance optimization expert for frontend, backend, and build performance.'
3
3
  name: 'Performance Expert'
4
- model: Gemini 3.1 Pro
4
+ model: Gemini 3.1 Pro (Preview)
5
5
  tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'read/problems', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search', 'execute/testFailure', 'search/usages', 'chrome-devtools/*', 'nx-mcp-server/nx_project_details', 'nx-mcp-server/nx_workspace']
6
6
  ---
7
7
 
@@ -3,6 +3,22 @@ description: 'Codebase exploration specialist for deep research, pattern discove
3
3
  name: 'Researcher'
4
4
  model: GPT-5 mini
5
5
  tools: ['search/codebase', 'search/textSearch', 'search/fileSearch', 'search/usages', 'read/readFile', 'search/listDirectory', 'web/fetch', 'execute/runInTerminal', 'read/terminalLastCommand']
6
+ handoffs:
7
+ - label: Implement Feature
8
+ agent: Team Lead
9
+ prompt: 'Use the implement-feature prompt to implement the following task with full orchestration, validation, and traceability:'
10
+ - label: Fix Bug
11
+ agent: Team Lead
12
+ prompt: 'Use the bug-fix prompt to investigate and fix the following bug with triage, root cause analysis, and verification:'
13
+ - label: Brainstorm
14
+ agent: Team Lead
15
+ prompt: 'Use the brainstorm prompt to explore requirements, approaches, and trade-offs before committing to a plan for:'
16
+ - label: Quick Refinement
17
+ agent: Team Lead
18
+ prompt: 'Use the quick-refinement prompt to handle these follow-up refinements (UI tweaks, polish, adjustments):'
19
+ - label: Generate Task Spec
20
+ agent: Team Lead
21
+ prompt: 'Use the generate-task-spec prompt to create an opencastle.tasks.yml spec for autonomous overnight runs based on:'
6
22
  ---
7
23
 
8
24
  <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the customizations/ directory instead. -->
@@ -1,6 +1,3 @@
1
- <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the customizations/ directory instead. -->
2
-
3
- ```chatagent
4
1
  ---
5
2
  description: 'Mandatory fast reviewer that validates every agent delegation output before acceptance. Checks acceptance criteria, file partitions, regressions, type safety, and security basics.'
6
3
  name: 'Reviewer'
@@ -8,6 +5,8 @@ model: GPT-5 mini
8
5
  tools: [read/readFile, search/codebase, search/fileSearch, search/textSearch, search/listDirectory, read/problems]
9
6
  ---
10
7
 
8
+ <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the customizations/ directory instead. -->
9
+
11
10
  # Reviewer
12
11
 
13
12
  You are a **code reviewer**. Your job is to verify that a delegated task was completed correctly. You produce a structured PASS/FAIL verdict.
@@ -61,4 +60,3 @@ CONFIDENCE: low | medium | high
61
60
  ## Skills
62
61
 
63
62
  Load the **fast-review** skill for the full review protocol, escalation thresholds, and integration details.
64
- ```
@@ -6,69 +6,23 @@ tools: [read/problems, read/readFile, agent/runSubagent, edit/createDirectory, e
6
6
  agents: ['*']
7
7
  handoffs:
8
8
  - label: Implement Feature
9
- agent: Developer
10
- prompt: 'Implement the plan outlined above. Follow the project conventions in .github/instructions/'
11
- send: true
12
- - label: Build UI Components
13
- agent: UI/UX Expert
14
- prompt: 'Build the UI components described above. Follow template patterns and ensure accessibility.'
15
- send: true
16
- - label: Design Schema
17
- agent: Content Engineer
18
- prompt: 'Design and implement the CMS schema changes described above. Write content queries as needed.'
19
- send: true
20
- - label: Create Migration
21
- agent: Database Engineer
22
- prompt: 'Create the database migration and security policies described above.'
23
- send: true
24
- - label: Write & Run Tests
25
- agent: Testing Expert
26
- prompt: 'Write E2E/integration tests and validate UI changes in the browser for the implementation described above.'
27
- send: true
28
- - label: Audit Security
29
- agent: Security Expert
30
- prompt: 'Audit the plan above for security concerns: RLS policies, input validation, auth flows, and header configuration.'
31
- send: true
32
- - label: Optimize Performance
33
- agent: Performance Expert
34
- prompt: 'Analyze and optimize performance for the implementation described above.'
35
- send: true
36
- - label: Deploy & Configure
37
- agent: DevOps Expert
38
- prompt: 'Handle the deployment and infrastructure configuration described above.'
39
- send: true
40
- - label: Process Data
41
- agent: Data Expert
42
- prompt: 'Implement the data pipeline or scraping task described above.'
43
- send: true
44
- - label: Review Architecture
45
- agent: Architect
46
- prompt: 'Review the plan. Challenge assumptions, validate architectural soundness, and assess scalability.'
47
- send: true
48
- - label: Update Documentation
49
- agent: Documentation Writer
50
- prompt: 'Update documentation for the changes described above.'
51
- send: true
52
- - label: Research Codebase
53
- agent: Researcher
54
- prompt: 'Research the codebase for the questions outlined above. Return a structured report with file paths, patterns, and findings.'
55
- send: true
56
- - label: Write Copy
57
- agent: Copywriter
58
- prompt: 'Write the user-facing text described above. Match the existing brand voice and provide variants for key headlines.'
59
- send: true
60
- - label: Optimize SEO
61
- agent: SEO Specialist
62
- prompt: 'Implement the SEO improvements described above. Add meta tags, structured data, and sitemap entries as needed.'
63
- send: true
64
- - label: Design API
65
- agent: API Designer
66
- prompt: 'Design the API contract described above. Define routes, request/response schemas, error cases, and validation.'
67
- send: true
68
- - label: Manage Release
69
- agent: Release Manager
70
- prompt: 'Run pre-release verification, generate changelog, and coordinate the release described above.'
71
- send: true
9
+ agent: Team Lead
10
+ prompt: 'Use the implement-feature prompt to implement the following task with full orchestration, validation, and traceability:'
11
+ - label: Fix Bug
12
+ agent: Team Lead
13
+ prompt: 'Use the bug-fix prompt to investigate and fix the following bug with triage, root cause analysis, and verification:'
14
+ - label: Brainstorm
15
+ agent: Team Lead
16
+ prompt: 'Use the brainstorm prompt to explore requirements, approaches, and trade-offs before committing to a plan for:'
17
+ - label: Quick Refinement
18
+ agent: Team Lead
19
+ prompt: 'Use the quick-refinement prompt to handle these follow-up refinements (UI tweaks, polish, adjustments):'
20
+ - label: Generate Task Spec
21
+ agent: Team Lead
22
+ prompt: 'Use the generate-task-spec prompt to create an opencastle.tasks.yml spec for autonomous overnight runs based on:'
23
+ - label: Resolve PR Comments
24
+ agent: Team Lead
25
+ prompt: 'Use the resolve-pr-comments prompt to resolve the GitHub PR review comments on this PR:'
72
26
  ---
73
27
 
74
28
  <!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the customizations/ directory instead. -->
@@ -101,6 +55,30 @@ You are a **team lead and task orchestrator**. You do **not** implement code you
101
55
  - **memory-merger** — Graduate mature lessons from LESSONS-LEARNED.md into permanent skills/instructions
102
56
  - **agent-hooks** — Lifecycle hooks (session-start, session-end, pre-delegate, post-delegate) for consistent agent behavior
103
57
 
58
+ ## Specialist Agents
59
+
60
+ Delegate to these agents via `runSubagent` (inline) or background sessions. `agents: ['*']` gives access to all.
61
+
62
+ | Agent | Scope | Default delegation prompt |
63
+ |-------|-------|--------------------------|
64
+ | **Developer** | General implementation — features, refactors, bug fixes | Implement the plan outlined above. Follow the project conventions in .github/instructions/ |
65
+ | **UI/UX Expert** | UI components, accessibility, responsive design | Build the UI components described above. Follow template patterns and ensure accessibility. |
66
+ | **Content Engineer** | CMS schema design, content queries, data modeling | Design and implement the CMS schema changes described above. Write content queries as needed. |
67
+ | **Database Engineer** | Migrations, RLS policies, schema changes | Create the database migration and security policies described above. |
68
+ | **Testing Expert** | E2E tests, integration tests, browser validation | Write E2E/integration tests and validate UI changes in the browser for the implementation described above. |
69
+ | **Security Expert** | Auth flows, RLS audit, input validation, headers | Audit the plan above for security concerns: RLS policies, input validation, auth flows, and header configuration. |
70
+ | **Performance Expert** | Bundle size, rendering, caching, Core Web Vitals | Analyze and optimize performance for the implementation described above. |
71
+ | **DevOps Expert** | Deployment, infrastructure, CI/CD, environment config | Handle the deployment and infrastructure configuration described above. |
72
+ | **Data Expert** | Data pipelines, scrapers, ETL, NDJSON processing | Implement the data pipeline or scraping task described above. |
73
+ | **Architect** | Architecture review, scalability, design decisions | Review the plan. Challenge assumptions, validate architectural soundness, and assess scalability. |
74
+ | **Documentation Writer** | Docs, READMEs, ADRs, guides | Update documentation for the changes described above. |
75
+ | **Researcher** | Codebase exploration, pattern discovery, reports | Research the codebase for the questions outlined above. Return a structured report with file paths, patterns, and findings. |
76
+ | **Copywriter** | User-facing text, brand voice, microcopy | Write the user-facing text described above. Match the existing brand voice and provide variants for key headlines. |
77
+ | **SEO Specialist** | Meta tags, structured data, sitemaps, URL strategy | Implement the SEO improvements described above. Add meta tags, structured data, and sitemap entries as needed. |
78
+ | **API Designer** | Route contracts, request/response schemas, validation | Design the API contract described above. Define routes, request/response schemas, error cases, and validation. |
79
+ | **Release Manager** | Pre-release checks, changelog, version coordination | Run pre-release verification, generate changelog, and coordinate the release described above. |
80
+ | **Reviewer** | Code review, acceptance criteria verification | Review the implementation above against the acceptance criteria. Report PASS or BLOCK with specific findings. |
81
+
104
82
  ## Workflow Templates
105
83
 
106
84
  Reproducible execution plans live in `.github/agent-workflows/`. Each template defines phases, agents, exit criteria, and file partitions. See the workflow files directly for the full template catalog — customize per task but follow the phase structure.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: 'UI/UX expert for designing and building accessible, consistent React components with deep knowledge of the design system.'
3
3
  name: 'UI/UX Expert'
4
- model: Gemini 3.1 Pro
4
+ model: Gemini 3.1 Pro (Preview)
5
5
  tools: ['search/changes', 'search/codebase', 'edit/editFiles', 'web/fetch', 'vscode/getProjectSetupInfo', 'vscode/installExtension', 'vscode/newWorkspace', 'vscode/runCommand', 'read/problems', 'execute/getTerminalOutput', 'execute/runInTerminal', 'read/terminalLastCommand', 'read/terminalSelection', 'search', 'execute/testFailure', 'search/usages', 'chrome-devtools/*']
6
6
  ---
7
7
 
@@ -5,12 +5,13 @@
5
5
  "type": "http"
6
6
  },
7
7
  "Contentful": {
8
- "url": "https://mcp.contentful.com/sse",
9
- "type": "http"
8
+ "command": "npx",
9
+ "args": ["-y", "@contentful/mcp-server"],
10
+ "type": "stdio"
10
11
  },
11
12
  "Strapi": {
12
13
  "command": "npx",
13
- "args": ["-y", "@strapi/mcp-server"],
14
+ "args": ["-y", "strapi-mcp"],
14
15
  "type": "stdio"
15
16
  },
16
17
  "Vercel": {
@@ -23,7 +24,7 @@
23
24
  },
24
25
  "Convex": {
25
26
  "command": "npx",
26
- "args": ["-y", "@anthropic-ai/convex-mcp-server"],
27
+ "args": ["-y", "convex@latest", "mcp", "start"],
27
28
  "type": "stdio"
28
29
  },
29
30
  "chrome-devtools": {
@@ -41,7 +42,7 @@
41
42
  "envFile": "${workspaceFolder}/.env"
42
43
  },
43
44
  "Jira": {
44
- "url": "https://mcp.atlassian.com/v2/sse",
45
+ "url": "https://mcp.atlassian.com/v1/mcp",
45
46
  "type": "http"
46
47
  },
47
48
  "Slack": {
@@ -54,8 +55,15 @@
54
55
  }
55
56
  },
56
57
  "Teams": {
57
- "url": "https://mcp.microsoft365.com/mcp",
58
- "type": "http"
58
+ "type": "http",
59
+ "url": "https://agent365.svc.cloud.microsoft/agents/tenants/${input:tenant_id}/servers/mcp_TeamsServer"
59
60
  }
60
- }
61
+ },
62
+ "inputs": [
63
+ {
64
+ "id": "tenant_id",
65
+ "type": "promptString",
66
+ "description": "Microsoft Entra tenant ID (GUID)"
67
+ }
68
+ ]
61
69
  }