opencastle 0.32.5 → 0.32.6

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 (69) hide show
  1. package/README.md +13 -3
  2. package/bin/cli.mjs +2 -0
  3. package/package.json +1 -1
  4. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  5. package/src/orchestrator/agents/api-designer.agent.md +25 -34
  6. package/src/orchestrator/agents/architect.agent.md +40 -84
  7. package/src/orchestrator/agents/content-engineer.agent.md +29 -31
  8. package/src/orchestrator/agents/copywriter.agent.md +35 -60
  9. package/src/orchestrator/agents/data-expert.agent.md +24 -30
  10. package/src/orchestrator/agents/database-engineer.agent.md +26 -31
  11. package/src/orchestrator/agents/developer.agent.md +32 -34
  12. package/src/orchestrator/agents/devops-expert.agent.md +31 -26
  13. package/src/orchestrator/agents/documentation-writer.agent.md +29 -29
  14. package/src/orchestrator/agents/performance-expert.agent.md +36 -33
  15. package/src/orchestrator/agents/release-manager.agent.md +25 -34
  16. package/src/orchestrator/agents/researcher.agent.md +41 -95
  17. package/src/orchestrator/agents/reviewer.agent.md +24 -34
  18. package/src/orchestrator/agents/security-expert.agent.md +35 -39
  19. package/src/orchestrator/agents/seo-specialist.agent.md +25 -32
  20. package/src/orchestrator/agents/session-guard.agent.md +20 -79
  21. package/src/orchestrator/agents/team-lead.agent.md +50 -254
  22. package/src/orchestrator/agents/testing-expert.agent.md +37 -49
  23. package/src/orchestrator/agents/ui-ux-expert.agent.md +33 -39
  24. package/src/orchestrator/customizations/KNOWN-ISSUES.md +0 -1
  25. package/src/orchestrator/customizations/agents/skill-matrix.json +12 -0
  26. package/src/orchestrator/instructions/general.instructions.md +24 -84
  27. package/src/orchestrator/plugins/astro/SKILL.md +23 -179
  28. package/src/orchestrator/plugins/convex/SKILL.md +38 -12
  29. package/src/orchestrator/plugins/netlify/SKILL.md +17 -13
  30. package/src/orchestrator/plugins/nextjs/SKILL.md +55 -261
  31. package/src/orchestrator/plugins/nx/SKILL.md +20 -72
  32. package/src/orchestrator/plugins/playwright/SKILL.md +5 -17
  33. package/src/orchestrator/plugins/slack/SKILL.md +28 -190
  34. package/src/orchestrator/plugins/teams/SKILL.md +10 -140
  35. package/src/orchestrator/plugins/vitest/SKILL.md +2 -2
  36. package/src/orchestrator/prompts/bug-fix.prompt.md +25 -63
  37. package/src/orchestrator/prompts/implement-feature.prompt.md +29 -66
  38. package/src/orchestrator/prompts/quick-refinement.prompt.md +31 -66
  39. package/src/orchestrator/skills/accessibility-standards/SKILL.md +50 -105
  40. package/src/orchestrator/skills/agent-hooks/SKILL.md +60 -110
  41. package/src/orchestrator/skills/agent-memory/SKILL.md +44 -93
  42. package/src/orchestrator/skills/api-patterns/SKILL.md +20 -68
  43. package/src/orchestrator/skills/code-commenting/SKILL.md +49 -101
  44. package/src/orchestrator/skills/context-map/SKILL.md +47 -88
  45. package/src/orchestrator/skills/data-engineering/SKILL.md +27 -74
  46. package/src/orchestrator/skills/decomposition/SKILL.md +50 -98
  47. package/src/orchestrator/skills/deployment-infrastructure/SKILL.md +44 -107
  48. package/src/orchestrator/skills/documentation-standards/SKILL.md +28 -89
  49. package/src/orchestrator/skills/fast-review/SKILL.md +51 -276
  50. package/src/orchestrator/skills/frontend-design/SKILL.md +53 -163
  51. package/src/orchestrator/skills/git-workflow/SKILL.md +18 -54
  52. package/src/orchestrator/skills/memory-merger/SKILL.md +51 -88
  53. package/src/orchestrator/skills/observability-logging/SKILL.md +29 -75
  54. package/src/orchestrator/skills/orchestration-protocols/SKILL.md +58 -117
  55. package/src/orchestrator/skills/panel-majority-vote/SKILL.md +65 -140
  56. package/src/orchestrator/skills/performance-optimization/SKILL.md +21 -85
  57. package/src/orchestrator/skills/project-consistency/SKILL.md +62 -281
  58. package/src/orchestrator/skills/react-development/SKILL.md +38 -86
  59. package/src/orchestrator/skills/security-hardening/SKILL.md +40 -84
  60. package/src/orchestrator/skills/self-improvement/SKILL.md +26 -60
  61. package/src/orchestrator/skills/seo-patterns/SKILL.md +40 -105
  62. package/src/orchestrator/skills/session-checkpoints/SKILL.md +26 -68
  63. package/src/orchestrator/skills/team-lead-reference/SKILL.md +66 -206
  64. package/src/orchestrator/skills/testing-workflow/SKILL.md +42 -112
  65. package/src/orchestrator/skills/validation-gates/SKILL.md +39 -170
  66. package/src/orchestrator/snippets/base-output-contract.md +14 -0
  67. package/src/orchestrator/snippets/discovered-issues-policy.md +15 -0
  68. package/src/orchestrator/snippets/logging-mandatory.md +11 -0
  69. package/src/orchestrator/snippets/never-expose-secrets.md +22 -0
