@nebulit/embuilder 0.1.39 → 0.1.41

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 (31) hide show
  1. package/package.json +1 -1
  2. package/templates/.claude/skills/sample-slices/SKILL.md +3 -1
  3. package/templates/.claude/skills/sample-slices/templates/.slices/index.json +1 -1
  4. package/templates/.claude/skills/ui-analyze-slices/SKILL.md +102 -0
  5. package/templates/.claude/skills/ui-build-slice-ui/SKILL.md +228 -0
  6. package/templates/.claude/skills/ui-generate-api/SKILL.md +141 -0
  7. package/templates/.claude/skills/ui-generate-hook/SKILL.md +118 -0
  8. package/templates/.claude/skills/ui-generate-types/SKILL.md +223 -0
  9. package/templates/.claude/skills/ui-read-ui-prompts/SKILL.md +192 -0
  10. package/templates/.claude/skills/ui-scaffold-component/SKILL.md +274 -0
  11. package/templates/.slices/Context/event/slice.json +117 -0
  12. package/templates/.slices/index.json +12 -0
  13. package/templates/backend/prompt.md +140 -0
  14. package/templates/config.json +133 -0
  15. package/templates/frontend/prompt.md +484 -0
  16. package/templates/prompt.md +4 -132
  17. package/templates/server.mjs +24 -2
  18. package/templates/.claude/skills/sample-slices/templates/Cart/additem/slice.json +0 -979
  19. package/templates/.claude/skills/sample-slices/templates/Cart/archiveitem/slice.json +0 -529
  20. package/templates/.claude/skills/sample-slices/templates/Cart/cartitems/slice.json +0 -1072
  21. package/templates/.claude/skills/sample-slices/templates/Cart/cartwithproducts/slice.json +0 -394
  22. package/templates/.claude/skills/sample-slices/templates/Cart/changedprices/slice.json +0 -88
  23. package/templates/.claude/skills/sample-slices/templates/Cart/changeinventory/slice.json +0 -264
  24. package/templates/.claude/skills/sample-slices/templates/Cart/changeprice/slice.json +0 -308
  25. package/templates/.claude/skills/sample-slices/templates/Cart/clearcart/slice.json +0 -358
  26. package/templates/.claude/skills/sample-slices/templates/Cart/inventories/slice.json +0 -203
  27. package/templates/.claude/skills/sample-slices/templates/Cart/publishcart/slice.json +0 -876
  28. package/templates/.claude/skills/sample-slices/templates/Cart/removeitem/slice.json +0 -560
  29. package/templates/.claude/skills/sample-slices/templates/Cart/submitcart/slice.json +0 -708
  30. package/templates/.claude/skills/sample-slices/templates/Cart/submittedcartdata/slice.json +0 -399
  31. package/templates/.claude/skills/sample-slices/templates/index.json +0 -108
