@slowcook-ai/cli 0.13.0 → 0.14.0-alpha.2

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/dist/cli.js +9 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/brew/prompts.d.ts +3 -290
  4. package/dist/commands/brew/prompts.d.ts.map +1 -1
  5. package/dist/commands/brew/prompts.js +3 -462
  6. package/dist/commands/brew/prompts.js.map +1 -1
  7. package/dist/commands/extract/index.d.ts +2 -0
  8. package/dist/commands/extract/index.d.ts.map +1 -0
  9. package/dist/commands/extract/index.js +90 -0
  10. package/dist/commands/extract/index.js.map +1 -0
  11. package/dist/commands/init/templates.d.ts.map +1 -1
  12. package/dist/commands/init/templates.js +4 -0
  13. package/dist/commands/init/templates.js.map +1 -1
  14. package/dist/commands/investigate/prompts.d.ts +7 -87
  15. package/dist/commands/investigate/prompts.d.ts.map +1 -1
  16. package/dist/commands/investigate/prompts.js +7 -234
  17. package/dist/commands/investigate/prompts.js.map +1 -1
  18. package/dist/commands/map/emit-tokens.d.ts +53 -0
  19. package/dist/commands/map/emit-tokens.d.ts.map +1 -0
  20. package/dist/commands/map/emit-tokens.js +316 -0
  21. package/dist/commands/map/emit-tokens.js.map +1 -0
  22. package/dist/commands/map/index.d.ts +17 -0
  23. package/dist/commands/map/index.d.ts.map +1 -1
  24. package/dist/commands/map/index.js +72 -5
  25. package/dist/commands/map/index.js.map +1 -1
  26. package/dist/commands/refine/agent.d.ts.map +1 -1
  27. package/dist/commands/refine/agent.js +21 -0
  28. package/dist/commands/refine/agent.js.map +1 -1
  29. package/dist/commands/refine/context.d.ts +11 -0
  30. package/dist/commands/refine/context.d.ts.map +1 -1
  31. package/dist/commands/refine/context.js +45 -0
  32. package/dist/commands/refine/context.js.map +1 -1
  33. package/dist/commands/refine/mock-fixtures.d.ts +39 -0
  34. package/dist/commands/refine/mock-fixtures.d.ts.map +1 -0
  35. package/dist/commands/refine/mock-fixtures.js +86 -0
  36. package/dist/commands/refine/mock-fixtures.js.map +1 -0
  37. package/dist/commands/refine/prompts.d.ts +10 -21
  38. package/dist/commands/refine/prompts.d.ts.map +1 -1
  39. package/dist/commands/refine/prompts.js +10 -376
  40. package/dist/commands/refine/prompts.js.map +1 -1
  41. package/dist/commands/refine/spec-yaml.d.ts +306 -128
  42. package/dist/commands/refine/spec-yaml.d.ts.map +1 -1
  43. package/dist/commands/refine/spec-yaml.js +33 -0
  44. package/dist/commands/refine/spec-yaml.js.map +1 -1
  45. package/dist/commands/sift/prompts.d.ts +3 -111
  46. package/dist/commands/sift/prompts.d.ts.map +1 -1
  47. package/dist/commands/sift/prompts.js +3 -190
  48. package/dist/commands/sift/prompts.js.map +1 -1
  49. package/dist/commands/testgen/prompts.d.ts +3 -13
  50. package/dist/commands/testgen/prompts.d.ts.map +1 -1
  51. package/dist/commands/testgen/prompts.js +3 -384
  52. package/dist/commands/testgen/prompts.js.map +1 -1
  53. package/package.json +5 -5
@@ -1,465 +1,6 @@
1
1
  /**
2
- * Prompts + tool definitions for the brew agent loop.
3
- *
4
- * The agent's one job per turn: make the TARGET red test go green without
5
- * regressing any currently-green test. Slowcook (not the agent) runs the test
6
- * suite between turns and applies the ratchet. The agent's tools are limited
7
- * to reading and writing files, plus one "justify-overflow" tool for when it
8
- * needs to break the graduality cap.
2
+ * Re-export shim see investigate/prompts.ts for the rationale.
3
+ * Source of truth: `@slowcook-ai/llm-anthropic/prompts/brew`.
9
4
  */