@@ -25,133 +25,73 @@ applyTo: '**'
25
25
 
26
26
  ## General Coding Principles
27
27
 
28
- - **Clean Code**: Prioritize readability, maintainability, reusability
29
- - **Self-documenting Code**: Comment WHY, not WHAT — for detailed patterns, load the **code-commenting** skill
30
- - **TypeScript First**: All code in TypeScript with proper types — never `as any`
31
- - **DRY**: Extract reusable logic into functions, custom hooks, or components
32
- - **Feature Grouping**: Co-locate code that changes together; avoid barrel files
33
- - **Shared Code**: Place reusable UI components and data queries in shared libraries
28
+ Clean code, readability, maintainability. TypeScript with proper types (never `as any`). DRY. Co-locate code that changes together; avoid barrel files. Shared code in shared libraries. Comment WHY, not WHAT (load **code-commenting** skill for patterns).
34
29
 
35
30
  ## Technology Standards
36
31
 
37
- Load the corresponding skill for detailed conventions before writing code in that domain. These are **not optional**. See `.opencastle/agents/skill-matrix.json` for the full domain-to-skill mapping.
32
+ Load the corresponding skill before writing code in that domain. See `.opencastle/agents/skill-matrix.json` for domain-to-skill mapping. Key domains: UI Components (**ui-library**), App Framework (**framework**), Accessibility (**accessibility-standards**), Performance (**performance-optimization**), Frontend Design (**frontend-design**).
38
33
 
39
- | Domain | Skill |
40
- |--------|-------|
41
- | UI Components | **ui-library** (via skill matrix) |
42
- | App Framework | **framework** (via skill matrix) |
43
- | Accessibility | **accessibility-standards** |
44
- | Performance | **performance-optimization** |
45
- | Frontend Design | **frontend-design** |
34
+ ## Task Decomposition
46
35
 
47
- ## Task Decomposition Protocol
48
-
49
- Before starting multi-step work, decompose it into individually verifiable tasks:
50
-
51
- 1. **Decompose first** — split the work into the smallest meaningful units before writing any code
52
- 2. **Verify each step** — after completing each unit, verify it (run tests, check types, lint, or visually inspect) before moving to the next
53
- 3. **Choose the right verification** — match the check to the change type:
54
- - Logic change → run unit tests
55
- - Type/interface change → run the project's type-check / lint command (see the **codebase-tool** skill)
56
- - UI change → start dev server and visually inspect in the browser
57
- - Build config change → run a full build
58
- 4. **Batch edits, then build** — group related edits across files, then run one build — not build-per-edit
59
- 5. **Stop and re-plan** — if execution diverges from the plan (unexpected errors, wrong assumptions, scope growth), stop immediately, reassess, and revise the plan before continuing
60
- 6. **When unsure how to verify** — ask the user rather than skipping verification
36
+ Decompose verify each step → batch edits → build once. Re-plan when execution diverges. Match verification to change type. Load **decomposition** skill for templates.
61
37
 