@@ -0,0 +1,484 @@
1
+ # Frontend Agent Prompt - UI Component Generation
2
+
3
+ Build React + TypeScript UI components from slice JSON definitions using established patterns.
4
+
5
+ ---
6
+
7
+ ## 0. Available Skills (Use These!)
8
+
9
+ This project has custom skills available in `.claude/skills/` that automate common tasks:
10
+
11
+ - **`/ui-build-slice-ui`**: Complete orchestrator - builds entire UI from slice definitions (types → API → hooks → components)
12
+ - **`/ui-analyze-slices`**: Analyze slice JSON files to identify grouping, dependencies, and implementation strategy
13
+ - **`/ui-read-ui-prompts`**: Find and parse UI prompts from slice definitions and `ui-prompt.md`
14
+ - **`/ui-generate-types`**: Generate TypeScript interfaces from slice field definitions
15
+ - **`/ui-generate-api`**: Generate API layer functions for queries (Supabase) and commands (POST)
16
+ - **`/ui-generate-hook`**: Generate React Query hooks for STATE_VIEW (queries) and STATE_CHANGE (mutations)
17
+ - **`/ui-scaffold-component`**: Scaffold React components (List, Dialog, Page) using Bulma CSS
18
+
19
+ **IMPORTANT**: When asked to build UI from slices, USE the `/ui-build-slice-ui` skill first! It will orchestrate all other skills in the correct order. Only use individual skills when you need to regenerate or modify a specific part.
20
+
21
+ ---
22
+
23
+ ## 1. Slice Composition (CRITICAL)
24
+
25
+ ### Slice Types
26
+
27
+ - **STATE_VIEW**: One read model table → Query hook → List component
28
+ - **STATE_CHANGE**: One command/POST endpoint → Mutation hook → Form/Dialog
29
+
30
+ ### Grouping Rule
31
+
32
+ **Slices with same `groupId` → Implement together as one component**
33
+
34
+ ```javascript
35
+ // Multiple slices, same groupId → One component
36
+ Slice A: { groupId: "123", sliceType: "STATE_VIEW", title: "Events View" }
37
+ Slice B: { groupId: "123", sliceType: "STATE_CHANGE", title: "Create Event" }
38
+ Slice C: { groupId: "123", sliceType: "STATE_CHANGE", title: "Cancel Event" }
39
+ // → Combine into EventsPage component
40
+ ```
41
+
42
+ ### UI Prompts Priority
43
+
44
+ 1. Check `ui-prompt.md` (detailed specs) - Use `/ui-read-ui-prompts` skill
45
+ 2. Check `codeGen.uiPrompts` array (high-level guidance) - Use `/ui-read-ui-prompts` skill
46
+ 3. Follow this prompt (standard patterns)
47
+ 4. Keep it simple if no guidance
48
+
49
+ ---
50
+
51
+ ## 2. Authentication & API Context
52
+
53
+ ```typescript
54
+ // AuthContext: user, session, restaurantId
55
+ import { useAuth } from "@/contexts/AuthContext";
56
+ const { user, session, restaurantId } = useAuth();
57
+
58
+ // ApiContext: token, restaurantId, userId (auto-injected into headers)
59
+ import { useApiContext } from "@/hooks/useApiContext";
60
+ const ctx = useApiContext();
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 3. Hooks Pattern
66
+
67
+ ### Query Hook (STATE_VIEW)
68
+
69
+ ```typescript
70
+ // src/hooks/api/useEvents.ts
71
+ import { useQuery } from "@tanstack/react-query";
72
+ import * as api from "@/lib/api";
73
+
74
+ export function useEvents() {
75
+ return useQuery({
76
+ queryKey: ["events"],
77
+ queryFn: () => api.fetchEvents(),
78
+ });
79
+ }
80
+ ```
81
+
82
+ ### Mutation Hook (STATE_CHANGE)
83
+
84
+ ```typescript
85
+ export function useCreateEvent() {
86
+ const ctx = useApiContext();
87
+ const queryClient = useQueryClient();
88
+
89
+ return useMutation({
90
+ mutationFn: (params: api.CreateEventParams) => api.createEvent(params, ctx),
91
+ onSuccess: () => {
92
+ queryClient.invalidateQueries({ queryKey: ["events"] });
93
+ },
94
+ });
95
+ }
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 4. API Layer (CQRS)
101
+
102
+ ### Query (Read from Supabase)
103
+
104
+ ```typescript
105
+ // src/lib/api.ts
106
+ export async function fetchEvents(): Promise<Event[]> {
107
+ const { data, error } = await supabase
108
+ .from("events_for_planning") // Read model table
109
+ .select("*");
110
+ if (error) throw new Error(error.message);
111
+ return data || [];
112
+ }
113
+ ```
114
+
115
+ ### Command (POST to Backend)
116
+
117
+ ```typescript
118
+ export async function createEvent(params: CreateEventParams, ctx: ApiContext) {
119
+ const response = await apiRequest(
120
+ commandEndpoints.createEvent, // /api/createevent
121
+ ctx,
122
+ { method: "POST", body: { ...params } }
123
+ );
124
+ if (!response.ok) throw new Error(response.error);
125
+ return response.data;
126
+ }
127
+ ```
128
+
129
+ **Add endpoint in `src/lib/api-client.ts`**:
130
+ ```typescript
131
+ export const commandEndpoints = {
132
+ createEvent: "/api/createevent",
133
+ // ...
134
+ };
135
+ ```
136
+
137
+ ---
138
+
139
+ ## 5. Component Patterns
140
+
141
+ ### List Component (STATE_VIEW)
142
+
143
+ ```typescript
144
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
145
+ import { Skeleton } from "@/components/ui/skeleton";
146
+ import { useEvents } from "@/hooks/api/useEvents";
147
+
148
+ export function EventList() {
149
+ const { data: events = [], isLoading } = useEvents();
150
+
151
+ if (isLoading) {
152
+ return <Skeleton className="h-20 w-full" />;
153
+ }
154
+
155
+ return (
156
+ <div className="grid gap-4 md:grid-cols-2">
157
+ {events.map(event => (
158
+ <Card key={event.id}>
159
+ <CardHeader><CardTitle>{event.name}</CardTitle></CardHeader>
160
+ <CardContent>{event.date}</CardContent>
161
+ </Card>
162
+ ))}
163
+ </div>
164
+ );
165
+ }
166
+ ```
167
+
168
+ ### Dialog Component (STATE_CHANGE)
169
+
170
+ ```typescript
171
+ import { useState } from "react";
172
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
173
+ import { Button } from "@/components/ui/button";
174
+ import { Input } from "@/components/ui/input";
175
+ import { Label } from "@/components/ui/label";
176
+ import { useCreateEvent } from "@/hooks/api/useEvents";
177
+ import { toast } from "sonner";
178
+
179
+ export function CreateEventDialog({ open, onOpenChange }) {
180
+ const createEvent = useCreateEvent();
181
+ const [form, setForm] = useState({ name: "", date: "" });
182
+
183
+ const handleSubmit = async () => {
184
+ if (!form.name) return toast.error("Name required");
185
+ try {
186
+ await createEvent.mutateAsync(form);
187
+ toast.success("Created");
188
+ onOpenChange(false);
189
+ } catch (err) {
190
+ toast.error(`Error: ${err.message}`);
191
+ }
192
+ };
193
+
194
+ return (
195
+ <Dialog open={open} onOpenChange={onOpenChange}>
196
+ <DialogContent>
197
+ <DialogHeader><DialogTitle>Create Event</DialogTitle></DialogHeader>
198
+ <div className="space-y-4">
199
+ <div>
200
+ <Label>Name</Label>
201
+ <Input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
202
+ </div>
203
+ <Button onClick={handleSubmit} disabled={createEvent.isPending}>
204
+ Create
205
+ </Button>
206
+ </div>
207
+ </DialogContent>
208
+ </Dialog>
209
+ );
210
+ }
211
+ ```
212
+
213
+ ### Page Composition (Combine Slices)
214
+
215
+ ```typescript
216
+ export function EventsPage() {
217
+ const [dialogOpen, setDialogOpen] = useState(false);
218
+
219
+ return (
220
+ <div className="p-6">
221
+ <div className="flex justify-between mb-6">
222
+ <h1 className="text-2xl font-bold">Events</h1>
223
+ <Button onClick={() => setDialogOpen(true)}>Create Event</Button>
224
+ </div>
225
+
226
+ <EventList />
227
+ <CreateEventDialog open={dialogOpen} onOpenChange={setDialogOpen} />
228
+ </div>
229
+ );
230
+ }
231
+ ```
232
+
233
+ ---
234
+
235
+ ## 6. Implementation Workflow
236
+
237
+ ### Recommended Approach: Use Skills!
238
+
239
+ **For complete UI generation from slices:**
240
+ ```bash
241
+ # Use the orchestrator skill - it handles everything
242
+ /ui-build-slice-ui <slice-file-paths>
243
+ ```
244
+
245
+ This will automatically:
246
+ 1. Analyze slices (`/ui-analyze-slices`)
247
+ 2. Read UI prompts (`/ui-read-ui-prompts`)
248
+ 3. Generate types (`/ui-generate-types`)
249
+ 4. Generate API functions (`/ui-generate-api`)
250
+ 5. Generate hooks (`/ui-generate-hook`)
251
+ 6. Scaffold components (`/ui-scaffold-component`)
252
+ 7. Verify integration
253
+
254
+ **For individual tasks:**
255
+ - **Analyze before coding**: `/ui-analyze-slices <slice-files>` - Understand grouping and dependencies
256
+ - **Read requirements**: `/ui-read-ui-prompts <slice-folder>` - Extract design specs and validation rules
257
+ - **Generate types only**: `/ui-generate-types <slice-file>` - Create TypeScript interfaces
258
+ - **Generate API only**: `/ui-generate-api <slice-file>` - Create Supabase queries or POST commands
259
+ - **Generate hook only**: `/ui-generate-hook <slice-file>` - Create React Query hooks
260
+ - **Generate component only**: `/ui-scaffold-component <slice-files>` - Create React components with Bulma CSS
261
+
262
+ ### Manual Workflow (If not using skills)
263
+
264
+ ### Step 0: Analyze Grouping
265
+ - Find all slices with same `groupId`
266
+ - Check `codeGen.uiPrompts` and `ui-prompt.md`
267
+ - Plan to implement together
268
+
269
+ ### Step 1: Types
270
+ ```typescript
271
+ // src/types/index.ts
272
+ export interface Event {
273
+ event_id: string;
274
+ name: string;
275
+ date: string;
276
+ }
277
+
278
+ export interface CreateEventParams {
279
+ name: string;
280
+ date: string;
281
+ }
282
+ ```
283
+
284
+ ### Step 2: API Functions
285
+ - Add endpoints to `src/lib/api-client.ts`
286
+ - Implement queries (Supabase) in `src/lib/api.ts`
287
+ - Implement commands (POST) in `src/lib/api.ts`
288
+
289
+ ### Step 3: Hooks
290
+ - Create query/mutation hooks in `src/hooks/api/use<Entity>.ts`
291
+ - Export in `src/hooks/api/index.ts`
292
+
293
+ ### Step 4: Components
294
+ - Build list component (STATE_VIEW)
295
+ - Build dialog/form components (STATE_CHANGE)
296
+ - Compose into page component
297
+
298
+ ---
299
+
300
+ ## 7. Field Type Mapping
301
+
302
+ | JSON Type | TypeScript | UI Component |
303
+ |-----------|-----------|--------------|
304
+ | `string` | `string` | `<Input type="text">` |
305
+ | `number` | `number` | `<Input type="number">` |
306
+ | `date` | `string` | `<Input type="date">` |
307
+ | `time` | `string` | `<Input type="time">` |
308
+ | `boolean` | `boolean` | `<Switch>` or `<Checkbox>` |
309
+
310
+ ---
311
+
312
+ ## 8. Common Patterns
313
+
314
+ **Loading**: `if (isLoading) return <Skeleton />;`
315
+
316
+ **Error Handling**:
317
+ ```typescript
318
+ try {
319
+ await mutation.mutateAsync(params);
320
+ toast.success("Success");
321
+ } catch (err) {
322
+ toast.error(`Error: ${err.message}`);
323
+ }
324
+ ```
325
+
326
+ **Form State**: `const [form, setForm] = useState({ field: "" });`
327
+
328
+ **Invalidation**: `queryClient.invalidateQueries({ queryKey: ["entity"] });`
329
+
330
+ ---
331
+
332
+ ## 9. UI Components
333
+
334
+ **NOTE**: The skills in `.claude/skills/` are configured to use **Bulma CSS** for styling. If you're using the skills (especially `/scaffold-component`), components will be generated with Bulma classes.
335
+
336
+ ### Bulma CSS (Used by Skills)
337
+
338
+ When using skills, components use Bulma classes:
339
+ - Layout: `container`, `section`, `columns`, `column`
340
+ - Components: `card`, `modal`, `button`, `notification`, `box`
341
+ - Forms: `field`, `control`, `label`, `input`, `select`, `textarea`
342
+ - Modifiers: `is-primary`, `is-active`, `is-fullwidth`, `has-text-centered`
343
+
344
+ ### shadcn/ui (Alternative)
345
+
346
+ If manually implementing (not using skills), you can use shadcn/ui components:
347
+
348
+ Import from `@/components/ui/*`:
349
+ - `Button`, `Input`, `Label`, `Textarea`, `Select`
350
+ - `Card`, `CardHeader`, `CardTitle`, `CardContent`
351
+ - `Dialog`, `DialogContent`, `DialogHeader`, `DialogTitle`
352
+ - `Table`, `Tabs`, `Skeleton`
353
+ - `toast` from `sonner`
354
+
355
+ **Recommendation**: Use the skills with Bulma CSS for consistency with project configuration.
356
+
357
+ ---
358
+
359
+ ## Checklist
360
+
361
+ **Pre-Implementation**:
362
+ - [ ] Check `groupId` - find all related slices
363
+ - [ ] Read `ui-prompt.md` and `codeGen.uiPrompts`
364
+ - [ ] Identify STATE_VIEW vs STATE_CHANGE slices
365
+
366
+ **Implementation**:
367
+ - [ ] Define types in `src/types/index.ts`
368
+ - [ ] Add endpoints to `src/lib/api-client.ts`
369
+ - [ ] Implement API functions in `src/lib/api.ts`
370
+ - [ ] Create hooks in `src/hooks/api/use<Entity>.ts`
371
+ - [ ] Build components in `src/components/<domain>/`
372
+ - [ ] Compose page combining all grouped slices
373
+ - [ ] Test loading, error handling, success flows
374
+
375
+ ---
376
+
377
+ ## Quick Reference
378
+
379
+ ✅ **Same `groupId`** = Implement together
380
+ ✅ **STATE_VIEW** = Read table → Query hook → List
381
+ ✅ **STATE_CHANGE** = Command → Mutation hook → Form/Dialog
382
+ ✅ **Keep modular** = Sub-components for each slice capability
383
+ ✅ **Keep simple** = Follow existing patterns, don't over-engineer
384
+
385
+ ---
386
+
387
+ ## 10. Skills Usage Examples
388
+
389
+ ### Example 1: Building Complete UI from Scratch
390
+
391
+ **User Request**: "Build the UI for the events management slices"
392
+
393
+ **Your Response**:
394
+ ```bash
395
+ # First, analyze what we're working with
396
+ /ui-analyze-slices src/slices/events/*.json
397
+
398
+ # Then build everything at once
399
+ /ui-build-slice-ui src/slices/events/ViewEvents.json src/slices/events/CreateEvent.json
400
+ ```
401
+
402
+ ### Example 2: Just Need to Understand Slices
403
+
404
+ **User Request**: "What slices are in the orders group?"
405
+
406
+ **Your Response**:
407
+ ```bash
408
+ # Use ui-analyze-slices to understand the grouping
409
+ /ui-analyze-slices src/slices/orders/*.json
410
+ ```
411
+
412
+ ### Example 3: Regenerating Just Types
413
+
414
+ **User Request**: "The Event interface is wrong, regenerate it from the slice"
415
+
416
+ **Your Response**:
417
+ ```bash
418
+ # Use ui-generate-types to recreate just the TypeScript interfaces
419
+ /ui-generate-types src/slices/events/ViewEvents.json
420
+ ```
421
+
422
+ ### Example 4: Adding New API Endpoint
423
+
424
+ **User Request**: "Add the API function for the CancelEvent command"
425
+
426
+ **Your Response**:
427
+ ```bash
428
+ # Use ui-generate-api to create the API layer
429
+ /ui-generate-api src/slices/events/CancelEvent.json
430
+ ```
431
+
432
+ ### Example 5: Understanding UI Requirements
433
+
434
+ **User Request**: "What are the validation rules for the event form?"
435
+
436
+ **Your Response**:
437
+ ```bash
438
+ # Use ui-read-ui-prompts to extract requirements
439
+ /ui-read-ui-prompts src/slices/events/
440
+ ```
441
+
442
+ ### Example 6: Fixing Component Styling
443
+
444
+ **User Request**: "The EventList component doesn't look right, regenerate it with proper Bulma styling"
445
+
446
+ **Your Response**:
447
+ ```bash
448
+ # Use ui-scaffold-component to regenerate with Bulma CSS
449
+ /ui-scaffold-component src/slices/events/ViewEvents.json
450
+ ```
451
+
452
+ ### Decision Tree: Which Skill to Use?
453
+
454
+ ```
455
+ Need to build complete UI from slices?
456
+ └─> /ui-build-slice-ui (orchestrates everything)
457
+
458
+ Just exploring/understanding?
459
+ └─> /ui-analyze-slices (analysis only)
460
+
461
+ Just need to understand UI requirements?
462
+ └─> /ui-read-ui-prompts (extract specs)
463
+
464
+ Need to fix/regenerate specific layer?
465
+ ├─> Types wrong? → /ui-generate-types
466
+ ├─> API functions wrong? → /ui-generate-api
467
+ ├─> Hooks wrong? → /ui-generate-hook
468
+ └─> Components wrong? → /ui-scaffold-component
469
+
470
+ Don't know which skill to use?
471
+ └─> Start with /ui-analyze-slices, then use /ui-build-slice-ui
472
+ ```
473
+
474
+ ---
475
+
476
+ ## Remember
477
+
478
+ **ALWAYS** prefer using the skills over manual implementation! They ensure:
479
+ - Consistency across the codebase
480
+ - Proper use of Bulma CSS
481
+ - Correct CQRS patterns
482
+ - Proper TypeScript types
483
+ - React Query best practices
484
+ - Adherence to UI prompts and validation rules
@@ -1,139 +1,11 @@
1
1
  # Ralph Agent Instructions