10
- export const BREW_SYSTEM = `You are the brewing implementer agent for slowcook — a rigorous TDD-first coding harness.
11
-
12
- ## Your task per turn
13
-
14
- You will be told one specific failing test (the **target**). Your job: make a code change that flips the target from red to green, WITHOUT breaking any currently-green test.
15
-
16
- After your turn ends, slowcook runs the test suite and applies a mechanical ratchet:
17
-
18
- - If any previously-green test now fails → your changes are **reverted entirely**.
19
- - If the target went green (and no regressions) → your changes become a **checkpoint**.
20
- - If nothing changed green/red → your changes are **reverted** (no progress = no commit).
21
-
22
- This means: **you only keep changes that advance the green set.** Make real progress per turn, not exploratory edits.
23
-
24
- ## Tools
25
-
26
- - **find_handler({ method, path })** — **call this FIRST for every \`api_contract\` entry in the spec.** Returns the exact handler file + function the brewing agent should edit (e.g. \`POST /api/rewos\` → \`src/app/api/rewos/route.ts\` :: \`POST\`). Saves the exploratory iteration where you'd otherwise grep for the route.
27
- - **outline_file(path)** — **prefer this over read_file for initial exploration.** Returns a compact outline (imports, top-level exports, signatures with line numbers) — ~200 tokens. Use this to decide whether a file is relevant before you read it fully.
28
- - **read_file(path)** — read a file's full contents. Only call this when you need to see inside a specific function body that outline_file flagged. Reading a file you don't need is the single biggest driver of wasted budget.
29
- - **list_directory(path)** — see what's in a directory. Useful when outline_file + find_handler don't give enough.
30
- - **write_file(path, contents)** — create or fully replace a file. Always read or outline first, then write the complete updated contents.
31
- - **justify_diff_overflow({ reason_category, affected_scope, narrative, proposed_substories_if_split? })** — call ONLY if your intended change must exceed the graduality soft-cap (200 lines across ≤5 files). Explain why.
32
-
33
- You do NOT run tests. Slowcook runs them after your turn and tells you the result in the next turn's prompt.
34
-
35
- ## Exploration strategy (cheap first, expensive last)
36
-
37
- **Start every turn by reading \`.brewing/code-map.target.md\`** — slowcook
38
- regenerates this **per-iter** with just the code-map entries scoped to
39
- the current target test (co-located src/ dir + identifier names mentioned
40
- in the test). It's typically 5-50 entries with full JSDoc + signatures,
41
- not the project-wide 200+. Read it first; cheaper attention than the full
42
- map and almost always sufficient for the iteration's edits.
43
-
44
- Fall back to the **full map** at \`.brewing/code-map.md\` (or the JSON
45
- sibling \`.brewing/code-map.json\`) only when the target slice is missing
46
- something you need — typically a cross-cutting helper / type referenced
47
- indirectly. The full map is the project's self-updating
48
- Swagger-for-everything; \`code-map.target.md\` is your default lens.
49
-
50
- Then, in order:
51
-
52
- 1. **Target slice first** — \`read_file('.brewing/code-map.target.md')\`.
53
- Skim to see what's relevant to *this* iteration.
54
- 2. For each api_contract entry relevant to the target test, **find_handler**
55
- to confirm the exact file + function (the code map also has this, but
56
- find_handler is a one-call shortcut).
57
- 3. **outline_file** on each file the slice / find_handler points to,
58
- plus obvious neighbours (utils, types, helpers the spec references).
59
- 4. **read_file** only the specific files + functions the outline flagged
60
- as needing changes.
61
- 5. **write_file** the minimum change.
62
- 6. **If the target slice doesn't show what you need** — read
63
- \`.brewing/code-map.md\` (full) for cross-cutting context. Don't burn
64
- exploration on this for routine edits; it's a fallback.
65
-
66
- A human doesn't read every file in a package to fix one test; neither should you.
67
-
68
- ## Mandatory pre-write discovery (0.12.0+)
69
-
70
- Before writing ANY new exported symbol — function, component, type,
71
- class, route handler — you MUST verify nothing similar already exists.
72
- This prevents a recurring failure mode: brew duplicates a helper that
73
- already lives elsewhere in the codebase, the duplicate passes the
74
- target test, and the duplication ships unnoticed. Same problem at scale
75
- in brownfield projects.
76
-
77
- **Required tool sequence:**
78
-
79
- 1. **\`find_references\`** on the symbol name you're about to introduce
80
- (or the most-likely existing equivalent). Examples:
81
- - About to write \`getProfileByHandle\`? Call \`find_references({symbol: "getProfileByHandle"})\`
82
- AND \`find_references({symbol: "getProfile"})\` (broader concept).
83
- - About to write a \`BookmarkItem\` component? Call
84
- \`find_references({symbol: "BookmarkItem"})\` AND consider similar
85
- concept names.
86
- 2. If \`find_references\` returns matches with kind=\`definition\`, READ
87
- that file's outline. Decide:
88
- - Can I extend the existing symbol with an extra arg / option?
89
- **YES → extend it. Don't create a parallel.**
90
- - Is the existing symbol unsuitable for this case (genuinely
91
- orthogonal use)? **OK to add a new one. State the reason in your
92
- turn rationale so the reviewer can audit the choice.**
93
- 3. **\`grep\`** is acceptable when you're searching for a concept rather
94
- than an exact identifier (e.g., "where do we do RLS?"). Always
95
- refine to specific symbols via find_references after.
96
-
97
- **Rule of thumb:** if the cumulative diff so far has duplication you'd
98
- consolidate, do it on this iteration's edit while you're already
99
- touching the file. Don't open a separate refactor turn — write
100
- cleaner code on the green path.
101
-
102
- The reviewer audits your discovery work via the iteration log's
103
- \`discovery:\` field (slowcook 0.12.0+) and the rationale you write at
104
- turn end. Silent skips of the discovery requirement turn into
105
- "why did you write a parallel function?" PR comments later.
106
-
107
- ## When you're stuck (same target, 2+ iterations without progress)
108
-
109
- **Check the \`Why the target failed last run\` section in every turn prompt FIRST.** The test's \`Received:\` / error message tells you what the assertion actually saw — that's ground truth. Don't spend iterations re-reading your own code looking for a bug you missed when the failure message is right there.
110
-
111
- **Specific anti-pattern to avoid:** "the code LOOKS like it shouldn't render X, but the test says X is in the document" — do NOT interpret this as "there must be a subtle JSX evaluation bug." It almost always means another element matches the same query selector. Read the \`Received:\` payload to see which element the selector hit.
112
-
113
- **If after reading the failure message you genuinely can't tell what's in the DOM:** insert a \`console.log(screen.debug())\` in the test file OR a distinctive \`data-testid="probe-iter-N"\` attribute in the component as a **one-iteration diagnostic**. The ratchet will revert your change (it's not a green gain), and on the NEXT iteration's prompt you'll see the DOM output in the failure message. Diagnostic probing is cheap; analysis paralysis is expensive.
114
-
115
- **If you still can't reconcile after 3 iterations on the same target — halt voluntarily.** End your rationale with a new line containing exactly:
116
-
117
- \`\`\`
118
- Considering halting voluntarily
119
- \`\`\`
120
-
121
- Followed by a concrete description of the specific mismatch you can't resolve (e.g. "test queries getByRole('alert'); my component has one \`role=\"alert\"\` element gated on \`!handle_confirmed\`; I can't see what's in the rendered DOM when handle_confirmed=true."). Slowcook will halt immediately and surface your description to the operator. This saves ~15 iterations of silent spending; the operator picks up the diagnostic you handed them and either hand-patches the blocker or clarifies the spec.
122
-
123
- ## Schema-assertion tests (target file lives under \`tests/schema/\`)
124
-
125
- When the target test is a schema assertion (path \`tests/schema/story-N.test.ts\`), it reads \`supabase/migrations/*.sql\` and asserts specific columns appear. Constraints:
126
-
127
- - **Write a new migration file** — never edit an existing one. Pick the next unused number (\`NNNNN_\` prefix, zero-padded to match neighbours): \`list_directory supabase/migrations/\`, find the max, add 1.
128
- - **Minimal DDL** — just \`ALTER TABLE <t> ADD COLUMN <c> <type> ...;\`. If the test asserts multiple columns, one migration file can add several in a single \`ALTER TABLE\` with comma-separated clauses, or multiple statements in the same file.
129
- - **Spec invariants drive the TYPE / constraints** (e.g. "boolean not null default false", "timestamptz nullable"). The schema-assertion test only checks NAME, not type — but the invariants must still be honoured by the migration you write.
130
- - **Backfill if invariants require it** — if an invariant says "...and backfills existing rows to false", write an \`UPDATE\` in the same migration, or use \`DEFAULT\` on \`ADD COLUMN\` to cover both new + existing rows in one shot.
131
- - **Never touch \`supabase/migrations/00001_*\`** through whatever number exists — those are historical. Append-only is the convention.
132
-
133
- ## Styling presence (target file ends in \`-styling.test.ts\` under \`tests/integration/\`)
134
-
135
- When the target test is a styling presence assertion, it reads the component source file and checks for:
136
-
137
- - At least 4 \`className=\` occurrences (raw unstyled HTML has 0-1; a real styled component has many).
138
- - At least one class from the project's design-token family (\`bg-\`, \`text-\`, \`border-\`, \`rounded\`, \`px-\`, \`py-\`, \`space-y-\`, \`flex\`, \`grid\`, \`mt-\`, \`mb-\`, \`gap-\`).
139
-
140
- Close it by adding Tailwind classes to the component file named in the test. Don't hand-pick arbitrary classes — read \`.brewing/context.md\`'s "Visual conventions" section (design tokens + reusable patterns) and use those. If context.md is silent on styling, imitate neighbouring files in \`src/components/\` / \`src/app/(main)/\`. The test doesn't care WHICH classes — it cares that you made the effort.
141
-
142
- ## Page-link assertion (target file ends in \`-page.test.ts\` under \`tests/integration/\`)
143
-
144
- When the target test is a page-link assertion, it reads a Next.js page file and asserts the page IMPORTS + MOUNTS a named component. Fix by editing the page:
145
-
146
- - **Add the import** from the specifier the test names (\`@/components/...\`).
147
- - **Render the component** in the page's JSX (\`<ComponentName .../>\` or \`<ComponentName>...children...</ComponentName>\`).
148
- - **If the page is a server component fetching data**, pass the fetched data to the component as a prop. Don't convert the page to a client component to avoid the fetch — that breaks the rest of the page.
149
- - **Existing layout stays** — don't refactor unrelated sections. Wedge the component in alongside what's already there (a new \`<section>\` block is typical).
150
-
151
- ## UI component tests (tier-1 UI, target file ends in \`.test.tsx\`)
152
-
153
- When the target test is a UI component test (file path ends in \`-ui.test.tsx\`), you're editing React/TSX — typically \`src/components/**/*.tsx\` or client pages at \`src/app/**/page.tsx\`. Constraints:
154
-
155
- - **Import path is the single source of truth** — the test file imports the component from some path; create / edit the file at that path. Don't rename.
156
- - **Stubs you find with a \`@slowcook-stub\` marker on line 1 are yours to replace.** Testgen emits these so tests can collect; brewing's job is to replace the body with real code.
157
- - **Helpers under \`tests/helpers/\` (e.g. \`renderWithProviders\`, \`mockFetch\`, \`realShapedFetch\`, \`axe\`) are fixed test infra** — never edit them. If a test imports from there, trust the import.
158
- - **Mocked \`fetch\` via \`vi.stubGlobal\`** means your component calls \`fetch("/api/…")\` like normal; the mock intercepts. Don't add branching for test-mode — call fetch cleanly in production shape.
159
- - **Accessibility asserts** (the mandatory axe test) care about semantic HTML — use \`<main>\`, \`<nav>\`, \`<button>\`, \`<label htmlFor>\`, proper heading hierarchy, \`aria-*\` attributes where needed. A non-accessible component fails the axe test.
160
- - **\`"use client"\` directive** at the top of the file when the component uses hooks (useState, useEffect, onClick handlers, etc.). Next.js App Router defaults to server components; tier-1 UI tests need client components.
161
- - **Props types** come from the spec + the test file's usage. If the test passes \`<Form profile={{ handle: "alice" }} />\`, the component must accept a \`profile\` prop of that shape.
162
- - **Match the project's visual conventions.** Tier-1 tests query by role/label/text and don't assert styling — but the user STILL has to look at what you ship. A component with zero \`className\` attributes is incomplete even if every test passes. Read \`.brewing/context.md\` for the project's design-token names + reusable class patterns (buttons, inputs, alerts, labels) before writing the component body. If context.md is silent on styling, imitate neighbouring files in \`src/components/\` / \`src/app/(main)/\` — match their spacing, border, focus-ring, and colour-token choices.
163
-
164
- ## Constraints
165
-
166
- - **One target per turn.** The prompt names ONE failing test. Work on that one. Incidental green flips on other tests are fine but not the goal.
167
- - **Minimum diff.** Smallest change that flips the target. Don't refactor. Don't anticipate future tests.
168
- - **Stay within \`allowed_paths\` from the spec.** If the spec says you may only touch \`src/app/api/reactions/\`, do not edit anything outside.
169
- - **Never modify frozen paths.** \`tests/\`, \`.brewing/\`, \`vitest.config.*\`, \`package.json\` scripts — read them, never write them. Slowcook will mechanically reject any such diff.
170
- - **Never use \`test.skip\` / \`.todo\` / \`.only\` / environment branches like \`if (NODE_ENV === 'test')\`.** Slowcook's static scan catches these and will reject the turn.
171
-
172
- ## Output conventions
173
-
174
- - Use tools to make changes. Do not paste code in your text reply — slowcook only applies changes that come through \`write_file\`.
175
- - At the end of your turn, include a one-paragraph **rationale** explaining what you changed and why. Slowcook uses this for halt reports if brewing stalls.
176
- - If you need more information (read files, list directories), use the read tools first, THEN edit. Don't guess at file contents.
177
-
178
- ## Failure recovery guidance
179
-
180
- - If you receive a prompt showing your previous turn was **reverted**, read the failure reason carefully. Typical causes:
181
- 1. **Regression** — one of your edits broke a currently-green test. Look at which test; your change touched its dependency.
182
- 2. **No progress** — your edits didn't change any test outcome. The code path you changed may not be exercised by the target test.
183
- 3. **Frozen-path violation** — you edited a file you shouldn't have. Don't.
184
- - On no-progress reverts, consider whether the target test is reachable from the code path you're editing, or whether it's testing a layer your code doesn't touch (e.g., the test calls \`fetch('http://localhost:3000')\` but no server is running).
185
- `;
186
- export const BREW_TOOLS = [
187
- {
188
- name: "find_handler",
189
- description: "Resolve an API spec entry (method + path) to its concrete handler file + function. Use this FIRST for every api_contract entry in the spec — it replaces an exploratory read/list cycle. Today supports Next.js App Router (detected by `src/app/`); other frameworks return `framework: 'unknown'`. Returns JSON with { framework, file, function, exists, note? }.",
190
- input_schema: {
191
- type: "object",
192
- properties: {
193
- method: {
194
- type: "string",
195
- description: "HTTP method, e.g. 'POST', 'GET', 'DELETE'.",
196
- },
197
- path: {
198
- type: "string",
199
- description: "URL path, with params as `:id` or `{id}` — both are normalised (e.g. '/api/rewos/:rewo_id/reports' → 'src/app/api/rewos/[rewo_id]/reports/route.ts').",
200
- },
201
- },
202
- required: ["method", "path"],
203
- },
204
- },
205
- {
206
- name: "find_references",
207
- description: "0.12.0+ symbol-aware retrieval. Return every place a named symbol is referenced in src/ (definition + imports + usages). MANDATORY before writing any new exported function/component/type — call this first to verify nothing similar already exists. AST-aware: ignores comments and string literals. Returns lines like `kind | file:line:col | context_line`. `kind` ∈ {definition, reference, import, implements, extends}.",
208
- input_schema: {
209
- type: "object",
210
- properties: {
211
- symbol: {
212
- type: "string",
213
- description: "The exact identifier name to search for (case-sensitive). E.g. 'getProfileByHandle', 'BookmarksPage', 'ReactionItem'.",
214
- },
215
- exclude_definitions: {
216
- type: "boolean",
217
- description: "If true, skip the symbol's own declaration. Useful when you want to know 'is anyone calling this' without seeing the definition itself.",
218
- },
219
- },
220
- required: ["symbol"],
221
- },
222
- },
223
- {
224
- name: "find_implementations",
225
- description: "0.12.0+ symbol-aware retrieval. Find every class that `implements <interface>` or `extends <class>`, plus every interface that extends another interface, by name. Returns the same shape as find_references, with kind ∈ {implements, extends}. Use when you're about to write a new implementor and want to see how others did it.",
226
- input_schema: {
227
- type: "object",
228
- properties: {
229
- interface_or_base: {
230
- type: "string",
231
- description: "Name of the interface or base class to find implementations/extensions of.",
232
- },
233
- },
234
- required: ["interface_or_base"],
235
- },
236
- },
237
- {
238
- name: "find_definition",
239
- description: "0.12.0+ symbol-aware retrieval. Jump to the canonical declaration site of a symbol. Returns at most one result (the first declaration found). Faster than find_references when you only need the definition; both use the same AST scan but find_definition stops at the first match.",
240
- input_schema: {
241
- type: "object",
242
- properties: {
243
- symbol: {
244
- type: "string",
245
- description: "The identifier name whose declaration site you want.",
246
- },
247
- },
248
- required: ["symbol"],
249
- },
250
- },
251
- {
252
- name: "outline_file",
253
- description: "Return a compact outline of a TypeScript/JavaScript file: imports, top-level exports, signatures with line numbers. ~200 tokens. PREFER this over read_file for initial exploration — only call read_file when the outline tells you a specific function body needs to be inspected.",
254
- input_schema: {
255
- type: "object",
256
- properties: {
257
- path: {
258
- type: "string",
259
- description: "Repo-relative path (e.g., 'src/app/api/reactions/route.ts').",
260
- },
261
- },
262
- required: ["path"],
263
- },
264
- },
265
- {
266
- name: "read_file",
267
- description: "Read a file's full contents. Call this AFTER outline_file tells you a specific file / function body needs to be inspected — reading files you don't need is the single biggest driver of wasted budget. Returns the full file (up to 20k chars).",
268
- input_schema: {
269
- type: "object",
270
- properties: {
271
- path: { type: "string", description: "Repo-relative path (e.g., 'src/app/api/reactions/route.ts')" },
272
- },
273
- required: ["path"],
274
- },
275
- },
276
- {
277
- name: "list_directory",
278
- description: "List entries in a directory. Returns an array of { name, type: 'file'|'dir' }. Useful for exploring code structure.",
279
- input_schema: {
280
- type: "object",
281
- properties: {
282
- path: { type: "string", description: "Repo-relative directory path (e.g., 'src/app/api/reactions/')" },
283
- },
284
- required: ["path"],
285
- },
286
- },
287
- {
288
- name: "write_file",
289
- description: "Create or fully overwrite a file. Parent directories are created as needed. Returns the number of lines written.",
290
- input_schema: {
291
- type: "object",
292
- properties: {
293
- path: { type: "string", description: "Repo-relative path to write." },
294
- contents: { type: "string", description: "Full file contents. This replaces whatever was there before." },
295
- },
296
- required: ["path", "contents"],
297
- },
298
- },
299
- {
300
- name: "justify_diff_overflow",
301
- description: "Call ONLY when your proposed change must exceed the graduality soft-cap (200 lines / 5 files). Without this call, an oversized diff is rejected by slowcook.",
302
- input_schema: {
303
- type: "object",
304
- properties: {
305
- reason_category: {
306
- type: "string",
307
- enum: ["new_module", "protocol_change", "cross_cutting", "refactor_needed", "other"],
308
- },
309
- affected_scope: {
310
- type: "array",
311
- items: { type: "string" },
312
- description: "Paths or directories affected by the overflow.",
313
- },
314
- narrative: {
315
- type: "string",
316
- description: "Concrete one-paragraph explanation of why the smaller diff isn't viable.",
317
- },
318
- proposed_substories_if_split: {
319
- type: "array",
320
- items: { type: "string" },
321
- description: "If this story should be split, list the sub-stories here.",
322
- },
323
- },
324
- required: ["reason_category", "affected_scope", "narrative"],
325
- },
326
- },
327
- ];
328
- /**
329
- * Render a single-turn prompt for the agent. Keeps history short (we re-supply
330
- * the same system prompt via prompt caching, then hand a fresh turn-state each
331
- * iteration; agent doesn't carry over its own previous turns because slowcook
332
- * may have reverted them).
333
- */
334
- export function turnPrompt(args) {
335
- // Backwards-compatible single-string form: prefix + body. Callers
336
- // that want prompt caching should use `turnPromptParts` (0.11.15+)
337
- // and emit two content blocks with cache_control on the prefix.
338
- const parts = turnPromptParts(args);
339
- return `${parts.cachedPrefix}\n\n${parts.dynamicBody}`;
340
- }
341
- /**
342
- * 0.11.15+ — split the per-iter prompt into a CACHEABLE prefix
343
- * (constant across iterations within a brew run: spec + allowed paths)
344
- * and a DYNAMIC body (iteration counter, target test, failure messages,
345
- * lint issues, prior attempts).
346
- *
347
- * The Anthropic API's prompt cache requires the cached content to be
348
- * a contiguous prefix; before this split, spec+allowed_paths sat in
349
- * the middle of the user message and were never cache-eligible. Moving
350
- * them to the front lets ~30-50% of the input tokens be reused across
351
- * iterations within the 5-minute ephemeral cache TTL.
352
- *
353
- * The instruction order doesn't change agent behaviour — having spec
354
- * context first is at least as good as having it later. The dynamic
355
- * body still ends with the iteration's specific request.
356
- */
357
- export function turnPromptParts(args) {
358
- // === CACHEABLE PREFIX === (constant across iterations in a single
359
- // brew run: spec body + allowed paths + prior brew history)
360
- const prefix = [];
361
- prefix.push("### Spec (the contract)");
362
- prefix.push("```yaml");
363
- prefix.push(args.spec_yaml.trim());
364
- prefix.push("```");
365
- prefix.push("");
366
- if (args.allowed_paths.length > 0) {
367
- prefix.push("### Allowed paths for this story");
368
- for (const p of args.allowed_paths)
369
- prefix.push(`- \`${p}\``);
370
- prefix.push("");
371
- }
372
- // 0.12.0+ — prior brew history. Listed here in the cached prefix
373
- // because the data doesn't change per iteration. Empty when the
374
- // current brew doesn't overlap with prior brews.
375
- if (args.prior_context_block && args.prior_context_block.trim().length > 0) {
376
- prefix.push(args.prior_context_block.trim());
377
- prefix.push("");
378
- }
379
- // 0.12.12+ (Phase 2C) — pattern index. Same caching rationale as
380
- // prior_context_block: per-brew constant, the body of each pattern
381
- // is fetched on-demand by the agent via read_file when relevant.
382
- if (args.pattern_index_block && args.pattern_index_block.trim().length > 0) {
383
- prefix.push(args.pattern_index_block.trim());
384
- prefix.push("");
385
- }
386
- const cachedPrefix = prefix.join("\n");
387
- // === DYNAMIC BODY === (varies per iteration)
388
- const sections = [];
389
- sections.push(`## Brew iteration ${args.iteration} of ${args.max_iterations}`);
390
- sections.push(`**Budget:** $${args.budget_spent_usd.toFixed(2)} spent of $${args.budget_cap_usd.toFixed(2)} cap.`);
391
- sections.push("");
392
- sections.push("### Target test (flip this one from red to green)");
393
- sections.push("```");
394
- sections.push(args.target_test_id);
395
- sections.push(` (in ${args.target_test_file})`);
396
- sections.push("```");
397
- sections.push("");
398
- // Fix 1 (0.7.14): the failure message is the single highest-leverage
399
- // piece of data for avoiding analysis paralysis. Vitest's output includes
400
- // the `Received:` payload (e.g., the actual DOM snippet for UI tests) —
401
- // without this the agent reasons about abstract code instead of
402
- // observed reality.
403
- if (args.target_failure_message) {
404
- sections.push("### Why the target failed last run");
405
- sections.push("```");
406
- sections.push(args.target_failure_message.trim());
407
- sections.push("```");
408
- sections.push("");
409
- sections.push("Read the `Received:` / error message CAREFULLY before inspecting code. The test's verdict is ground truth; your mental model of the code is not.");
410
- sections.push("");
411
- }
412
- if (args.other_failure_messages && args.other_failure_messages.length > 0) {
413
- sections.push("<details><summary>Other red tests' failure messages (peripheral vision)</summary>");
414
- sections.push("");
415
- for (const f of args.other_failure_messages.slice(0, 5)) {
416
- sections.push(`**\`${f.test_id}\`:**`);
417
- sections.push("```");
418
- sections.push(f.message.slice(0, 400));
419
- sections.push("```");
420
- sections.push("");
421
- }
422
- if (args.other_failure_messages.length > 5) {
423
- sections.push(`_+ ${args.other_failure_messages.length - 5} more red tests._`);
424
- }
425
- sections.push("</details>");
426
- sections.push("");
427
- }
428
- sections.push(`### Test state going into this turn: ${args.currently_green.length} green / ${args.currently_red.length} red`);
429
- sections.push("");
430
- // 0.11.13+ — lint + typecheck issues from prior iter's edits.
431
- // These are reds at the static-analysis level and must be fixed
432
- // alongside the test target. Hard signal: the agent can't satisfy
433
- // an eslint or tsc error by rewriting prose.
434
- if (args.lint_issues && args.lint_issues.trim().length > 0) {
435
- sections.push(args.lint_issues.trim());
436
- sections.push("");
437
- sections.push("Treat the lint/typecheck errors above as additional reds: fix them in the same edit that flips the target test, or fix them first if they block compilation.");
438
- sections.push("");
439
- }
440
- if (args.currently_green.length > 0) {
441
- sections.push("<details><summary>Currently green (keep them green!)</summary>");
442
- sections.push("");
443
- for (const t of args.currently_green.slice(0, 30))
444
- sections.push(`- \`${t}\``);
445
- if (args.currently_green.length > 30) {
446
- sections.push(`- … (${args.currently_green.length - 30} more)`);
447
- }
448
- sections.push("</details>");
449
- sections.push("");
450
- }
451
- if (args.previous_attempts && args.previous_attempts.length > 0) {
452
- sections.push("### Your previous attempts on this target");
453
- for (const a of args.previous_attempts.slice(-3)) {
454
- sections.push(`- **iter ${a.iteration}: ${a.outcome}** — ${a.note}`);
455
- if (a.files_touched.length > 0) {
456
- sections.push(` files: ${a.files_touched.map((f) => `\`${f}\``).join(", ")}`);
457
- }
458
- }
459
- sections.push("");
460
- }
461
- sections.push("### Your turn");
462
- sections.push("Use the tools to inspect the code, then write the minimum change that flips the target test. End with a one-paragraph rationale of what you changed and why.");
463
- return { cachedPrefix, dynamicBody: sections.join("\n") };
464
- }
5
+ export { BREW_SYSTEM, BREW_TOOLS, turnPrompt, turnPromptParts, } from "@slowcook-ai/llm-anthropic";
465
6
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/brew/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/brew/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function extract(argv: string[], _cliVersion: string): Promise<void>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/extract/index.ts"],"names":[],"mappings":"AA2FA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhF"}
@@ -0,0 +1,90 @@
1
+ import { emitSchemaDiagram, emitTokensCatalog } from "../map/index.js";
2
+ function parseArgs(argv) {
3
+ const args = {
4
+ repoRoot: process.cwd(),
5
+ schema: false,
6
+ tokens: false,
7
+ };
8
+ let any = false;
9
+ for (let i = 0; i < argv.length; i++) {
10
+ const a = argv[i];
11
+ const next = argv[i + 1];
12
+ if (a === "--cwd" && next) {
13
+ args.repoRoot = next;
14
+ i++;
15
+ }
16
+ else if (a === "--schema") {
17
+ args.schema = true;
18
+ any = true;
19
+ }
20
+ else if (a === "--tokens") {
21
+ args.tokens = true;
22
+ any = true;
23
+ }
24
+ else if (a === "--help" || a === "-h") {
25
+ printHelp();
26
+ process.exit(0);
27
+ }
28
+ else {
29
+ console.error(`Unknown flag: ${a}`);
30
+ printHelp();
31
+ process.exit(64);
32
+ }
33
+ }
34
+ // Default = extract everything when no specific flag is passed.
35
+ if (!any) {
36
+ args.schema = true;
37
+ args.tokens = true;
38
+ }
39
+ return args;
40
+ }
41
+ function printHelp() {
42
+ console.log(`
43
+ slowcook extract — brownfield project-awareness extracts
44
+
45
+ Walks the consumer's existing code/config and writes refine-readable
46
+ context blocks to .brewing/diagrams/. Designed to run BEFORE refine /
47
+ investigate so their proposals align with the project's existing
48
+ schema + design tokens instead of inventing.
49
+
50
+ Usage:
51
+ slowcook extract [--schema] [--tokens] [--cwd <path>]
52
+
53
+ No flag = extract everything (currently --schema + --tokens).
54
+ Outputs are gitignored; regenerate per refine run.
55
+
56
+ Targets:
57
+ --schema .brewing/diagrams/schema.mmd
58
+ Mermaid erDiagram from supabase/migrations/*.sql.
59
+ Skipped silently when no migrations directory exists.
60
+ --tokens .brewing/diagrams/tokens.md
61
+ Design-token catalog from :root + @theme blocks in
62
+ **/*.css (skipping node_modules / .next / build dirs).
63
+ Skipped silently when no .css files / no tokens are found.
64
+
65
+ This command does NOT run the ts-morph code-map scan; for that,
66
+ use \`slowcook map generate\`.
67
+ `);
68
+ }
69
+ export async function extract(argv, _cliVersion) {
70
+ const args = parseArgs(argv);
71
+ if (args.schema) {
72
+ const r = emitSchemaDiagram(args.repoRoot);
73
+ if (r.written) {
74
+ console.log(`Wrote .brewing/diagrams/schema.mmd (${r.entityCount} entities, ${r.migrationsCount} migrations parsed).`);
75
+ }
76
+ else {
77
+ console.log(`Skipped schema extract: ${r.skippedReason}`);
78
+ }
79
+ }
80
+ if (args.tokens) {
81
+ const r = emitTokensCatalog(args.repoRoot);
82
+ if (r.written) {
83
+ console.log(`Wrote .brewing/diagrams/tokens.md (${r.lightCount} light, ${r.darkCount} dark, ${r.themeCount} @theme; ${r.filesScanned} css file(s) scanned).`);
84
+ }
85
+ else {
86
+ console.log(`Skipped tokens extract: ${r.skippedReason}`);
87
+ }
88
+ }
89
+ }
90
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/extract/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/init/templates.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,UAAU,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,kCAAkC,CAAC;AAEzE,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEjE;AAaD,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,gCAAgC,0CAA0C,CAAC;AACxF,eAAO,MAAM,8BAA8B,wCAAwC,CAAC;AAMpF,eAAO,MAAM,+BAA+B,2CAA2C,CAAC;AACxF,eAAO,MAAM,6BAA6B,yCAAyC,CAAC;AAEpF,wBAAgB,eAAe,IAAI,MAAM,CAoCxC;AAGD,wBAAgB,iBAAiB,IAAI,MAAM,CAmD1C;AAED,wBAAgB,aAAa,IAAI,MAAM,CA0CtC;AAGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAehE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAQjE;AAED,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,IAAI,MAAM,CA2CtC;AAED;;;;;;GAMG;AACH;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAsDvC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAYzC"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/init/templates.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,UAAU,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,kCAAkC,CAAC;AAEzE,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEjE;AAaD,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,gCAAgC,0CAA0C,CAAC;AACxF,eAAO,MAAM,8BAA8B,wCAAwC,CAAC;AAMpF,eAAO,MAAM,+BAA+B,2CAA2C,CAAC;AACxF,eAAO,MAAM,6BAA6B,yCAAyC,CAAC;AAEpF,wBAAgB,eAAe,IAAI,MAAM,CAoCxC;AAGD,wBAAgB,iBAAiB,IAAI,MAAM,CAmD1C;AAED,wBAAgB,aAAa,IAAI,MAAM,CA0CtC;AAGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAehE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAQjE;AAED,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,IAAI,MAAM,CA2CtC;AAED;;;;;;GAMG;AACH;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAsDvC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC"}
@@ -320,6 +320,10 @@ export function gitignoreSection() {
320
320
  .brewing/code-map.json
321
321
  .brewing/code-map.md
322
322
  .brewing/code-map.target.md
323
+ # 0.13.5+ — brownfield extracts (schema.mmd, tokens.md). Same
324
+ # rationale: regenerated each refine/investigate workflow run via
325
+ # \`slowcook extract\`. Live as derived state, not in source control.
326
+ .brewing/diagrams/
323
327
  ${SLOWCOOK_GITIGNORE_MARKER_END}
324
328
  `;
325
329
  }
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/commands/init/templates.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sDAAsD;AAEtD,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,+BAA+B,CAAC;AAEzE,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACvD,OAAO,UAAU,GAAG,IAAI,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG;;;0HAGiG,CAAC;AAS3H,MAAM,CAAC,MAAM,gCAAgC,GAAG,uCAAuC,CAAC;AACxF,MAAM,CAAC,MAAM,8BAA8B,GAAG,qCAAqC,CAAC;AAEpF,sEAAsE;AACtE,oEAAoE;AACpE,mEAAmE;AACnE,0CAA0C;AAC1C,MAAM,CAAC,MAAM,+BAA+B,GAAG,wCAAwC,CAAC;AACxF,MAAM,CAAC,MAAM,6BAA6B,GAAG,sCAAsC,CAAC;AAEpF,MAAM,UAAU,eAAe;IAC7B,OAAO,CACL,IAAI,CAAC,SAAS,CACZ;QACE,OAAO,EAAE,4BAA4B;QACrC,IAAI,EACF,qFAAqF;YACrF,6FAA6F;YAC7F,iEAAiE;QACnE,WAAW,EAAE;YACX,QAAQ;YACR,iBAAiB;YACjB,gBAAgB;YAChB,qBAAqB;SACtB;QACD,KAAK,EAAE;YACL,kBAAkB;YAClB,mBAAmB;YACnB,kBAAkB;YAClB,4BAA4B;YAC5B,qBAAqB;YACrB,qBAAqB;YACrB,gCAAgC;YAChC,4CAA4C;YAC5C,wCAAwC;SACzC;QACD,OAAO,EAAE;YACP,cAAc,EAAE;gBACd,gBAAgB,EAAE,CAAC,cAAc,EAAE,oBAAoB,CAAC;aACzD;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;AACJ,CAAC;AAGD,MAAM,UAAU,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCR,CAAC;AACF,CAAC;AAGD,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO,GAAG,gCAAgC;;;;kCAIV,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;8CACA,MAAM,CAAC,KAAK;8CACZ,MAAM,CAAC,KAAK;8CACZ,MAAM,CAAC,KAAK;8CACZ,MAAM,CAAC,KAAK;EACxD,8BAA8B;CAC/B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,qEAAqE;IACrE,OAAO;;;;;EAKP,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCR,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,GAAG,+BAA+B;;;;;;;;;EASzC,6BAA6B;CAC9B,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/commands/init/templates.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sDAAsD;AAEtD,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,+BAA+B,CAAC;AAEzE,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACvD,OAAO,UAAU,GAAG,IAAI,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG;;;0HAGiG,CAAC;AAS3H,MAAM,CAAC,MAAM,gCAAgC,GAAG,uCAAuC,CAAC;AACxF,MAAM,CAAC,MAAM,8BAA8B,GAAG,qCAAqC,CAAC;AAEpF,sEAAsE;AACtE,oEAAoE;AACpE,mEAAmE;AACnE,0CAA0C;AAC1C,MAAM,CAAC,MAAM,+BAA+B,GAAG,wCAAwC,CAAC;AACxF,MAAM,CAAC,MAAM,6BAA6B,GAAG,sCAAsC,CAAC;AAEpF,MAAM,UAAU,eAAe;IAC7B,OAAO,CACL,IAAI,CAAC,SAAS,CACZ;QACE,OAAO,EAAE,4BAA4B;QACrC,IAAI,EACF,qFAAqF;YACrF,6FAA6F;YAC7F,iEAAiE;QACnE,WAAW,EAAE;YACX,QAAQ;YACR,iBAAiB;YACjB,gBAAgB;YAChB,qBAAqB;SACtB;QACD,KAAK,EAAE;YACL,kBAAkB;YAClB,mBAAmB;YACnB,kBAAkB;YAClB,4BAA4B;YAC5B,qBAAqB;YACrB,qBAAqB;YACrB,gCAAgC;YAChC,4CAA4C;YAC5C,wCAAwC;SACzC;QACD,OAAO,EAAE;YACP,cAAc,EAAE;gBACd,gBAAgB,EAAE,CAAC,cAAc,EAAE,oBAAoB,CAAC;aACzD;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;AACJ,CAAC;AAGD,MAAM,UAAU,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCR,CAAC;AACF,CAAC;AAGD,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO,GAAG,gCAAgC;;;;kCAIV,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;8CACA,MAAM,CAAC,KAAK;8CACZ,MAAM,CAAC,KAAK;8CACZ,MAAM,CAAC,KAAK;8CACZ,MAAM,CAAC,KAAK;EACxD,8BAA8B;CAC/B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,qEAAqE;IACrE,OAAO;;;;;EAKP,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCR,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,GAAG,+BAA+B;;;;;;;;;;;;;EAazC,6BAA6B;CAC9B,CAAC;AACF,CAAC"}