62
38
  ## Testing
63
39
 
64
- - **95% minimum** unit test coverage for all new code
65
- - **Test plan before implementation**: initial state, user interactions, state transitions, edge cases, integration
66
- - **Browser testing mandatory** for any UI change — verified at responsive breakpoints defined in `testing-config.md`
67
- - Load the **testing-workflow** skill for test patterns and the **browser-testing** skill for E2E automation
40
+ 95% minimum unit test coverage. Test plan before implementation. Browser testing mandatory for UI changes. Load **testing-workflow** and **browser-testing** skills.
68
41
 
69
42
  ## Build & Task Commands
70
43
 
71
- Use the project's configured task runner for all build, test, lint, and serve commands. **Never invoke test runners or linters directly** — always use the task runner wrapper.
72
-
73
- Resolve exact commands by loading the **codebase-tool** skill from the skill matrix. Common tasks:
74
-
75
- - **Test** — run project tests (with optional coverage)
76
- - **Lint** — run linter with auto-fix
77
- - **Build** — production build
78
- - **Serve** — start dev server
79
- - **Affected** — run a target for all projects affected by current changes
80
-
81
- **Exception:** Tools without task runner targets may be invoked directly (e.g., CMS CLI commands, database CLI commands). Check the project's task runner config first; only bypass it when no target exists.
44
+ Always use the project's configured task runner. Load **codebase-tool** skill for exact commands. Direct CLI only for tools without task runner targets.
82
45
 
83
46
  ## Documentation
84
47
 
85
- Follow markdown formatting and documentation standards when writing docs. For templates, structure, and detailed patterns, load the **documentation-standards** skill.
48
+ Follow markdown formatting standards. Load **documentation-standards** skill for templates.
86
49
 
87
50
  ## AI Optimization
88
51
 
89
- See [ai-optimization.instructions.md](ai-optimization.instructions.md) for batch processing, tool efficiency, and anti-patterns.
52
+ See [ai-optimization.instructions.md](ai-optimization.instructions.md).
90
53
 
91
54
  ## Project Context
92
55
 
93
- For project-specific context (apps, libraries, tech stack, ports, URLs), see [project.instructions.md](../.opencastle/project.instructions.md).
56
+ See [project.instructions.md](../.opencastle/project.instructions.md).
94
57
 
95
58
  ## Git Workflow
96
59
 
97
- **NEVER commit or push directly to the `main` branch.** All changes go through a feature/fix branch and a pull request. Load the **git-workflow** skill for branch naming, PR rules, and the Delivery Outcome checklist.
60
+ **NEVER push to `main`.** All changes via feature/fix branch PR. Load **git-workflow** skill for branch naming and PR rules.
98
61
 
99
62
  ## Discovered Issues Policy
100
63
 
101
- > **⛔ No issue gets ignored.** Untracked bugs discovered during work are a quality gate failure.
64
+ > Inherits: [discovered-issues-policy](../snippets/discovered-issues-policy.md)
102
65
 
103
- When you encounter a bug unrelated to the current task: check if already tracked in `KNOWN-ISSUES.md` or the task tracker. If NOT tracked, track it (known issue entry or bug ticket). Never assume a pre-existing issue is somebody else's problem. See the **git-workflow** skill for the full procedure.
66
+ See **git-workflow** skill for full tracking procedure.
104
67
 
105
68
  ## Observability Logging
106
69
 
107
- > **⛔ HARD GATE — This is a blocking requirement, not a suggestion.**
108
- > Do NOT respond to the user until you have appended the required log records.
109
- > A session without log records is a failed session — regardless of code quality.
70
+ > Inherits: [logging-mandatory](../snippets/logging-mandatory.md)
110
71
 
111
- **Every agent MUST log every session** to `.opencastle/logs/events.ndjson`. No exceptions. No threshold. No "too small to log." Load the **observability-logging** skill for CLI commands, record schemas, and the full logging checklist.
72
+ Load **observability-logging** skill for CLI commands and schemas.
112
73
 
113
74
  ## Self-Improvement Protocol
114
75
 
