@eventmodelers/cli 1.0.53 → 1.0.55

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 (53) hide show
  1. package/README.md +6 -0
  2. package/cli.js +29 -1
  3. package/package.json +1 -1
  4. package/shared/build-kit/lib/ralph.js +103 -5
  5. package/shared/build-kit/lib/util/find-slice.cjs +2 -0
  6. package/shared/skills/learn-eventmodelers-api/SKILL.md +3 -0
  7. package/stacks/node/templates/build-kit/lib/check-commit-scope.cjs +17 -4
  8. package/stacks/node/templates/root/.githooks/pre-commit +10 -3
  9. package/stacks/react/templates/.claude/skills/build-automation/SKILL.md +42 -0
  10. package/stacks/react/templates/.claude/skills/build-state-change/SKILL.md +43 -0
  11. package/stacks/react/templates/.claude/skills/build-state-view/SKILL.md +42 -0
  12. package/stacks/react/templates/build-kit/CLAUDE.md +62 -0
  13. package/stacks/react/templates/build-kit/README.md +79 -0
  14. package/stacks/react/templates/build-kit/lib/AGENT.md +47 -0
  15. package/stacks/react/templates/build-kit/lib/backend-prompt.md +135 -0
  16. package/stacks/react/templates/build-kit/lib/prompt.md +139 -0
  17. package/stacks/react/templates/build-kit/lib/ralph.js +508 -0
  18. package/stacks/react/templates/build-kit/package.json +9 -0
  19. package/stacks/react/templates/build-kit/ralph-claude.js +107 -0
  20. package/stacks/react/templates/build-kit/ralph-ollama.js +40 -0
  21. package/stacks/supabase/templates/build-kit/lib/check-commit-scope.cjs +17 -4
  22. package/stacks/supabase/templates/root/.githooks/pre-commit +10 -3
  23. package/stacks/supabase-react/templates/.claude/skills/build-state-change/SKILL.md +305 -0
  24. package/stacks/supabase-react/templates/.claude/skills/build-state-view/SKILL.md +238 -0
  25. package/stacks/supabase-react/templates/.claude/skills/init-style-guide/SKILL.md +60 -0
  26. package/stacks/supabase-react/templates/.claude/skills/learn-styleguide/SKILL.md +28 -0
  27. package/stacks/supabase-react/templates/.claude/skills/learn-styleguide/references/README.md +5 -0
  28. package/stacks/supabase-react/templates/build-kit/CLAUDE.md +149 -0
  29. package/stacks/supabase-react/templates/build-kit/lib/AGENT.md +47 -0
  30. package/stacks/supabase-react/templates/build-kit/lib/backend-prompt.md +139 -0
  31. package/stacks/supabase-react/templates/build-kit/lib/prompt.md +145 -0
  32. package/stacks/supabase-react/templates/root/.env.example +12 -0
  33. package/stacks/supabase-react/templates/root/.oxlintrc.json +9 -0
  34. package/stacks/supabase-react/templates/root/README.md +49 -0
  35. package/stacks/supabase-react/templates/root/index.html +13 -0
  36. package/stacks/supabase-react/templates/root/package.json +26 -0
  37. package/stacks/supabase-react/templates/root/public/favicon.svg +1 -0
  38. package/stacks/supabase-react/templates/root/public/icons.svg +24 -0
  39. package/stacks/supabase-react/templates/root/src/App.css +184 -0
  40. package/stacks/supabase-react/templates/root/src/App.tsx +122 -0
  41. package/stacks/supabase-react/templates/root/src/assets/hero.png +0 -0
  42. package/stacks/supabase-react/templates/root/src/assets/react.svg +1 -0
  43. package/stacks/supabase-react/templates/root/src/assets/vite.svg +1 -0
  44. package/stacks/supabase-react/templates/root/src/index.css +111 -0
  45. package/stacks/supabase-react/templates/root/src/lib/api.ts +127 -0
  46. package/stacks/supabase-react/templates/root/src/lib/supabase.ts +10 -0
  47. package/stacks/supabase-react/templates/root/src/main.tsx +10 -0
  48. package/stacks/supabase-react/templates/root/src/slices/.gitkeep +0 -0
  49. package/stacks/supabase-react/templates/root/src/vite-env.d.ts +13 -0
  50. package/stacks/supabase-react/templates/root/tsconfig.app.json +26 -0
  51. package/stacks/supabase-react/templates/root/tsconfig.json +7 -0
  52. package/stacks/supabase-react/templates/root/tsconfig.node.json +23 -0
  53. package/stacks/supabase-react/templates/root/vite.config.ts +7 -0
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: init-style-guide
3
+ description: Interview the user for CSS, design tokens, brand documents, or any existing style guide material, and persist it as references inside the learn-styleguide skill so UI-generating skills (build-state-change, build-state-view) stay on-brand
4
+ ---
5
+
6
+ # Init Style Guide
7
+
8
+ Run this whenever the user wants to give this project a design system to follow — "here's our
9
+ style guide", "add our brand CSS", "use this doc for the UI" — or wants to add more material to
10
+ one already started. This skill only collects and files material; it does not itself apply any
11
+ styling to code.
12
+
13
+ ## Step 1 — Ask what they have
14
+
15
+ Ask the user what they'd like to provide. Accept any of:
16
+ - An existing CSS/SCSS file (a path) — design tokens, a component library stylesheet, a Tailwind
17
+ config, etc.
18
+ - A brand/style guide document (Markdown, PDF, plain text, a Figma export, ...) — a path.
19
+ - Pasted text/tokens directly in the conversation (e.g. a color palette, font stack, spacing
20
+ scale).
21
+ - A URL to a live, publicly reachable style guide page — only if the user gives the URL
22
+ themselves; never search for or guess one.
23
+
24
+ If they have nothing to add right now, stop — do not create empty placeholder files.
25
+
26
+ ## Step 2 — Persist each item as a reference, verbatim
27
+
28
+ For every item provided, write it into `.claude/skills/learn-styleguide/references/`. **Never
29
+ summarize, rewrite, or supplement** what was given — this is a store of source material, not an
30
+ interpretation of it.
31
+
32
+ - **A file path** → copy the file as-is into `references/<original-filename>`, preserving its
33
+ extension (`.css`, `.scss`, `.md`, `.pdf`, ...).
34
+ - **A URL** → fetch it and save the raw content into `references/<slugified-title-or-host>.md`,
35
+ with a one-line header noting the source URL and the fetch date.
36
+ - **Pasted text/tokens** → write into `references/<short-slug>.md`, wrapped in a fenced code block
37
+ when it's CSS/code, with a one-line header noting what it is and the date provided.
38
+
39
+ Pick filenames that describe the content (`brand-colors.css`, `component-library.md`,
40
+ `voice-and-tone.pdf`), never generic names like `input1`.
41
+
42
+ If `references/` already has files from a previous run, list them back to the user first so they
43
+ know what's already covered, then only add what's new. Never delete or overwrite an existing
44
+ reference unless the user confirms that specific file should be replaced.
45
+
46
+ ## Step 3 — Refresh learn-styleguide's index
47
+
48
+ In `.claude/skills/learn-styleguide/SKILL.md`, replace the `## References` section's contents with
49
+ one bullet per file now in `references/` — filename plus a short (one-line) description of what it
50
+ contains, based on a quick read of the file, never invented. Leave everything else in that file
51
+ (frontmatter, the "How to use this skill" section) untouched.
52
+
53
+ ## Step 4 — Confirm
54
+
55
+ Tell the user what was saved and where, e.g.:
56
+ ```
57
+ Saved to .claude/skills/learn-styleguide/references/:
58
+ - brand-colors.css (CSS custom properties: primary/secondary palette, spacing scale)
59
+ - voice-and-tone.md (brand document — tone, terminology to avoid)
60
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: learn-styleguide
3
+ description: This project's visual style guide / design system reference material — read before generating or redesigning any UI (screens, components). Populated and kept up to date by the init-style-guide skill.
4
+ ---
5
+
6
+ # Style Guide References
7
+
8
+ ## References
9
+
10
+ _None yet — run `init-style-guide` to add CSS, design tokens, or brand documents._
11
+
12
+ ## How to use this skill
13
+
14
+ Before turning a marked screen fragment into a component (`build-state-change`/`build-state-view`
15
+ Step 2), or designing any new screen, read whichever file(s) under `references/` are relevant to
16
+ the task at hand — colors/typography/spacing before styling, a component-library doc before
17
+ choosing markup patterns, a voice-and-tone doc before writing copy.
18
+
19
+ Prefer these references over values invented on the spot, and prefer them over an existing screen
20
+ mockup's own ad hoc inline styles when the two disagree — the mockup gives structure and content,
21
+ this skill gives the real visual language.
22
+
23
+ Do not invent references that aren't listed above. If the current task needs a design decision
24
+ these references don't cover, fall back to what the mockup/task already gives you rather than
25
+ guessing a brand rule — or ask the user, if the choice materially affects business logic.
26
+
27
+ This skill's content is entirely sourced from what the user provided via `init-style-guide` —
28
+ never add, rewrite, or supplement it with invented material.
@@ -0,0 +1,5 @@
1
+ # References
2
+
3
+ Source material dropped here by `init-style-guide`, verbatim — CSS/SCSS files, brand or style
4
+ guide documents, saved pages, or pasted design tokens. Each file is exactly what the user provided;
5
+ nothing here is generated or summarized. See `../SKILL.md` for how these get used.
@@ -0,0 +1,149 @@
1
+ # Project Configuration
2
+
3
+ Read `src/slices` to understand the global structure — each subdirectory is one board slice; there is no other domain code in this project.
4
+
5
+ This stack is UI-only: it only builds **state-change** (command → event, write side) and
6
+ **state-view** (read model, read side) slices. Translation slices default to
7
+ `build-state-change`. Automations/processors have no UI counterpart here — if a slice's
8
+ `processors` array is non-empty, that slice belongs to a backend stack, not this one; do
9
+ not attempt to build it, flag it via `request-feedback` instead.
10
+
11
+ ## File Structure Constraints
12
+
13
+ - **Strict Path Limitation**: `src/slices/{contextSlug}/{laneSlug}/{slicename}/*` — the one
14
+ exception is `src/pages/`, where multiple slices sharing one screen get composed together (see
15
+ guideline 8 below)
16
+ - **Slice Organization**: Each feature/domain should be organized as a separate slice
17
+
18
+ ## Code Standards
19
+
20
+ - **Language**: TypeScript
21
+ - **Module System**: ESM
22
+ - **Type Safety**: TypeScript, strict mode (see `tsconfig.app.json`)
23
+
24
+ ## Development Guidelines
25
+
26
+ 1. Each slice should be self-contained and focused on a specific domain
27
+ 2. Maintain clear separation of concerns within each slice
28
+ 3. Headers, auth, `fetch`, and Supabase table access live exclusively in `src/lib/api.ts` — a
29
+ slice component never imports `src/lib/supabase.ts` itself, never calls `fetch`, and never
30
+ calls `supabase.from(...)` directly; it calls `postCommand`/`queryReadModel` and only contains
31
+ business logic (validation, request-body shaping, response handling)
32
+ 4. A command's/read-model's screen markup (`meta.pages` on its actor HTML_SCREEN node, scoped to
33
+ this slice's `meta.marks` when the screen is shared) is the visual blueprint — translate it into
34
+ JSX rather than redesigning it; see `build-state-change`/`build-state-view` Step 2
35
+ 5. A slice's business logic lives in its component by default (plain `useState`, no ceremony). Only
36
+ split it into a colocated `use<Name>.ts` hook when that's genuinely warranted — reused by more
37
+ than one sibling component, or non-rendering logic large enough that separating it clearly helps
38
+ — never by default or "for consistency"; see `build-state-change`/`build-state-view` Step 3.
39
+ 6. **Design every slice for deletability**: its folder must be removable wholesale without
40
+ leaving dangling imports elsewhere.
41
+ - Local state shared only *within* one slice's sub-components (e.g. a multi-step command, a
42
+ list + submit bar) — and *only* when a single component's own `useState` genuinely can't hold
43
+ it — gets its own `<Name>Context.tsx`, colocated in that same slice folder, never in
44
+ `src/lib`, never imported by another slice. This is the exception, not the default; most
45
+ slices need no Context at all. Follow the same `createContext`/`XProvider`/`useX` shape used
46
+ in this pattern's origin, `miro-eventmodeling` (e.g. `useReadOnly`/`ReadOnlyProvider`,
47
+ `useUser`/`UserProvider`): a context object, a `<Name>Provider>` component owning the state,
48
+ and a `use<Name>` hook wrapping `useContext` — throwing if the value is missing when there's
49
+ no sensible default (slice-scoped state always throws), returning a plain default only for
50
+ something genuinely app-wide.
51
+ - Only concerns that are truly cross-cutting (current session, theme, feature flags — things
52
+ every slice might need) get a shared provider under `src/lib/`, composed once where the app
53
+ mounts its providers (e.g. `src/main.tsx`), the same way `miro-eventmodeling`'s root layout
54
+ nests `UserProvider`/`OrganizationProvider`/etc.
55
+ - A slice component must never import from another slice's folder — the one place that's allowed
56
+ to is `src/pages/` (guideline 7). If two slices seem to need the same state, that state belongs
57
+ in a `src/lib` provider, not a cross-slice import.
58
+ 7. **A screen's title is the page name.** Several slices can each hold their own copy of one shared
59
+ visual screen (one node per slice, each with a different mark, per the `html-screen` skill) —
60
+ when their screens share a `title`, their components belong on one real page together, arranged
61
+ as the marks show. The count of *distinct* screen titles across the board is a direct hint at how
62
+ many pages this app needs, not one page per slice. That composition lives at
63
+ `src/pages/<ScreenTitle>.tsx`, translating the screen's whole unmarked markup into JSX and
64
+ substituting each marked position with that slice's actual component; see
65
+ `build-state-change`/`build-state-view`'s page-composition step for the full procedure.
66
+ 8. **A screen's lane is reflected in the folder.** The actor row (lane) a slice's screen is placed
67
+ in on the board — e.g. "Admin" vs. "Customer" — becomes a folder segment between context and
68
+ slice: `src/slices/<contextSlug>/<laneSlug>/<sliceFolder>/`. Resolve it via
69
+ `mcp__eventmodelers__get_board_outline` on the screen's chapter (returns `{id, type, title,
70
+ lane}` per node); see `build-state-change`/`build-state-view` Step 2. Omit the segment only for
71
+ the rare slice with no screen at all.
72
+ 9. **Every component is testable in isolation, with samples.** A component must render sensibly
73
+ with no data (an empty/background state, not a crash), and must be exercisable with no real
74
+ backend running. Every slice ships a colocated `samples/sample-<N>.json` per numbered scenario
75
+ (`sample-1.json`, `sample-2.json`, ...) — for a STATE_VIEW component, shaped exactly like the
76
+ row(s) its `queryReadModel` call returns; for a STATE_CHANGE component, a full set of prop
77
+ values. `src/lib/api.ts`'s `postCommand`/`queryReadModel` are mock-aware: set
78
+ `VITE_DATA_MODE=mock` and every read is served from `samples/sample-<VITE_MOCK_SAMPLE>.json`
79
+ instead of Supabase, and every command POST resolves locally instead of hitting the network —
80
+ flipping one env var is the "switch between samples" mechanism, nothing per-component to wire.
81
+ The same number across different components' samples represents one coherent scenario across
82
+ the app, not an arbitrary per-component index. See `build-state-change`/`build-state-view`'s
83
+ samples step for the full convention.
84
+
85
+ At the start of every session, read `.build-kit/AGENTS.md` if it exists to load accumulated project learnings.
86
+
87
+ When starting to work on a slice, invoke the `update-slice-status` skill with `InProgress` status before doing anything else.
88
+
89
+ ## Building a Slice
90
+
91
+ **CRITICAL: You MUST always use the provided skills to build slices. NEVER implement a slice manually.**
92
+ **ALL fields, event names, command names, and business rules MUST come exclusively from slice.json. Do NOT invent, assume, or guess any field or logic not present in the slice definition.**
93
+
94
+ **If, at any point below, the slice's requirements are genuinely ambiguous, contradictory, or missing
95
+ a decision you need in order to proceed — do not guess, and do not build anyway.** Invoke the
96
+ `request-feedback` skill with the specific question; it posts the question as a comment on the slice
97
+ and marks it `Blocked`, and you then stop work on this slice for this run. This is an escalation path,
98
+ not a routine step — read `slice.json` and the matching build skill's own instructions fully first;
99
+ most slices are fully specified and need none of this.
100
+
101
+ **Exception: a missing `apiEndpoint`** (no backend endpoint/table decided yet) is a partial version of
102
+ this — flag it, but don't fully stop. `build-state-change`/`build-state-view` Step 1 cover the exact
103
+ mechanics: post a comment on the slice and mark it `Blocked` (same as `request-feedback`), but then
104
+ keep going — build the slice normally against a provisional mock path/table name with meaningful
105
+ sample data. The slice ends this run `Blocked` (step 6 below does not flip it to `Done`), but the code
106
+ is there, mocked, ready to be pointed at the real API once one exists.
107
+
108
+ When asked to build a slice, always follow this flow:
109
+
110
+ 1. Read the slice definition from `.build-kit/.slices/<contextSlug>/<sliceFolder>/slice.json`.
111
+ 2. Determine the slice type from `sliceType`:
112
+ - **`STATE_CHANGE`** → invoke `/build-state-change`
113
+ - **`STATE_VIEW`** → invoke `/build-state-view`
114
+ - **`AUTOMATION`** → not this stack's job (no UI counterpart) — invoke `request-feedback`
115
+ rather than building it; it belongs to whichever backend stack is installed alongside this one
116
+ 3. Invoke the matching skill and follow its instructions completely. Do not deviate.
117
+ 4. **Verify against slice.json**: After the skill completes, check that every command field, event field, and specification in slice.json appears in the implementation. No invented fields — if it is not in slice.json, it must not be in the code.
118
+ 5. Run `npm run build` and `npm run lint` (both must pass clean), then the slice's own tests only, if any exist.
119
+ 6. If checks pass, commit with `feat: [Slice Name]` and set slice status to `Done` — **unless** the
120
+ matching build skill flagged a missing `apiEndpoint` and already marked the slice `Blocked`
121
+ (Step 1 exception above); in that case, commit as normal but leave the status `Blocked`.
122
+
123
+ After you are done, automatically run the tests for the slice that was edited.
124
+
125
+ ## Example Slice Structure
126
+
127
+ ```
128
+ src/lib/supabase.ts # Supabase client singleton — imported ONLY by api.ts
129
+ src/lib/api.ts # postCommand/queryReadModel + auth headers + mock-mode switch (shared, not per-slice)
130
+ src/lib/<CrossCutting>Provider.tsx # only for concerns every slice might need (session, theme, ...)
131
+ src/pages/<ScreenTitle>.tsx # only when >1 slice shares a screen title — composes their components
132
+ src/slices/<contextSlug>/<laneSlug>/<sliceFolder>/
133
+ <CommandTitle>.tsx # STATE_CHANGE slice — component (logic inline by default)
134
+ use<CommandTitle>.ts # only if the logic was genuinely worth splitting out
135
+ <CommandTitle>Context.tsx # only if sibling components must share state
136
+ <ReadModelTitle>.tsx # STATE_VIEW slice — component (logic inline by default)
137
+ samples/
138
+ sample-1.json # one numbered scenario per file — props (STATE_CHANGE) or query result (STATE_VIEW)
139
+ sample-2.json
140
+ ```
141
+
142
+ Everything under one `<sliceFolder>/` is deletable as a unit — nothing outside it should import
143
+ from it except the parent that renders the slice's top-level component, or `src/pages/` when this
144
+ slice's screen is composed into a shared page.
145
+
146
+ `contextSlug`/`sliceFolder` are derived exactly as in the `load-slice` skill, and `laneSlug` per
147
+ guideline 8 above — so a slice's frontend code nests one level deeper than the staging data at
148
+ `.build-kit/.slices/<contextSlug>/<sliceFolder>/slice.json` (which has no lane concept), rather
149
+ than mirroring it 1:1.
@@ -0,0 +1,47 @@
1
+ # Agent Learnings
2
+
3
+ Patterns and gotchas discovered during task processing. Update this file whenever you encounter something reusable.
4
+
5
+ ## tasks.json
6
+
7
+ - Tasks are objects with `id`, `createdAt`, and `payload` (a `SliceChangedPayload`).
8
+ - After completing a task, remove it from the array entirely — do not add a status field.
9
+ - Write `[]` to `tasks.json` if the last task is completed.
10
+
11
+ ## SliceChangedPayload fields
12
+
13
+ ```
14
+ event always "slice:changed"
15
+ organizationId org UUID or null
16
+ boardId board UUID
17
+ sliceId SLICE_BORDER node UUID — use this with /load-slice
18
+ sliceTitle human-readable slice name (may be null)
19
+ sliceStatus e.g. "Created", "InProgress", "Done", "Blocked" (may be null)
20
+ timestamp unix ms when the change was emitted
21
+ ```
22
+
23
+ ## Slice files
24
+
25
+ The realtime agent writes one file per slice on startup and after each `slice:changed` event:
26
+
27
+ ```
28
+ .slices/<context>/<sliceName>.json
29
+ ```
30
+
31
+ - `<context>` is the slice's context value, or `default` if none.
32
+ - `<sliceName>` is the slice title lowercased with spaces and the `"slice:"` prefix removed (e.g. `"slice: Enable User"` → `enableuser`).
33
+
34
+ These files are always up to date — read them directly before invoking any skill.
35
+
36
+ ## Skill Usage
37
+
38
+ - Always run `/connect` first to load credentials from `.eventmodelers/config.json` before calling any other skill.
39
+ - `/load-slice sliceId=<uuid>` re-fetches all slices from the API, refreshes the slice files, and returns the requested slice. Use it when you need a guaranteed-fresh view of a specific slice.
40
+ - Read `.slices/<context>/<sliceName>.json` directly when you already know the context and name and the file is recent enough.
41
+
42
+ ## Board API
43
+
44
+ - The `boardId` and `organizationId` from each payload provide full context — pass them to skills.
45
+ - Node events use `node:created`, `node:changed`, `node:deleted` — always POST to `/api/org/:orgId/boards/:boardId/nodes/events`.
46
+ - Slice metadata (title, status) lives on the SLICE_BORDER node under `meta.sliceStatus` and `meta.title`.
47
+ - `/update-slice-status` rejects moving a slice into a status it's already in — this is a concurrency guard, not a bug. It means another agent already claimed the slice. Treat it as `ALREADY_IN_STATUS`, skip that slice, and move on to the next `Planned` one instead of erroring out.
@@ -0,0 +1,139 @@
1
+ # Ralph Agent Instructions
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.
4
+
5
+ The structure defined in the Project-Skills is relevant.
6
+
7
+ ## Context Boundary (READ FIRST — NON-NEGOTIABLE)
8
+
9
+ You work within **exactly ONE context at a time** — the one named in `.build-kit/.slices/current_context.json`.
10
+
11
+ - **ONLY** look for and build slices inside `.build-kit/.slices/<currentContext>/`.
12
+ - **NEVER** read, scan, or build slices from any other context directory, even if it has "Planned" slices, and even if the current context has no work left.
13
+ - A "Planned" slice in a *different* context is **NOT yours to build**. Ignore it completely.
14
+ - If the current context has no "Planned" slice, you are **done for this iteration** — reply `<promise>NO_TASKS</promise>` and stop. Do not go looking elsewhere. The context is only ever changed on the board, never by you.
15
+
16
+ ## Your Task
17
+
18
+ 0. Do not read the entire code base. Focus on the tasks in this description.
19
+ 1. Read `.build-kit/.slices/current_context.json` to find the active context name, then read `.build-kit/.slices/<contextName>/index.json`. Every item in status "planned" is a task.
20
+ 2. Read the progress log at `progress.txt` (check Codebase Patterns section first)
21
+ 3. Make sure you are on the right branch "feature/<slicename>", if unsure, start from main.
22
+ 5. Pick the **highest priority** slice where status is **exactly** "Planned" (case insensitive). This becomes your PRD. Set the status "InProgress" in the index.json **and** update the slice status on the eventmodelers board using the `update-slice-status` skill (or MCP if available).
23
+ **IMPORTANT: Only work on slices with status "Planned" in the CURRENT context. Never pick up a slice that is "InProgress", "Done", "Blocked", "Created", or any other status — even if it looks incomplete. If no slice has status "Planned" in the current context, reply with:**
24
+ <promise>NO_TASKS</promise> and stop immediately. Do not work on other slices and do not switch to another context.
25
+ **Claim conflict**: the board rejects the status update if the slice is already in the target status — this is expected: another agent claimed it first, racing you for the same slice. This is NOT an error. Do not stop, do not retry the same slice. Re-read `index.json` (or re-fetch via `load-slice`), pick the next-highest-priority slice still "Planned", and try claiming that one instead. Repeat until a claim succeeds or no "Planned" slice remains, in which case reply `<promise>NO_TASKS</promise>`.
26
+ 6. Pick the slice definition from `.build-kit/.slices/<contextName>/<folder>/slice.json` as defined in the prd. Never work on more than one slice per iteration.
27
+ 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
28
+ 7. Determine the slice type and invoke the matching skill as defined in the **Building a Slice** section of `.build-kit/CLAUDE.md`. Do NOT implement manually.
29
+ 8. Write a short progress one liner after each step to progress.txt
30
+ 9. Analyze and Implement that single slice, making use of the skills in the skills directory plus your previously collected knowledge. Make a TODO list for what needs to be done, and 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.
31
+ 10. The slice in the json is always true, the code follows what is defined in the json
32
+ 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 fulfills the slice.json. There must be no specification in json that has no equivalent in code.
33
+ 12. Make sure to write the ui-prompt.md as defined if defined in the skill
34
+ 13. Run quality checks — `npm run build` (typecheck + build) and `npm run lint`. No test runner is configured in this stack yet; if a slice's specifications demand behavioral tests, flag it via `request-feedback` instead of inventing a test setup ad hoc.
35
+ 14. If checks pass, commit ALL changes with message: `feat: [Slice Name]` and merge back to main as FF merge (update first)
36
+ 15. Update the PRD to set `status: Done` for the completed story in index.json **and** update the slice status on the eventmodelers board using the `update-slice-status` skill (or MCP if available).
37
+ 16. Append your progress to `progress.txt` after each step in the iteration.
38
+ 17. Append your new learnings to `.build-kit/AGENTS.md` in a compressed form, reusable for future iterations. Only add learnings if they are not already there.
39
+ 18. Finish the iteration.
40
+
41
+ ## Escalating Ambiguity
42
+
43
+ **If the slice's requirements are genuinely ambiguous, contradictory, or missing a decision you need
44
+ in order to proceed — do not guess, and do not build anyway.** Invoke `/request-feedback` with the
45
+ specific question; it posts the question as a comment on the slice and marks it `Blocked` on the
46
+ board (overriding the `InProgress` set in step 5), then stop this iteration without finishing the
47
+ build — reply `<promise>DONE</promise>` as if the iteration's work was to raise the question, not to
48
+ implement the slice. This is an escalation path, not a routine step — read the slice.json and the
49
+ matching build skill's own instructions fully first; most slices are fully specified and need none of
50
+ this.
51
+
52
+ ## Progress Report Format
53
+
54
+ APPEND to progress.txt (never replace, always append):
55
+
56
+ ```
57
+ ## [Date/Time] - [Slice]
58
+
59
+ - What was implemented
60
+ - Files changed
61
+ - **Learnings for future iterations:**
62
+ - Patterns discovered (e.g., "this codebase uses X for Y")
63
+ - Gotchas encountered (e.g., "don't forget to update Z when changing W")
64
+ - Useful context (e.g., "the evaluation panel is in component X")
65
+ ---
66
+ ```
67
+
68
+ The learnings section is critical - it helps future iterations avoid repeating mistakes and understand the codebase better.
69
+
70
+ ## Consolidate Patterns
71
+
72
+ If you discover a **reusable pattern** that future iterations should know, add it to the `## Codebase Patterns` section at the TOP of progress.txt (create it if it doesn't exist).
73
+
74
+ ```
75
+ ## Codebase Patterns
76
+ - TODO: an example of a your stack-specific reusable pattern once you have one
77
+ ```
78
+
79
+ Only add patterns that are **general and reusable**, not story-specific details.
80
+
81
+ ## Update AGENTS.md Files
82
+
83
+ Before committing, check if any edited files have learnings worth preserving in nearby AGENTS.md files — API patterns/conventions, gotchas, dependencies between files, testing approaches, configuration/environment requirements.
84
+
85
+ **Do NOT add:**
86
+
87
+ - Slice specific implementation details
88
+ - Story-specific implementation details
89
+ - Temporary debugging notes
90
+ - Information already in progress.txt
91
+ - Task-specific learnings
92
+
93
+ Only update AGENTS.md if you have **genuinely reusable knowledge** that would help future work
94
+
95
+ ## Quality Requirements
96
+
97
+ - ALL commits must pass this project's quality checks (typecheck/compile, lint, test)
98
+ - TODO: your stack's build command
99
+ - TODO: your stack's test command
100
+ - Do NOT commit broken code
101
+ - Keep changes focused and minimal
102
+ - Follow existing code patterns
103
+
104
+ ## Skills
105
+
106
+ Use the provided skills in the skills folder as guidance.
107
+ Update skill definitions if you find an improvement you can make.
108
+
109
+ ## Specifications
110
+
111
+ For every specification added to the Slice, you need to implement one executable Specification in Code.
112
+
113
+ A Slice is not complete if specifications are missing or can't be executed.
114
+
115
+ ## Stop Condition
116
+
117
+ **After completing ONE slice, always stop — regardless of whether more slices are Planned.** The ralph loop will invoke you again for the next slice. Never chain multiple slices in one iteration.
118
+
119
+ If the slice was completed and committed successfully, reply with:
120
+ <promise>DONE</promise>
121
+
122
+ If no slice has status "Planned" in the current context, reply with:
123
+ <promise>NO_TASKS</promise>
124
+ (Do NOT switch to another context to find work — stop here.)
125
+
126
+ If ALL slices in the current context are Done, reply with:
127
+ <promise>COMPLETE</promise>
128
+
129
+ ## Important
130
+
131
+ - If `.build-kit/.eventmodelers/config.json` is absent, skip all platform communication (MCP calls, `update-slice-status`, board sync) and continue working locally.
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 progress.txt and update the `.build-kit/AGENTS.md` file with those learnings.
@@ -0,0 +1,145 @@
1
+ # Agent Task Instructions
2
+
3
+ You are an autonomous agent reacting to slice status change events on an Eventmodelers board.
4
+
5
+ ## Your Loop
6
+
7
+ 1. Read `AGENT.md` to load accumulated learnings before doing anything else.
8
+ 2. Read `.build-kit/tasks.json`.
9
+ 3. If `tasks.json` is empty or missing, reply with:
10
+ <promise>IDLE</promise>
11
+ and stop.
12
+ 4. Pick the **oldest task** (earliest `createdAt`).
13
+ 5. Execute the task — see the Execution section below.
14
+ 6. After execution, remove that task from the array and write `.build-kit/tasks.json` back.
15
+ 7. Append a progress entry to `progress.txt` (create if missing).
16
+ 8. Update `AGENT.md` with any new reusable learnings discovered this iteration.
17
+ 9. Reply normally so the next iteration can pick up the next task.
18
+
19
+ ## Execution
20
+
21
+ Each task has a single `payload` of type `SliceChangedPayload`:
22
+
23
+ ```
24
+ {
25
+ event: "slice:changed"
26
+ organizationId: string | null
27
+ boardId: string
28
+ sliceId: string ← SLICE_BORDER node UUID
29
+ sliceTitle: string | null
30
+ sliceStatus: string | null ← e.g. "InProgress", "Done", "Blocked"
31
+ timestamp: number
32
+ }
33
+ ```
34
+
35
+ ### Step 1 — Load credentials
36
+
37
+ Run `/connect` to resolve `TOKEN`, `BOARD_ID`, `ORG_ID`, and `BASE_URL` from `.eventmodelers/config.json`.
38
+
39
+ ### Step 2 — Load the slice
40
+
41
+ Run `/load-slice sliceId=<payload.sliceId>` to fetch full slice details (title, status, raw node record).
42
+
43
+ ### Step 3 — Act on the change
44
+
45
+ Inspect the `sliceStatus` in the payload:
46
+
47
+ #### `Planned` — build the slice
48
+
49
+ This is the build trigger. Setting `InProgress` and building are one atomic step:
50
+
51
+ 1. Immediately call `/update-slice-status` to set the slice to `InProgress` on the board.
52
+
53
+ **Claim conflict**: if this call reports the slice is already in `InProgress` (or any status other than `Planned`), another agent already claimed it first — this is expected, not an error. Log it in `progress.txt`, drop this task without building, and continue the loop (the next task will naturally cover the next slice). Do not retry.
54
+
55
+ 2. Read the slice definition from `.build-kit/.slices/<contextSlug>/<sliceFolder>/slice.json` (written by `/load-slice`).
56
+
57
+ 3. Determine the **slice type** from `sliceType` in the slice.json:
58
+ - **`STATE_CHANGE`** → invoke `/build-state-change`
59
+ - **`STATE_VIEW`** → invoke `/build-state-view`
60
+ - **`AUTOMATION`** → not this stack's job (no UI counterpart) — invoke `/request-feedback`
61
+ rather than building it
62
+
63
+ 4. Invoke the matching skill and follow its instructions **completely**. Do NOT implement the slice manually.
64
+
65
+ 5. **Verify against slice.json**: cross-check the implementation — every command field, event field, and specification in slice.json must appear in the code. No invented fields — if it is not in slice.json, it must not be in the code.
66
+
67
+ 6. Run `npm run build` and `npm run lint` (both must pass clean) — plus the slice's own tests only, if any exist.
68
+
69
+ 7. If checks pass, commit all changes with message: `feat: [Slice Name]`.
70
+
71
+ 8. Call `/update-slice-status` to set the slice to `Done` on the board — **unless** the matching
72
+ build skill flagged a missing `apiEndpoint` and already marked the slice `Blocked` (see
73
+ "Escalating Ambiguity" below); in that case, skip this step and leave it `Blocked`.
74
+
75
+ #### `InProgress`
76
+ Another agent is already building this slice. Log it and skip — do not build.
77
+
78
+ #### `Done`
79
+ Summarize what was completed and update `progress.txt`.
80
+
81
+ #### `Blocked`
82
+ Log the blocker in `progress.txt`.
83
+
84
+ #### `Review`
85
+ Fetch slice details and prepare a review summary in `progress.txt`.
86
+
87
+ #### Any other status (`Created`, etc.)
88
+ Load the slice and log the state transition in `progress.txt`. No build action.
89
+
90
+ Use the skills available in `.claude/skills/` to interact with the board.
91
+
92
+ ## Updating tasks.json
93
+
94
+ After completing a task, remove it from the array and write the updated array back to `.build-kit/tasks.json`. If the array is now empty, write `[]`.
95
+
96
+ ## Escalating Ambiguity
97
+
98
+ **If the slice's requirements are genuinely ambiguous, contradictory, or missing a decision you need
99
+ in order to proceed — do not guess, and do not build anyway.** Invoke `/request-feedback` with the
100
+ specific question; it posts the question as a comment on the slice and marks it `Blocked` on the
101
+ board (overriding the `InProgress` set earlier), then stop this iteration without finishing the
102
+ build — reply `<promise>DONE</promise>` as if the iteration's work was to raise the question, not to
103
+ implement the slice. This is an escalation path, not a routine step — read the slice.json and the
104
+ matching build skill's own instructions fully first; most slices are fully specified and need none of
105
+ this.
106
+
107
+ **Exception: a missing `apiEndpoint`** (no backend endpoint/table decided yet) is a partial version of
108
+ this — flag it, but don't fully stop. `build-state-change`/`build-state-view` Step 1 cover the exact
109
+ mechanics: post a comment on the slice and mark it `Blocked` (same as `/request-feedback`), but then
110
+ keep going — build the slice normally against a provisional mock path/table name with meaningful
111
+ sample data. The slice ends this run `Blocked` (step 8 above does not apply for this case — leave it
112
+ `Blocked` instead of setting `Done`), but the code is there, mocked, ready to be pointed at the real
113
+ API once one exists.
114
+
115
+ ## Progress Report Format
116
+
117
+ APPEND to `progress.txt` (never replace):
118
+ ```
119
+ ## [ISO timestamp] — Task [task.id]
120
+
121
+ Slice: [sliceTitle] ([sliceId])
122
+ Status change: [sliceStatus]
123
+
124
+ Action taken:
125
+ - [what was done in response to the slice change]
126
+
127
+ Learnings:
128
+ - [any patterns, gotchas, or reusable knowledge discovered]
129
+ ---
130
+ ```
131
+
132
+ ## Stop Condition
133
+
134
+ If `.build-kit/tasks.json` is empty (`[]`) or does not exist, reply with:
135
+ <promise>IDLE</promise>
136
+
137
+ ## Updating AGENT.md
138
+
139
+ After completing a task, add any **reusable** learnings to `AGENT.md` — patterns, gotchas, API quirks, or skill behaviour that future iterations should know. Only add things that are general and applicable beyond this single task. Do not duplicate what is already there.
140
+
141
+ ## Important
142
+
143
+ - Process **one task per iteration**.
144
+ - Read `AGENT.md` first — it contains patterns from previous iterations.
145
+ - Always start with `/connect` if credentials are not yet loaded.
@@ -0,0 +1,12 @@
1
+ # Supabase project this app authenticates against and issues commands as.
2
+ VITE_SUPABASE_URL=
3
+ VITE_SUPABASE_ANON_KEY=
4
+
5
+ # Base URL of the backend that receives command POSTs (empty for same-origin/relative paths).
6
+ VITE_API_BASE=
7
+
8
+ # Set to "mock" to serve every component's samples/sample-<N>.json instead of hitting
9
+ # Supabase/the backend at all — lets any slice component be tested/previewed in isolation.
10
+ VITE_DATA_MODE=
11
+ # Which numbered sample set is active when VITE_DATA_MODE=mock, e.g. "1", "2".
12
+ VITE_MOCK_SAMPLE=1
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": ["react", "typescript", "oxc"],
4
+ "ignorePatterns": [".build-kit/**"],
5
+ "rules": {
6
+ "react/rules-of-hooks": "error",
7
+ "react/only-export-components": ["warn", { "allowConstantExport": true }]
8
+ }
9
+ }
@@ -0,0 +1,49 @@
1
+ # Project
2
+
3
+ A React (Vite + TypeScript) frontend, built slice-by-slice from an eventmodelers board.
4
+
5
+ ## Stack
6
+
7
+ - [Vite](https://vite.dev) + React 19 + TypeScript
8
+ - [oxlint](https://oxc.rs/docs/guide/usage/linter.html) for linting
9
+ - [Supabase](https://supabase.com) for auth — every command POST is authenticated with the
10
+ current Supabase session's JWT (see `src/lib/api.ts` / `src/lib/supabase.ts`)
11
+
12
+ ## Scripts
13
+
14
+ ```bash
15
+ npm install # install dependencies
16
+ npm run dev # start the dev server
17
+ npm run build # type-check and build for production
18
+ npm run preview # preview the production build
19
+ npm run lint # lint with oxlint
20
+ ```
21
+
22
+ ## Structure
23
+
24
+ - `src/lib/api.ts` / `src/lib/supabase.ts` — the **only** place that knows about base URLs, auth
25
+ headers, and the Supabase client. Slice components never call `fetch` or read the Supabase
26
+ session directly — they call `postCommand(path, body)` and handle only their own request/response
27
+ shape.
28
+ - `src/slices/` — one directory per board slice, generated by the `build-state-change` /
29
+ `build-state-view` skills from `.build-kit/.slices/<context>/<slice>/slice.json`. Do not
30
+ hand-edit slice code without reading the matching `slice.json` first.
31
+ - `.build-kit/` — Ralph's runtime: the agent loop, realtime board subscription, and the
32
+ build skills under `.build-kit/lib/`. See `.build-kit/README.md`.
33
+ - `.claude/skills/` — Claude skills used to build slices (`connect`, `learn-eventmodelers-api`,
34
+ `load-slice`, `build-state-change`, `build-state-view`, `update-slice-status`,
35
+ `request-feedback`) plus `init-style-guide` / `learn-styleguide` for keeping generated UI
36
+ on-brand — run `init-style-guide` once to hand over CSS/design tokens/brand docs.
37
+
38
+ ## Environment
39
+
40
+ Copy `.env.example` to `.env` and fill in:
41
+ - `VITE_SUPABASE_URL` / `VITE_SUPABASE_ANON_KEY` — the Supabase project this app authenticates
42
+ against.
43
+ - `VITE_API_BASE` — base URL of the backend that receives command POSTs (leave empty for
44
+ same-origin/relative paths).
45
+
46
+ This stack is UI-only: it builds **state-change** (command → event) and **state-view**
47
+ (read model) slices. Automations/processors are a backend concern and are handled by
48
+ whatever backend stack is installed alongside this one — see the note in
49
+ `.build-kit/CLAUDE.md`.