the-grid-cc 1.4.0 → 1.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.
- package/GRID_EVOLUTION.md +297 -0
- package/README.md +224 -123
- package/agents/grid-e2e-exerciser.md +311 -0
- package/agents/grid-persona-simulator.md +346 -0
- package/agents/grid-refinement-synth.md +284 -0
- package/agents/grid-visual-inspector.md +229 -0
- package/commands/grid/VERSION +1 -1
- package/commands/grid/help.md +22 -3
- package/commands/grid/mc.md +204 -12
- package/commands/grid/refine.md +283 -0
- package/package.json +1 -1
- package/.grid/STATE.md +0 -22
- package/.grid/plans/blog-PLAN-SUMMARY.md +0 -518
- package/.grid/plans/blog-block-01.md +0 -180
- package/.grid/plans/blog-block-02.md +0 -229
- package/.grid/plans/blog-block-03.md +0 -253
- package/.grid/plans/blog-block-04.md +0 -287
- package/.grid/plans/blog-block-05.md +0 -235
- package/.grid/plans/blog-block-06.md +0 -325
- package/TICKETS.md +0 -585
- package/test-cli/converter.py +0 -206
- package/test-cli/test_data.json +0 -39
- package/test-cli/test_data.yaml +0 -35
- package/todo-app/README.md +0 -16
- package/todo-app/eslint.config.js +0 -29
- package/todo-app/index.html +0 -13
- package/todo-app/package-lock.json +0 -2917
- package/todo-app/package.json +0 -27
- package/todo-app/public/vite.svg +0 -1
- package/todo-app/src/App.css +0 -125
- package/todo-app/src/App.jsx +0 -84
- package/todo-app/src/index.css +0 -68
- package/todo-app/src/main.jsx +0 -10
- package/todo-app/vite.config.js +0 -7
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
cluster: james-weatherhead-blog
|
|
3
|
-
block: 02
|
|
4
|
-
type: execute
|
|
5
|
-
wave: 2
|
|
6
|
-
depends_on: [01]
|
|
7
|
-
files_modified: [src/layouts/BaseLayout.astro, src/components/Header.astro, src/components/Footer.astro, src/components/DarkModeToggle.astro, src/styles/global.css]
|
|
8
|
-
autonomous: false
|
|
9
|
-
|
|
10
|
-
must_haves:
|
|
11
|
-
truths:
|
|
12
|
-
- "Dark mode toggles between light and dark themes"
|
|
13
|
-
- "Navigation links are visible and functional"
|
|
14
|
-
- "Layout is responsive on mobile and desktop"
|
|
15
|
-
artifacts:
|
|
16
|
-
- path: "src/layouts/BaseLayout.astro"
|
|
17
|
-
provides: "Base HTML structure with dark mode support"
|
|
18
|
-
min_lines: 40
|
|
19
|
-
- path: "src/components/Header.astro"
|
|
20
|
-
provides: "Site navigation with logo/title and links"
|
|
21
|
-
min_lines: 20
|
|
22
|
-
- path: "src/components/DarkModeToggle.astro"
|
|
23
|
-
provides: "Interactive dark mode toggle button"
|
|
24
|
-
min_lines: 30
|
|
25
|
-
key_links:
|
|
26
|
-
- from: "DarkModeToggle.astro"
|
|
27
|
-
to: "document.documentElement"
|
|
28
|
-
via: "classList.toggle('dark')"
|
|
29
|
-
pattern: "classList\\.toggle\\('dark'\\)"
|
|
30
|
-
- from: "BaseLayout.astro"
|
|
31
|
-
to: "localStorage"
|
|
32
|
-
via: "theme persistence script"
|
|
33
|
-
pattern: "localStorage\\.getItem\\('theme'\\)"
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
<objective>
|
|
37
|
-
Build the layout system with base layout, header, footer, and dark mode functionality.
|
|
38
|
-
|
|
39
|
-
Purpose: Create reusable layout components that provide consistent structure, navigation, and theming across all pages.
|
|
40
|
-
Output: Responsive layout with working dark mode toggle, navigation header, and footer.
|
|
41
|
-
</objective>
|
|
42
|
-
|
|
43
|
-
<context>
|
|
44
|
-
Block 01 completed: Astro project initialized with Tailwind (darkMode: 'class') and Vercel adapter.
|
|
45
|
-
|
|
46
|
-
This block builds the visual foundation. The layout system must:
|
|
47
|
-
- Support dark mode toggle (class-based, not media query)
|
|
48
|
-
- Be minimal and clean (per requirements)
|
|
49
|
-
- Work on mobile and desktop
|
|
50
|
-
- Include header with site title and nav links
|
|
51
|
-
- Include footer with copyright/contact info
|
|
52
|
-
|
|
53
|
-
No blog content yet - that comes in Block 03. This focuses purely on structure and theming.
|
|
54
|
-
</context>
|
|
55
|
-
|
|
56
|
-
<threads>
|
|
57
|
-
|
|
58
|
-
<thread type="auto">
|
|
59
|
-
<name>Thread 1: Create base layout with dark mode persistence</name>
|
|
60
|
-
<files>src/layouts/BaseLayout.astro, src/styles/global.css</files>
|
|
61
|
-
<action>
|
|
62
|
-
Create BaseLayout.astro as the foundational layout component:
|
|
63
|
-
|
|
64
|
-
1. Create src/layouts/BaseLayout.astro with props interface:
|
|
65
|
-
- title: string
|
|
66
|
-
- description?: string
|
|
67
|
-
- ogImage?: string
|
|
68
|
-
|
|
69
|
-
2. Structure:
|
|
70
|
-
- HTML doctype and head with meta tags (viewport, charset, description)
|
|
71
|
-
- SEO meta tags (og:title, og:description, twitter:card)
|
|
72
|
-
- Link to global.css
|
|
73
|
-
- Inline script in head (before body renders) to prevent flash:
|
|
74
|
-
```js
|
|
75
|
-
const theme = localStorage.getItem('theme') || 'dark'; // default dark per minimal aesthetic
|
|
76
|
-
if (theme === 'dark') document.documentElement.classList.add('dark');
|
|
77
|
-
```
|
|
78
|
-
- Body with dark:bg-gray-900 bg-gray-50 dark:text-gray-100 text-gray-900
|
|
79
|
-
- Slot for page content
|
|
80
|
-
|
|
81
|
-
3. Create src/styles/global.css:
|
|
82
|
-
- @tailwind base/components/utilities
|
|
83
|
-
- Custom font stack: system-ui, -apple-system, sans-serif
|
|
84
|
-
- Smooth scroll behavior
|
|
85
|
-
- Focus styles for accessibility
|
|
86
|
-
|
|
87
|
-
AVOID: Do not use media query dark mode (requirements specify toggle, not auto). Do not add analytics scripts yet (keep minimal). WHY: User wants control over theme, not automatic switching based on system preference.
|
|
88
|
-
</action>
|
|
89
|
-
<verify>
|
|
90
|
-
Check: src/layouts/BaseLayout.astro exists with inline theme script
|
|
91
|
-
Check: localStorage persistence script runs before body render
|
|
92
|
-
Check: global.css imports Tailwind directives
|
|
93
|
-
Run: grep -r "localStorage.getItem" src/layouts/BaseLayout.astro
|
|
94
|
-
</verify>
|
|
95
|
-
<done>
|
|
96
|
-
- BaseLayout.astro exports layout with title, description props
|
|
97
|
-
- Inline script prevents FOUC (flash of unstyled content)
|
|
98
|
-
- Dark mode classes applied to html element
|
|
99
|
-
- global.css configures Tailwind and typography
|
|
100
|
-
</done>
|
|
101
|
-
</thread>
|
|
102
|
-
|
|
103
|
-
<thread type="auto">
|
|
104
|
-
<name>Thread 2: Build Header and Footer components</name>
|
|
105
|
-
<files>src/components/Header.astro, src/components/Footer.astro</files>
|
|
106
|
-
<action>
|
|
107
|
-
Create navigation header and footer components:
|
|
108
|
-
|
|
109
|
-
Header.astro:
|
|
110
|
-
1. Create header element with container max-w-3xl mx-auto px-4 py-8
|
|
111
|
-
2. Site title "James Weatherhead" as h1 or logo
|
|
112
|
-
3. Navigation links: Home (/) | Blog (/blog) | About (/about)
|
|
113
|
-
4. Include DarkModeToggle component (will create in next thread)
|
|
114
|
-
5. Make responsive: stack on mobile, horizontal on desktop (md:flex)
|
|
115
|
-
6. Style links with hover:text-blue-600 dark:hover:text-blue-400
|
|
116
|
-
|
|
117
|
-
Footer.astro:
|
|
118
|
-
1. Create footer element with border-t border-gray-200 dark:border-gray-800
|
|
119
|
-
2. Container max-w-3xl mx-auto px-4 py-8
|
|
120
|
-
3. Copyright text: © 2024 James Weatherhead
|
|
121
|
-
4. Optional: Contact links or social media (GitHub, Twitter) if provided
|
|
122
|
-
5. Small text size: text-sm text-gray-600 dark:text-gray-400
|
|
123
|
-
|
|
124
|
-
AVOID: Do not add complex navigation menus (keep minimal - 3 links max). Do not add social media icons unless assets provided. WHY: Requirements specify "minimal design" - extra navigation adds visual clutter.
|
|
125
|
-
</action>
|
|
126
|
-
<verify>
|
|
127
|
-
Check: src/components/Header.astro exists with nav links
|
|
128
|
-
Check: src/components/Footer.astro exists with copyright
|
|
129
|
-
Check: Both use max-w-3xl for content width consistency
|
|
130
|
-
Run: grep -r "max-w-3xl" src/components/
|
|
131
|
-
</verify>
|
|
132
|
-
<done>
|
|
133
|
-
- Header.astro contains site title and 3 navigation links
|
|
134
|
-
- Footer.astro contains copyright and minimal info
|
|
135
|
-
- Both components use consistent container width (max-w-3xl)
|
|
136
|
-
- Responsive styles applied with Tailwind breakpoints
|
|
137
|
-
</done>
|
|
138
|
-
</thread>
|
|
139
|
-
|
|
140
|
-
<thread type="auto">
|
|
141
|
-
<name>Thread 3: Implement dark mode toggle component</name>
|
|
142
|
-
<files>src/components/DarkModeToggle.astro</files>
|
|
143
|
-
<action>
|
|
144
|
-
Create interactive dark mode toggle button:
|
|
145
|
-
|
|
146
|
-
1. Create DarkModeToggle.astro with client:load directive (needs JS)
|
|
147
|
-
2. Button element with aria-label="Toggle dark mode" for accessibility
|
|
148
|
-
3. Icon: Use Unicode characters (☀️ sun / 🌙 moon) or SVG for sun/moon icons
|
|
149
|
-
4. Client-side script:
|
|
150
|
-
```js
|
|
151
|
-
const toggle = document.querySelector('#dark-mode-toggle');
|
|
152
|
-
toggle.addEventListener('click', () => {
|
|
153
|
-
const isDark = document.documentElement.classList.toggle('dark');
|
|
154
|
-
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
|
155
|
-
});
|
|
156
|
-
```
|
|
157
|
-
5. Style: rounded-full p-2 hover:bg-gray-200 dark:hover:bg-gray-800 transition
|
|
158
|
-
6. Position in Header component (top-right corner)
|
|
159
|
-
|
|
160
|
-
AVOID: Do not use React or Vue (keep Astro-native for simplicity). Do not add animations beyond simple transition. WHY: Requirements don't specify framework components, and excessive animations conflict with minimal aesthetic.
|
|
161
|
-
</action>
|
|
162
|
-
<verify>
|
|
163
|
-
Check: DarkModeToggle.astro exists with client:load directive
|
|
164
|
-
Check: Toggle button has click handler that updates localStorage
|
|
165
|
-
Check: classList.toggle('dark') targets documentElement
|
|
166
|
-
Run: grep -r "client:load" src/components/DarkModeToggle.astro
|
|
167
|
-
</verify>
|
|
168
|
-
<done>
|
|
169
|
-
- DarkModeToggle.astro component created with interactive button
|
|
170
|
-
- Click handler toggles 'dark' class on html element
|
|
171
|
-
- Theme preference persists in localStorage
|
|
172
|
-
- Accessible with aria-label
|
|
173
|
-
</done>
|
|
174
|
-
</thread>
|
|
175
|
-
|
|
176
|
-
<thread type="checkpoint:human-verify" gate="blocking">
|
|
177
|
-
<what-built>
|
|
178
|
-
Complete layout system with:
|
|
179
|
-
- BaseLayout.astro (theme persistence, no FOUC)
|
|
180
|
-
- Header.astro (navigation: Home, Blog, About)
|
|
181
|
-
- Footer.astro (copyright, minimal info)
|
|
182
|
-
- DarkModeToggle.astro (interactive toggle with localStorage)
|
|
183
|
-
- global.css (Tailwind config, typography)
|
|
184
|
-
</what-built>
|
|
185
|
-
<how-to-verify>
|
|
186
|
-
1. cd /Users/jacweath/grid/blog && npm run dev
|
|
187
|
-
2. Create test page at src/pages/index.astro using BaseLayout
|
|
188
|
-
3. Visit http://localhost:4321
|
|
189
|
-
4. Check:
|
|
190
|
-
- Header appears with "James Weatherhead" title and nav links
|
|
191
|
-
- Footer appears with copyright
|
|
192
|
-
- Dark mode toggle button visible (sun/moon icon)
|
|
193
|
-
5. Click dark mode toggle:
|
|
194
|
-
- Background switches from light to dark (or vice versa)
|
|
195
|
-
- Text color changes appropriately
|
|
196
|
-
- Refresh page - theme persists
|
|
197
|
-
6. Test responsive:
|
|
198
|
-
- Resize browser to mobile width
|
|
199
|
-
- Header should stack vertically or remain readable
|
|
200
|
-
7. Check browser console for errors (should be none)
|
|
201
|
-
</how-to-verify>
|
|
202
|
-
<resume-signal>Type "approved" if layout and dark mode work correctly, or describe any issues (e.g., "toggle not working", "colors wrong")</resume-signal>
|
|
203
|
-
</thread>
|
|
204
|
-
|
|
205
|
-
</threads>
|
|
206
|
-
|
|
207
|
-
<verification>
|
|
208
|
-
Complete verification checklist:
|
|
209
|
-
1. BaseLayout.astro exists with theme persistence script
|
|
210
|
-
2. Header.astro has navigation links (/, /blog, /about)
|
|
211
|
-
3. Footer.astro has copyright text
|
|
212
|
-
4. DarkModeToggle.astro has client:load and click handler
|
|
213
|
-
5. global.css imports Tailwind directives
|
|
214
|
-
6. Dark mode toggle switches theme without page reload
|
|
215
|
-
7. Theme persists across page refresh (localStorage)
|
|
216
|
-
8. Layout is responsive on mobile and desktop
|
|
217
|
-
9. No FOUC (flash of unstyled content) on page load
|
|
218
|
-
10. Browser console has no errors
|
|
219
|
-
</verification>
|
|
220
|
-
|
|
221
|
-
<success_criteria>
|
|
222
|
-
- Layout system renders correctly in browser
|
|
223
|
-
- Dark mode toggle switches between light and dark themes
|
|
224
|
-
- Theme preference persists in localStorage
|
|
225
|
-
- Navigation links are visible and clickable
|
|
226
|
-
- Responsive on mobile and desktop
|
|
227
|
-
- No console errors
|
|
228
|
-
- User approves visual appearance and functionality
|
|
229
|
-
</success_criteria>
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
cluster: james-weatherhead-blog
|
|
3
|
-
block: 03
|
|
4
|
-
type: execute
|
|
5
|
-
wave: 2
|
|
6
|
-
depends_on: [01]
|
|
7
|
-
files_modified: [src/content/config.ts, src/content/blog/sample-post.md, src/pages/blog/[...slug].astro, src/components/PostList.astro, src/components/Tag.astro]
|
|
8
|
-
autonomous: false
|
|
9
|
-
|
|
10
|
-
must_haves:
|
|
11
|
-
truths:
|
|
12
|
-
- "Blog posts are defined as content collection with schema"
|
|
13
|
-
- "Individual blog posts render with frontmatter data"
|
|
14
|
-
- "Tags are extracted and displayed for each post"
|
|
15
|
-
artifacts:
|
|
16
|
-
- path: "src/content/config.ts"
|
|
17
|
-
provides: "Content collection schema for blog posts"
|
|
18
|
-
exports: ["collections"]
|
|
19
|
-
- path: "src/pages/blog/[...slug].astro"
|
|
20
|
-
provides: "Dynamic blog post page template"
|
|
21
|
-
min_lines: 50
|
|
22
|
-
- path: "src/components/PostList.astro"
|
|
23
|
-
provides: "Reusable component for listing blog posts"
|
|
24
|
-
min_lines: 30
|
|
25
|
-
key_links:
|
|
26
|
-
- from: "src/pages/blog/[...slug].astro"
|
|
27
|
-
to: "getCollection('blog')"
|
|
28
|
-
via: "Astro content collections API"
|
|
29
|
-
pattern: "getCollection\\('blog'\\)"
|
|
30
|
-
- from: "src/content/config.ts"
|
|
31
|
-
to: "zod schema"
|
|
32
|
-
via: "defineCollection"
|
|
33
|
-
pattern: "defineCollection"
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
<objective>
|
|
37
|
-
Implement blog content structure using Astro Content Collections with markdown posts, frontmatter validation, and tag support.
|
|
38
|
-
|
|
39
|
-
Purpose: Create the core blog functionality - content schema, post rendering, and listing capabilities.
|
|
40
|
-
Output: Content collection configured, sample post created, dynamic post template working.
|
|
41
|
-
</objective>
|
|
42
|
-
|
|
43
|
-
<context>
|
|
44
|
-
Block 01 completed: Astro project initialized with Tailwind and Vercel adapter.
|
|
45
|
-
Block 02 in progress: Layout system (runs parallel with this block).
|
|
46
|
-
|
|
47
|
-
This block focuses on the content layer using Astro's Content Collections API. Requirements specify:
|
|
48
|
-
- Markdown-based posts
|
|
49
|
-
- Tags for organization
|
|
50
|
-
- Syntax highlighting (shiki installed in Block 01)
|
|
51
|
-
|
|
52
|
-
Content Collections provide type-safe frontmatter, automatic routing, and built-in markdown processing. This is the canonical Astro approach for blog content.
|
|
53
|
-
|
|
54
|
-
Block 02 (layouts) and Block 03 (content) can run in parallel since they modify different files with no overlap.
|
|
55
|
-
</context>
|
|
56
|
-
|
|
57
|
-
<threads>
|
|
58
|
-
|
|
59
|
-
<thread type="auto">
|
|
60
|
-
<name>Thread 1: Configure content collection schema</name>
|
|
61
|
-
<files>src/content/config.ts, src/content/blog/sample-post.md</files>
|
|
62
|
-
<action>
|
|
63
|
-
Set up Astro Content Collections for blog posts:
|
|
64
|
-
|
|
65
|
-
1. Create src/content/config.ts with zod schema:
|
|
66
|
-
```ts
|
|
67
|
-
import { defineCollection, z } from 'astro:content';
|
|
68
|
-
|
|
69
|
-
const blog = defineCollection({
|
|
70
|
-
type: 'content',
|
|
71
|
-
schema: z.object({
|
|
72
|
-
title: z.string(),
|
|
73
|
-
description: z.string(),
|
|
74
|
-
pubDate: z.coerce.date(),
|
|
75
|
-
updatedDate: z.coerce.date().optional(),
|
|
76
|
-
tags: z.array(z.string()).default([]),
|
|
77
|
-
draft: z.boolean().default(false),
|
|
78
|
-
}),
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
export const collections = { blog };
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
2. Create src/content/blog/ directory
|
|
85
|
-
|
|
86
|
-
3. Create sample post: src/content/blog/sample-post.md
|
|
87
|
-
- Frontmatter with all required fields (title, description, pubDate, tags)
|
|
88
|
-
- Markdown content with headings, paragraphs, code blocks
|
|
89
|
-
- Use tags: ["javascript", "astro", "web-development"]
|
|
90
|
-
- Include code block to test syntax highlighting
|
|
91
|
-
|
|
92
|
-
AVOID: Do not add complex media fields yet (images come later if needed). Do not add author field unless multi-author (single author blog). WHY: Keep schema minimal - only add fields when content requires them.
|
|
93
|
-
</action>
|
|
94
|
-
<verify>
|
|
95
|
-
Run: npm run build (should succeed with no schema errors)
|
|
96
|
-
Check: src/content/config.ts exports 'collections' with 'blog'
|
|
97
|
-
Check: sample-post.md exists with valid frontmatter
|
|
98
|
-
Run: npx astro check (validates content schema)
|
|
99
|
-
</verify>
|
|
100
|
-
<done>
|
|
101
|
-
- src/content/config.ts defines blog collection with zod schema
|
|
102
|
-
- Schema includes: title, description, pubDate, updatedDate, tags, draft
|
|
103
|
-
- sample-post.md created with valid frontmatter
|
|
104
|
-
- Build completes without content validation errors
|
|
105
|
-
</done>
|
|
106
|
-
</thread>
|
|
107
|
-
|
|
108
|
-
<thread type="auto">
|
|
109
|
-
<name>Thread 2: Create dynamic blog post template</name>
|
|
110
|
-
<files>src/pages/blog/[...slug].astro</files>
|
|
111
|
-
<action>
|
|
112
|
-
Create dynamic route for individual blog posts:
|
|
113
|
-
|
|
114
|
-
1. Create src/pages/blog/[...slug].astro
|
|
115
|
-
|
|
116
|
-
2. Implement getStaticPaths():
|
|
117
|
-
```ts
|
|
118
|
-
import { getCollection } from 'astro:content';
|
|
119
|
-
export async function getStaticPaths() {
|
|
120
|
-
const posts = await getCollection('blog', ({ data }) => !data.draft);
|
|
121
|
-
return posts.map(post => ({
|
|
122
|
-
params: { slug: post.slug },
|
|
123
|
-
props: post,
|
|
124
|
-
}));
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
3. Destructure props: const { data, render } = Astro.props;
|
|
129
|
-
4. Render post with BaseLayout:
|
|
130
|
-
- Pass title and description to layout
|
|
131
|
-
- Render metadata: title, date, tags
|
|
132
|
-
- Render content: const { Content } = await render();
|
|
133
|
-
- Style with Tailwind typography: prose dark:prose-invert max-w-3xl
|
|
134
|
-
|
|
135
|
-
5. Date formatting: use Intl.DateTimeFormat or date-fns
|
|
136
|
-
6. Tags: render as badges with Tag component (create in next thread)
|
|
137
|
-
|
|
138
|
-
AVOID: Do not add comments (requirements say "none"). Do not add related posts sidebar (keep minimal). WHY: Feature requirements explicitly exclude comments; related posts adds complexity without requirement.
|
|
139
|
-
</action>
|
|
140
|
-
<verify>
|
|
141
|
-
Run: npm run dev
|
|
142
|
-
Visit: http://localhost:4321/blog/sample-post
|
|
143
|
-
Check: Post renders with title, date, tags, and content
|
|
144
|
-
Check: Code blocks have syntax highlighting
|
|
145
|
-
Check: Prose typography applied correctly
|
|
146
|
-
</verify>
|
|
147
|
-
<done>
|
|
148
|
-
- [slug].astro implements getStaticPaths with getCollection
|
|
149
|
-
- Filters out draft posts (data.draft === false)
|
|
150
|
-
- Renders post content with proper typography
|
|
151
|
-
- Displays frontmatter data (title, date, tags)
|
|
152
|
-
- Syntax highlighting works in code blocks
|
|
153
|
-
</done>
|
|
154
|
-
</thread>
|
|
155
|
-
|
|
156
|
-
<thread type="auto">
|
|
157
|
-
<name>Thread 3: Build post list and tag components</name>
|
|
158
|
-
<files>src/components/PostList.astro, src/components/Tag.astro</files>
|
|
159
|
-
<action>
|
|
160
|
-
Create reusable components for displaying posts and tags:
|
|
161
|
-
|
|
162
|
-
PostList.astro:
|
|
163
|
-
1. Props interface: posts (array of blog collection entries)
|
|
164
|
-
2. Map over posts and display:
|
|
165
|
-
- Title (link to /blog/{slug})
|
|
166
|
-
- Description
|
|
167
|
-
- Date (formatted)
|
|
168
|
-
- Tags (using Tag component)
|
|
169
|
-
3. Sort by pubDate descending (newest first)
|
|
170
|
-
4. Style: space-y-8 for vertical spacing, hover states on titles
|
|
171
|
-
5. No pagination yet (add later if needed)
|
|
172
|
-
|
|
173
|
-
Tag.astro:
|
|
174
|
-
1. Props: tag (string), variant?: 'link' | 'badge'
|
|
175
|
-
2. If variant === 'link': render as link to /blog/tags/{tag}
|
|
176
|
-
3. If variant === 'badge': render as span with badge styles
|
|
177
|
-
4. Style: rounded-full px-3 py-1 text-sm bg-gray-200 dark:bg-gray-800
|
|
178
|
-
|
|
179
|
-
AVOID: Do not add filter/search UI (add later if needed). Do not add pagination yet (YAGNI - wait until many posts exist). WHY: Premature optimization - start simple, add features when content volume requires it.
|
|
180
|
-
</action>
|
|
181
|
-
<verify>
|
|
182
|
-
Check: PostList.astro accepts posts prop and maps over entries
|
|
183
|
-
Check: Tag.astro handles both 'link' and 'badge' variants
|
|
184
|
-
Check: Tags are clickable links (variant='link') or static badges
|
|
185
|
-
Run: grep -r "variant=" src/components/Tag.astro
|
|
186
|
-
</verify>
|
|
187
|
-
<done>
|
|
188
|
-
- PostList.astro displays posts with title, description, date, tags
|
|
189
|
-
- Posts sorted by date descending (newest first)
|
|
190
|
-
- Tag.astro renders tags as links or badges based on variant prop
|
|
191
|
-
- Hover states applied to post titles
|
|
192
|
-
</done>
|
|
193
|
-
</thread>
|
|
194
|
-
|
|
195
|
-
<thread type="checkpoint:human-verify" gate="blocking">
|
|
196
|
-
<what-built>
|
|
197
|
-
Complete blog content system with:
|
|
198
|
-
- Content collection schema (src/content/config.ts)
|
|
199
|
-
- Sample blog post (src/content/blog/sample-post.md)
|
|
200
|
-
- Dynamic post template ([slug].astro)
|
|
201
|
-
- PostList component (reusable post listing)
|
|
202
|
-
- Tag component (link and badge variants)
|
|
203
|
-
</what-built>
|
|
204
|
-
<how-to-verify>
|
|
205
|
-
1. cd /Users/jacweath/grid/blog && npm run dev
|
|
206
|
-
2. Visit http://localhost:4321/blog/sample-post
|
|
207
|
-
3. Check post page:
|
|
208
|
-
- Title displays correctly
|
|
209
|
-
- Date shows formatted (e.g., "January 23, 2024")
|
|
210
|
-
- Tags appear as badges or links
|
|
211
|
-
- Markdown content renders properly
|
|
212
|
-
- Code blocks have syntax highlighting (colors visible)
|
|
213
|
-
- Dark mode: check prose-invert class applies (text readable on dark bg)
|
|
214
|
-
4. Check browser console for errors (should be none)
|
|
215
|
-
5. Run: npm run build
|
|
216
|
-
- Build should complete successfully
|
|
217
|
-
- Check: npx astro check (no content schema errors)
|
|
218
|
-
6. Create test listing page:
|
|
219
|
-
- Add src/pages/blog/index.astro using PostList component
|
|
220
|
-
- Visit http://localhost:4321/blog
|
|
221
|
-
- Sample post appears in list
|
|
222
|
-
</how-to-verify>
|
|
223
|
-
<resume-signal>Type "approved" if content renders correctly and schema validates, or describe issues (e.g., "highlighting broken", "schema error", "tags not visible")</resume-signal>
|
|
224
|
-
</thread>
|
|
225
|
-
|
|
226
|
-
</threads>
|
|
227
|
-
|
|
228
|
-
<verification>
|
|
229
|
-
Complete verification checklist:
|
|
230
|
-
1. src/content/config.ts defines blog collection with zod schema
|
|
231
|
-
2. Schema includes all required fields (title, description, pubDate, tags, draft)
|
|
232
|
-
3. src/content/blog/sample-post.md exists with valid frontmatter
|
|
233
|
-
4. src/pages/blog/[slug].astro implements getStaticPaths correctly
|
|
234
|
-
5. Dynamic route filters out draft posts
|
|
235
|
-
6. Post template renders content with prose typography
|
|
236
|
-
7. Syntax highlighting works in code blocks
|
|
237
|
-
8. PostList.astro sorts posts by date (newest first)
|
|
238
|
-
9. Tag.astro supports 'link' and 'badge' variants
|
|
239
|
-
10. npm run build completes successfully
|
|
240
|
-
11. npx astro check passes with no errors
|
|
241
|
-
12. User approves content rendering and functionality
|
|
242
|
-
</verification>
|
|
243
|
-
|
|
244
|
-
<success_criteria>
|
|
245
|
-
- Content collection configured with type-safe schema
|
|
246
|
-
- Sample blog post renders at /blog/sample-post
|
|
247
|
-
- Frontmatter data displays correctly (title, date, tags)
|
|
248
|
-
- Markdown content styled with typography plugin
|
|
249
|
-
- Syntax highlighting functional
|
|
250
|
-
- PostList and Tag components work correctly
|
|
251
|
-
- Build succeeds with no content validation errors
|
|
252
|
-
- User approves rendering and functionality
|
|
253
|
-
</success_criteria>
|