2
2
 
3
- You are an autonomous coding agent working on a software project. You apply your skills to build software slices. You only work on one slice at a time.
3
+ You are an autonomous software architect, oversseing the sliced architecture. working on the backend of a software project. You apply your skills to build software slices. You only work on one slice at a time.
4
4
 
5
5
  The structure defined in the Project-Skills is relevant.
6
6
 
7
7
  ## Your Task
8
8
 
9
- 0. Do not read the entire code base. Focus on the tasks in this description.
10
- 1. Read the description at `.slices/index.json` (in the same directory as this file). Every item in status "planned" is a task.
11
- 2. Read the progress log at `progress.txt` (check Codebase Patterns section first)
12
- 3. Make sure you are on the right branch "feature/<slicename>", if unsure, start from main.
13
- 5. Pick the **highest priority** slice where status is "planned" ( case insensitive ). This becomes your PRD. Set the status "InProgress" in the index.json. If no slice has status planned, reply with:
14
- <promise>NO_TASKS</promise> and stop. Do not work on other slices.
15
- 6. Pick the slice definition from the project root /.slices in <folder> defined in the prd. Never work on more than one slice per iteration.
16
- 7. A slice can define additional prompts as codegen/backendPrompt. any additional prompts defined in backend are hints for the implementation of the slice and have to be taken into account. If you use the additional prompt, add a line in progress.txt
17
- 7. Define the slice type and load the matching skill. If the processors-array is not empty, it´s an automation slice.
18
- 8. Write a short progress one liner after each step to progress.txt
19
- 9. Analyze and Implement that single slice, make use of the skills in the skills directory, but also your previsously collected
20
- knowledge. Make a list TODO list for what needs to be done. Also make sure to adjust the implementation according to the json definition. Carefully inspect events, fields and compare against the implemented slice. JSON is the desired state. ATTENTION: A "planned" task can also be just added specifications. So always look at the slice itself, but also the specifications. If specifications were added in json, which are not on code, you need to add them in code.
21
- 10. The slice in the json is always true, the code follows what is defined in the json
22
- 11. slice is only 'Done' if business logic is implemented as defined in the JSON, APIs are implemented, all scenarios in JSON are implemented in code and it
23
- fulfills the slice.json. There must be no specification in json, that has no equivalent in code.
24
- 12. make sure to write the ui-prompt.md as defined if defined in the skill
25
- 13. Run quality checks ( npm run build, npm run test ) - Attention - it´s enough to run the tests for the slice. Do not run all tests.
26
- 14. even if the slice is fully implemented, run your test-analyzer skill and provide the code-slice.json file as defined in the skill
27
- 15. Update the Slice in the index.json to either `status: Done` for the completed, 'status: Planned' if rework is necessary.
28
- 16. If checks pass, commit ALL changes with message: `feat: [Slice Name]` and merge back to main as FF merge ( update
29
- first )
30
- 17. Append your progress to `progress.txt` after each step in the iteration.
31
- 18. append your new learnings to AGENTS.md in a compressed form, reusable for future iterations. Only add learnings if they are not already there.
32
- 19. Finish the iteration.
33
-
34
- ## Progress Report Format
35
-
36
- APPEND to progress.txt (never replace, always append):
37
-
38
- ```
39
- ## [Date/Time] - [Slice]
40
-
41
- - What was implemented
42
- - Files changed
43
- - **Learnings for future iterations:**
44
- - Patterns discovered (e.g., "this codebase uses X for Y")
45
- - Gotchas encountered (e.g., "don't forget to update Z when changing W")
46
- - Useful context (e.g., "the evaluation panel is in component X")
47
- ---
48
- ```
49
-
50
- The learnings section is critical - it helps future iterations avoid repeating mistakes and understand the codebase
51
- better.
52
-
53
- ## Consolidate Patterns
54
-
55
- If you discover a **reusable pattern** that future iterations should know, add it to the `## Codebase Patterns` section
56
- at the TOP of progress.txt (create it if it doesn't exist). This section should consolidate the most important
57
- learnings:
58
-
59
- ```
60
- ## Codebase Patterns
61
- - Example: Use `sql<number>` template for aggregations
62
- - Example: Always use `IF NOT EXISTS` for migrations
63
- - Example: Export types from actions.ts for UI components
64
- ```
65
-
66
- Only add patterns that are **general and reusable**, not story-specific details.
67
-
68
- ## Update AGENTS.md Files
69
-
70
- Before committing, check if any edited files have learnings worth preserving in nearby AGENTS.md files:
71
-
72
- 1. **Identify directories with edited files** - Look at which directories you modified
73
- 3. **Add valuable learnings that apply to all tasks** to the Agents.md - If you discovered something future developers/agents should know:
74
- - API patterns or conventions specific to that module
75
- - Gotchas or non-obvious requirements
76
- - Dependencies between files
77
- - Testing approaches for that area
78
- - Configuration or environment requirements
79
-
80
- **Examples of good AGENTS.md additions:**
81
-
82
- - "When modifying X, also update Y to keep them in sync"
83
- - "This module uses pattern Z for all API calls"
84
- - "Tests require the dev server running on PORT 3000"
85
- - "Field names must match the template exactly"
86
-
87
- **Do NOT add:**
88
-
89
- - Slice specific implementation details
90
- - Story-specific implementation details
91
- - Temporary debugging notes
92
- - Information already in progress.txt
93
- - Task speecific learnings like "- Timesheet approval requires: submitted=true, reverted=false, approved=false, declined=false"
94
-
95
- Only update AGENTS.md if you have **genuinely reusable knowledge** that would help future work
96
-
97
- ## Quality Requirements
98
-
99
- - ALL commits must pass your project's quality checks (typecheck, lint, test)
100
- - run 'npm run build'
101
- - run 'npm run test'
102
- - Do NOT commit broken code
103
- - Keep changes focused and minimal
104
- - Follow existing code patterns
105
-
106
- ## Skills
107
-
108
- Use the provided skills in the skills folder as guidance.
109
- Update skill definitions if you find an improvement you can make.
110
-
111
- ## Specifications
112
-
113
- For every specification added to the Slice, you need to implement one use executable Specification in Code.
114
-
115
- A Slice is not complete if specifications are missing or can´t be executed.
116
-
117
- ## Stop Condition
118
-
119
- After completing a user story, check if ALL slices have `status: Done`.
120
-
121
- If ALL stories are complete and passing, reply with:
122
- <promise>COMPLETE</promise>
123
-
124
- If there are no stories with `status: Planned` (but not all are Done), reply with:
125
- <promise>NO_TASKS</promise>
126
-
127
- If there are still stories with `status: Planned`, end your response normally (another iteration will pick up the next
128
- story).
129
-
130
- ## Important
131
-
132
- - Work on ONE slice per iteration
133
- - Commit frequently
134
- - update progress.txt frequently
135
- - Read the Codebase Patterns section in progress.txt before starting
136
-
137
- ## When an iteration completes
138
-
139
- Use all the key learnings from the project.txt and update the Agends.md file with those learning.
9
+ 1. find the most important next slice
10
+ 2. if the slice is in status planned and not assigned, assign it to backend_worker (property assigned in ) and continue with backend/prompt.md. Ignore the rest of this file.
11
+ 3. if the slice is in status planned and assigned to ui_worker, continue with frontend/prompt.md. Ignore the rest of this file.
@@ -172,6 +172,18 @@ const server = createServer(async (req, res) => {
172
172
 
173
173
  // Write all slices
174
174
  if (config.slices) {
175
+ // Build a map of slice ID to group ID from sliceGroups
176
+ const sliceToGroupMap = new Map();
177
+ if (config.sliceGroups) {
178
+ config.sliceGroups.forEach((group) => {
179
+ if (group.sliceIds) {
180
+ group.sliceIds.forEach((sliceId) => {
181
+ sliceToGroupMap.set(sliceId, group.id);
182
+ });
183
+ }
184
+ });
185
+ }
186
+
175
187
  config.slices.forEach((slice) => {
176
188
  const baseFolder = join(SLICES_DIR, slice.context ?? "default");
177
189
  const sliceFolder = slice.title?.replaceAll(" ", "")?.replaceAll("slice:", "")?.toLowerCase();
@@ -184,6 +196,13 @@ const server = createServer(async (req, res) => {
184
196
  const filePath = join(folder, 'slice.json');
185
197
  const sliceData = { ...slice };
186
198
  delete sliceData.index;
199
+
200
+ // Add group ID to slice data if it belongs to a group
201
+ const groupId = sliceToGroupMap.get(slice.id);
202
+ if (groupId) {
203
+ sliceData.group = groupId;
204
+ }
205
+
187
206
  writeFileSync(filePath, JSON.stringify(sliceData, null, 2));
188
207
 
189
208
  const sliceIndex = {
@@ -195,6 +214,11 @@ const server = createServer(async (req, res) => {
195
214
  status: slice.status
196
215
  };
197
216
 
217
+ // Add group ID to index entry if it belongs to a group
218
+ if (groupId) {
219
+ sliceIndex.group = groupId;
220
+ }
221
+
198
222
  const index = sliceIndices.slices.findIndex(it => it.id == slice.id);
199
223
  if (index == -1) {
200
224
  sliceIndices.slices.push(sliceIndex);
@@ -223,8 +247,6 @@ const server = createServer(async (req, res) => {
223
247
  }
224
248
 
225
249
  sendJSON(res, { success: true, path: join(ROOT, fileName) });
226
- console.log('🛑 Shutting down server...');
227
- server.close(() => process.exit(0));
228
250
  } catch (err) {
229
251
  sendJSON(res, { success: false, error: err.message }, 400);
230
252
  }