115
- > **⛔ HARD GATE — Lessons are the team's collective memory. Skipping them causes repeated failures.**
116
-
117
- 1. **Before starting work:** Read `.opencastle/LESSONS-LEARNED.md` — apply relevant lessons proactively. This is NOT optional.
118
- 2. **During execution:** If you retry with a different approach and it works, use the **self-improvement** skill to add a lesson immediately.
119
- 3. **Update source files:** If the lesson reveals a gap in instruction/skill files, update those files too.
76
+ > **⛔ HARD GATE**Read `.opencastle/LESSONS-LEARNED.md` before starting work. Add lessons via **self-improvement** skill when retries succeed.
120
77
 
121
78
  ## Universal Agent Rules
122
79
 
123
- These rules apply to ALL specialist agents automatically. **Do not duplicate them in individual agent files.**
124
-
125
- 1. **Never delegate** — Specialist agents complete their own work and return results. Never invoke the Team Lead or spawn sub-agents.
126
- 2. **Follow the Discovered Issues Policy** — Track any pre-existing bugs found during your work (see above).
127
- 3. **Read and update lessons** — See Self-Improvement Protocol above.
128
- 4. **Log every session** — See Observability Logging above. This is Constitution rule #6 — a blocking gate, not optional.
80
+ 1. Never delegate (specialists complete their own work)
81
+ 2. Follow Discovered Issues Policy
82
+ 3. Read and update lessons
83
+ 4. Log every session (Constitution rule #6)
129
84
 
130
85
  ## Pre-Response Quality Gate
131
86
 
132
- > **⛔ STOP before responding to the user.** Run through this checklist. If ANY required item is missing, fix it NOW.
133
-
134
- - [ ] **Lessons read** — `LESSONS-LEARNED.md` was read at session start
135
- - [ ] **Lessons captured** — If any retry occurred, a new lesson was added via the **self-improvement** skill
136
- - [ ] **Discovered issues tracked** — Any pre-existing bugs found were tracked (Discovered Issues Policy)
137
- - [ ] **Lint/type/test pass** — No new errors introduced; verification ran after code changes (Constitution rule #5)
138
- - [ ] **Session logged** — `events.ndjson` has a new `session` record (Constitution rule #6 — ALWAYS required)
139
- - [ ] **Delegations logged** — `events.ndjson` has a `delegation` record for each delegation (Team Lead only)
140
- - [ ] **Reviews logged** — `events.ndjson` has a `review` record for each fast review (if any)
141
- - [ ] **Panels logged** — `events.ndjson` has a `panel` record for each panel review (if any)
142
- - [ ] **Agent expertise updated** — `AGENT-EXPERTISE.md` updated for each delegation (strong/weak areas + file familiarity) (Team Lead only)
143
- - [ ] **Knowledge graph appended** — `KNOWLEDGE-GRAPH.md` has new rows for file relationships discovered (Team Lead only)
144
-
145
- Load the **observability-logging** skill for CLI commands, Base Output Contract, and detailed schemas.
146
-
147
- ## Workflow & Governance Skills
87
+ > **⛔ STOP before responding.** Load **observability-logging** skill and run its pre-response checklist.
148
88
 
149
- These skills provide detailed procedures. Load when their phase is reached.
89
+ ## Governance Skills
150
90
 
151
91
  | Concern | Skill |
152
92
  |---------|-------|
153
- | Branch naming, PR rules, delivery outcome, task tracking | **git-workflow** |
154
- | Log CLI commands, record schemas, output contracts | **observability-logging** |
155
- | Lesson writing CLI, categories, quality standards | **self-improvement** |
93
+ | Branching, PR rules, delivery, tracking | **git-workflow** |
94
+ | Log commands, schemas, output contracts | **observability-logging** |
95
+ | Lesson writing, categories, quality | **self-improvement** |
156
96
 
157
97
  <!-- End of Coding Standards -->
@@ -9,64 +9,37 @@ description: "Astro framework best practices for content-driven sites, islands a
9
9
 
10
10
  ## Project Structure
11
11
 
12
- - **Use `src/pages/` directory** for file-based routing. Each `.astro`, `.md`, or `.mdx` file becomes a route.
13
- - Top-level: `src/`, `public/`, `astro.config.mjs`.
14
- - Inside `src/`: `pages/`, `layouts/`, `components/`, `content/`, `styles/`, `assets/`.
15
- - **`public/`** — static assets served as-is (favicons, robots.txt, fonts).
16
- - **`src/assets/`** — images and assets processed by Astro's build pipeline.
12
+ Top-level: `src/`, `public/`, `astro.config.mjs`. Inside `src/`: `pages/`, `layouts/`, `components/`, `content/`, `styles/`, `assets/`. `public/` serves static assets as-is; `src/assets/` goes through Astro's build pipeline.
17
13
 
18
14
  ```
19
15
  src/
20
- ├── pages/
21
- ├── index.astro # → /
22
- ├── about.astro # /about
23
- │ └── blog/
24
- ├── index.astro # → /blog
25
- └── [slug].astro # /blog/:slug
26
- ├── layouts/
27
- │ └── BaseLayout.astro
28
- ├── components/
29
- │ ├── Header.astro
30
- │ └── Counter.tsx # React island
31
- ├── content/
32
- │ └── blog/ # Content collection
33
- │ ├── first-post.md
34
- │ └── second-post.md
35
- └── styles/
36
- └── global.css
16
+ ├── pages/ # file-based routing (.astro, .md, .mdx)
17
+ ├── layouts/ # BaseLayout.astro, etc.
18
+ ├── components/ # .astro + framework components (React islands)
19
+ ├── content/ # Content collections (blog/, docs/, etc.)
20
+ ├── styles/ # global.css
21
+ └── assets/ # processed images
37
22
  ```
38
23
 
39
24
  ## Component Model
40
25
 
41
- **Default: Zero JS** — Astro components (`.astro`) render to HTML with no client-side JavaScript.
26
+ **Default: Zero JS** — `.astro` components render to HTML with no client-side JavaScript.
42
27
 
43
28
  **Islands Architecture** — Interactive components use `client:*` directives to hydrate only where needed.
44
29
 
45
- ### Astro Components
30
+ ### Astro Component Example
46
31
 
47
32
  ```astro
48
33
  ---
49
- // Component script (runs at build time / server)
50
- interface Props {
51
- title: string;
52
- description?: string;
53
- }
34
+ interface Props { title: string; description?: string; }
54
35
  const { title, description = 'Default description' } = Astro.props;
55
36
  const data = await fetch('https://api.example.com/data').then(r => r.json());
56
37
  ---
57
-
58
38
  <section>
59
39
  <h2>{title}</h2>
60
- <p>{description}</p>
61
- <ul>
62
- {data.items.map((item: { id: string; name: string }) => (
63
- <li>{item.name}</li>
64
- ))}
65
- </ul>
40
+ {data.items.map((item: { name: string }) => <li>{item.name}</li>)}
66
41
  </section>
67
-
68
42
  <style>
69
- /* Scoped by default */
70
43
  section { max-width: 800px; margin: 0 auto; }
71
44
  </style>
72
45
  ```
@@ -81,22 +54,9 @@ const data = await fetch('https://api.example.com/data').then(r => r.json());
81
54
  | `client:media="(max-width: 768px)"` | When media query matches | Mobile-only interactivity |
82
55
  | `client:only="react"` | Client-only, no SSR | Components that can't server-render |
83
56
 
84
- ```astro
85
- ---
86
- import Counter from '../components/Counter.tsx';
87
- import HeavyChart from '../components/HeavyChart.tsx';
88
- ---
89
-
90
- <!-- Hydrates immediately -->
91
- <Counter client:load />
92
-
93
- <!-- Hydrates when visible -->
94
- <HeavyChart client:visible />
95
- ```
96
-
97
57
  ## Content Collections
98
58
 
99
- Define collections in `src/content.config.ts` (Astro v5+) using the Content Layer API:
59
+ Define in `src/content.config.ts` (Astro v5+) using the Content Layer API:
100
60
 
101
61
  ```ts
102
62
  import { defineCollection, z } from 'astro:content';
@@ -106,173 +66,56 @@ const blog = defineCollection({
106
66
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
107
67
  schema: z.object({
108
68
  title: z.string(),
109
- description: z.string(),
110
69
  pubDate: z.coerce.date(),
111
- updatedDate: z.coerce.date().optional(),
112
- heroImage: z.string().optional(),
113
70
  draft: z.boolean().default(false),
114
71
  tags: z.array(z.string()).default([]),
115
72
  }),
116
73
  });
117
-
118
74
  export const collections = { blog };
119
75
  ```
120
76
 
121
- ### Querying Collections
77
+ Query collections:
122
78
 
123
79
  ```astro
124
80
  ---
125
- import { getCollection, getEntry } from 'astro:content';
126
-
127
- // All published posts, sorted by date
81
+ import { getCollection } from 'astro:content';
128
82
  const posts = (await getCollection('blog', ({ data }) => !data.draft))
129
83
  .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
130
-
131
- // Single entry
132
- const entry = await getEntry('blog', 'first-post');
133
84
  ---
134
85
  ```
135
86
 
136
87
  ## Routing
137
88
 
138
- ### Static Routes
139
-
140
- Every `.astro` or `.md` file in `src/pages/` becomes a route.
141
-
142
- ### Dynamic Routes
89
+ Every `.astro` or `.md` file in `src/pages/` becomes a route. For dynamic routes:
143
90
 
144
91
  ```astro
145
92
  ---
146
93
  // src/pages/blog/[slug].astro
147
94
  import { getCollection } from 'astro:content';
148
-
149
95
  export async function getStaticPaths() {
150
96
  const posts = await getCollection('blog');
151
- return posts.map(post => ({
152
- params: { slug: post.id },
153
- props: { post },
154
- }));
97
+ return posts.map(post => ({ params: { slug: post.id }, props: { post } }));
155
98
  }
156
-
157
99
  const { post } = Astro.props;
158
100
  const { Content } = await post.render();
159
101
  ---
160
-
161
102
  <Content />
162
103
  ```
163
104
 
164
- ### Server-Side Rendering (On-Demand)
165
-
166
- Enable SSR with an adapter in `astro.config.mjs`:
167
-
168
- ```js
169
- import { defineConfig } from 'astro/config';
170
- import node from '@astrojs/node';
171
-
172
- export default defineConfig({
173
- output: 'server', // or 'hybrid' for mixed static + server
174
- adapter: node({ mode: 'standalone' }),
175
- });
176
- ```
105
+ **SSR**: Set `output: 'server'` (or `'hybrid'`) and add an adapter (`node`, `vercel`, `netlify`, `cloudflare`) in `astro.config.mjs`.
177
106
 
178
107
  ## Layouts
179
108
 
180
- ```astro
181
- ---
182
- // src/layouts/BaseLayout.astro
183
- interface Props {
184
- title: string;
185
- description?: string;
186
- }
187
- const { title, description = 'My Astro Site' } = Astro.props;
188
- ---
189
-
190
- <!doctype html>
191
- <html lang="en">
192
- <head>
193
- <meta charset="UTF-8" />
194
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
195
- <meta name="description" content={description} />
196
- <title>{title}</title>
197
- </head>
198
- <body>
199
- <slot />
200
- </body>
201
- </html>
202
- ```
109
+ Define in `src/layouts/BaseLayout.astro` — a full HTML shell with `<slot />` for page content. Pass `title` and `description` as props.
203
110
 
204
111
  ## Integrations
205
112
 
206
- Use `astro add` for official integrations:
207
-
208
- ```bash
209
- npx astro add react # Add React support
210
- npx astro add tailwind # Add Tailwind CSS v4
211
- npx astro add mdx # Add MDX support
212
- npx astro add sitemap # Add sitemap generation
213
- npx astro add node # Add Node.js SSR adapter
214
- npx astro add vercel # Add Vercel adapter
215
- npx astro add netlify # Add Netlify adapter
216
- npx astro add cloudflare # Add Cloudflare adapter
217
- ```
218
-
219
- ## API Routes (Endpoints)
220
-
221
- ```ts
222
- // src/pages/api/search.ts
223
- import type { APIRoute } from 'astro';
224
-
225
- export const GET: APIRoute = async ({ url }) => {
226
- const query = url.searchParams.get('q');
227
- const results = await searchDatabase(query);
228
- return new Response(JSON.stringify(results), {
229
- headers: { 'Content-Type': 'application/json' },
230
- });
231
- };
232
-
233
- export const POST: APIRoute = async ({ request }) => {
234
- const body = await request.json();
235
- // handle mutation
236
- return new Response(JSON.stringify({ ok: true }), { status: 200 });
237
- };
238
- ```
239
-
240
- ## Actions (Server Mutations)
113
+ Use `astro add` for react, tailwind, mdx, sitemap, node, vercel, netlify, cloudflare.
241
114
 
242
- Define type-safe server actions in `src/actions/index.ts`:
115
+ ## API Routes & Actions
243
116
 
244
- ```ts
245
- import { defineAction } from 'astro:actions';
246
- import { z } from 'astro:schema';
247
-
248
- export const server = {
249
- subscribe: defineAction({
250
- accept: 'form',
251
- input: z.object({ email: z.string().email() }),
252
- handler: async ({ email }) => {
253
- await addToNewsletter(email);
254
- return { success: true };
255
- },
256
- }),
257
- };
258
- ```
259
-
260
- ## Performance Patterns
261
-
262
- - **Zero JS by default** — only ship JavaScript for interactive islands.
263
- - **Image optimization** — use `astro:assets` for automatic image optimization.
264
- - **View Transitions** — use `<ViewTransitions />` for smooth page navigation.
265
- - **Prefetching** — enabled by default for visible links.
266
- - **CSS scoping** — styles in `.astro` files are scoped automatically.
267
-
268
- ```astro
269
- ---
270
- import { Image } from 'astro:assets';
271
- import heroImage from '../assets/hero.jpg';
272
- ---
273
-
274
- <Image src={heroImage} alt="Hero" width={800} />
275
- ```
117
+ - **API routes**: Export `GET`/`POST` handlers from `src/pages/api/*.ts` returning `new Response(...)`.
118
+ - **Actions**: Use `defineAction` in `src/actions/index.ts` for type-safe server mutations with Zod validation.
276
119
 
277
120
  ## Anti-Patterns
278
121
 
@@ -286,3 +129,4 @@ import heroImage from '../assets/hero.jpg';
286
129
  | Giant monolithic pages | Hard to maintain and test | Split into layouts + reusable components |
287
130
  | Ignoring `astro add` for integrations | Manual config is error-prone | Use `astro add` for official integrations |
288
131
  | Missing `alt` on images | Accessibility violation | Always provide descriptive `alt` text |
132
+ | Not using `astro:assets` for images | Missing optimization | Use `<Image>` from `astro:assets` |
@@ -11,16 +11,36 @@ Generic Convex development methodology. For project-specific schema, functions,
11
11
 
12
12
  ## Critical Development Rules
13
13
 
14
- 1. **Schema-first design** — define schema in `convex/schema.ts` using `defineSchema` and `defineTable`
15
- 2. **Queries are reactive** Convex queries automatically re-run when underlying data changes
16
- 3. **Mutations are transactional** mutations run as ACID transactions; leverage this for consistency
17
- 4. **Actions for side effects** — use actions (not mutations) for external API calls, file uploads, etc.
18
- 5. **Never await queries in mutations** — queries and mutations run in separate contexts
19
- 6. **Use validators** validate all function arguments with `v` (Convex's validator library)
20
- 7. **Index design** create indexes for frequently filtered/sorted fields in the schema
21
- 8. **Paginated queries** — use `.paginate()` for large result sets
22
- 9. **File storage** — use Convex's built-in file storage API, not external services
23
- 10. **Environment variables**set via Convex dashboard, access with `process.env` in actions only
14
+ **Function Registration**
15
+ - Public: `query`/`mutation`/`action`; Private: `internalQuery`/`internalMutation`/`internalAction` (import from `./_generated/server`)
16
+ - Always include `returns` validator; use `returns: v.null()` when the function returns nothing (JS implicitly returns `null`)
17
+
18
+ **Function References**
19
+ - Use `api.filename.functionName` for public and `internal.filename.functionName` for internal functions (from `./_generated/api`)
20
+ - Never pass functions directly to `ctx.runQuery`/`ctx.runMutation`/`ctx.runAction` always use function references
21
+
22
+ **Queries**
23
+ - Do NOT use `.filter()` define an index in the schema and use `.withIndex()` instead
24
+ - Use `.unique()` for single document queries
25
+ - No `.delete()` on queries — collect results, then call `ctx.db.delete(row._id)` on each
26
+
27
+ **Actions**
28
+ - Add `"use node";` at the top of files containing actions that use Node.js built-in modules
29
+ - Never use `ctx.db` inside actions — actions don't have database access; use `ctx.runQuery`/`ctx.runMutation` instead
30
+
31
+ **Schema**
32
+ - Index name must include all fields: `["field1", "field2"]` → `"by_field1_and_field2"`
33
+ - Index fields must be queried in definition order
34
+ - Do NOT define `_id` or `_creationTime` — they are automatic system fields
35
+
36
+ **General**
37
+ - Schema-first design: define in `convex/schema.ts` using `defineSchema`/`defineTable`
38
+ - Mutations are ACID transactional; use actions for external API calls or side effects
39
+ - Never await queries in mutations — they run in separate contexts
40
+ - Use `.paginate()` for large result sets
41
+ - Use `Id<'tableName'>` for document ID types (from `./_generated/dataModel`)
42
+ - Use `v.null()` not `v.undefined()` — `undefined` is not a valid Convex value
43
+ - Environment variables: set via Convex dashboard; access with `process.env` in actions only
24
44
 
25
45
  ## Schema Patterns
26
46
 
@@ -34,7 +54,9 @@ export default defineSchema({
34
54
  name: v.string(),
35
55
  email: v.string(),
36
56
  role: v.union(v.literal("admin"), v.literal("user")),
37
- }).index("by_email", ["email"]),
57
+ })
58
+ .index("by_email", ["email"])
59
+ .index("by_role", ["role"]),
38
60
  });
39
61
  ```
40
62
 
@@ -45,9 +67,12 @@ import { v } from "convex/values";
45
67
 
46
68
  export const list = query({
47
69
  args: { role: v.optional(v.string()) },
70
+ returns: v.array(v.any()),
48
71
  handler: async (ctx, args) => {
49
72
  if (args.role) {
50
- return await ctx.db.query("users").filter(q => q.eq(q.field("role"), args.role)).collect();
73
+ return await ctx.db.query("users")
74
+ .withIndex("by_role", q => q.eq("role", args.role!))
75
+ .collect();
51
76
  }
52
77
  return await ctx.db.query("users").collect();
53
78
  },
@@ -61,6 +86,7 @@ import { v } from "convex/values";
61
86
 
62
87
  export const create = mutation({
63
88
  args: { name: v.string(), email: v.string() },
89
+ returns: v.id("users"),
64
90
  handler: async (ctx, args) => {
65
91
  return await ctx.db.insert("users", { ...args, role: "user" });
66
92
  },
@@ -54,17 +54,21 @@ Place functions in `netlify/functions/`:
54
54
 
55
55
  ```typescript
56
56
  // netlify/functions/hello.ts
57
- import type { Handler } from '@netlify/functions';
57
+ import type { Context, Config } from "@netlify/functions";
58
58
 
59
- export const handler: Handler = async (event) => {
60
- return {
61
- statusCode: 200,
62
- body: JSON.stringify({ message: 'Hello from Netlify Functions' }),
63
- };
59
+ export default async (req: Request, context: Context) => {
60
+ return new Response(JSON.stringify({ message: "Hello from Netlify Functions" }), {
61
+ headers: { "Content-Type": "application/json" },
62
+ });
63
+ };
64
+
65
+ export const config: Config = {
66
+ path: "/hello",
64
67
  };
65
68
  ```
66
69
 
67
- - Functions are available at `/.netlify/functions/<name>`
70
+ Functions use web standard Request/Response. The `Config` export defines routing (path) instead of the default `/.netlify/functions/<name>` path.
71
+
68
72
  - Supports TypeScript out of the box
69
73
  - Default timeout: 10s (extendable to 26s on Pro)
70
74
  - Use background functions for long-running tasks (up to 15 min)
@@ -110,15 +114,15 @@ export const config = { path: '/geo' };
110
114
 
111
115
  ```typescript
112
116
  // netlify/functions/daily-task.ts
113
- import type { Handler } from '@netlify/functions';
117
+ import type { Config } from "@netlify/functions";
114
118
 
115
- export const handler: Handler = async () => {
116
- // Run daily task
117
- return { statusCode: 200, body: 'OK' };
119
+ export default async (req: Request) => {
120
+ const { next_run } = await req.json();
121
+ console.log("Next invocation at:", next_run);
118
122
  };
119
123
 
120
- export const config = {
121
- schedule: '0 0 * * *', // Daily at midnight UTC
124
+ export const config: Config = {
125
+ schedule: "0 0 * * *", // Daily at midnight UTC
122
126
  };
123
127
  ```
124
128