@slowcook-ai/cli 0.16.0-alpha.4 → 0.17.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +50 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/brew/agent.d.ts +25 -1
- package/dist/commands/brew/agent.d.ts.map +1 -1
- package/dist/commands/brew/agent.js +123 -20
- package/dist/commands/brew/agent.js.map +1 -1
- package/dist/commands/brew/halt.d.ts +1 -1
- package/dist/commands/brew/halt.d.ts.map +1 -1
- package/dist/commands/brew/halt.js +13 -0
- package/dist/commands/brew/halt.js.map +1 -1
- package/dist/commands/check/index.d.ts +14 -0
- package/dist/commands/check/index.d.ts.map +1 -0
- package/dist/commands/check/index.js +75 -0
- package/dist/commands/check/index.js.map +1 -0
- package/dist/commands/check/mock-isolation.d.ts +52 -0
- package/dist/commands/check/mock-isolation.d.ts.map +1 -0
- package/dist/commands/check/mock-isolation.js +186 -0
- package/dist/commands/check/mock-isolation.js.map +1 -0
- package/dist/commands/init/from-prod.d.ts +48 -0
- package/dist/commands/init/from-prod.d.ts.map +1 -0
- package/dist/commands/init/from-prod.js +256 -0
- package/dist/commands/init/from-prod.js.map +1 -0
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +9 -0
- package/dist/commands/init/index.js.map +1 -1
- package/dist/commands/init/mock.d.ts.map +1 -1
- package/dist/commands/init/mock.js +47 -13
- package/dist/commands/init/mock.js.map +1 -1
- package/dist/commands/on-mockup-approved/index.d.ts +25 -0
- package/dist/commands/on-mockup-approved/index.d.ts.map +1 -0
- package/dist/commands/on-mockup-approved/index.js +359 -0
- package/dist/commands/on-mockup-approved/index.js.map +1 -0
- package/dist/commands/plate/classify.d.ts +65 -0
- package/dist/commands/plate/classify.d.ts.map +1 -0
- package/dist/commands/plate/classify.js +194 -0
- package/dist/commands/plate/classify.js.map +1 -0
- package/dist/commands/plate/index.d.ts.map +1 -1
- package/dist/commands/plate/index.js +259 -34
- package/dist/commands/plate/index.js.map +1 -1
- package/dist/commands/port/index.d.ts +30 -0
- package/dist/commands/port/index.d.ts.map +1 -0
- package/dist/commands/port/index.js +237 -0
- package/dist/commands/port/index.js.map +1 -0
- package/dist/commands/port/transform.d.ts +68 -0
- package/dist/commands/port/transform.d.ts.map +1 -0
- package/dist/commands/port/transform.js +122 -0
- package/dist/commands/port/transform.js.map +1 -0
- package/dist/commands/preview/config.d.ts +73 -0
- package/dist/commands/preview/config.d.ts.map +1 -0
- package/dist/commands/preview/config.js +200 -0
- package/dist/commands/preview/config.js.map +1 -0
- package/dist/commands/preview/deploy.d.ts +35 -0
- package/dist/commands/preview/deploy.d.ts.map +1 -0
- package/dist/commands/preview/deploy.js +247 -0
- package/dist/commands/preview/deploy.js.map +1 -0
- package/dist/commands/preview/index.d.ts +9 -0
- package/dist/commands/preview/index.d.ts.map +1 -0
- package/dist/commands/preview/index.js +67 -0
- package/dist/commands/preview/index.js.map +1 -0
- package/dist/commands/preview/ssh.d.ts +49 -0
- package/dist/commands/preview/ssh.d.ts.map +1 -0
- package/dist/commands/preview/ssh.js +99 -0
- package/dist/commands/preview/ssh.js.map +1 -0
- package/dist/commands/preview/teardown.d.ts +25 -0
- package/dist/commands/preview/teardown.d.ts.map +1 -0
- package/dist/commands/preview/teardown.js +164 -0
- package/dist/commands/preview/teardown.js.map +1 -0
- package/dist/commands/recon/index.d.ts +60 -0
- package/dist/commands/recon/index.d.ts.map +1 -0
- package/dist/commands/recon/index.js +278 -0
- package/dist/commands/recon/index.js.map +1 -0
- package/dist/commands/refine/context.d.ts +12 -0
- package/dist/commands/refine/context.d.ts.map +1 -1
- package/dist/commands/refine/context.js +72 -0
- package/dist/commands/refine/context.js.map +1 -1
- package/dist/commands/refine/history-index.d.ts +84 -0
- package/dist/commands/refine/history-index.d.ts.map +1 -0
- package/dist/commands/refine/history-index.js +289 -0
- package/dist/commands/refine/history-index.js.map +1 -0
- package/dist/commands/refine/index.d.ts.map +1 -1
- package/dist/commands/refine/index.js +28 -0
- package/dist/commands/refine/index.js.map +1 -1
- package/dist/commands/run-mock/index.d.ts +34 -0
- package/dist/commands/run-mock/index.d.ts.map +1 -0
- package/dist/commands/run-mock/index.js +308 -0
- package/dist/commands/run-mock/index.js.map +1 -0
- package/dist/commands/vibe/index.d.ts.map +1 -1
- package/dist/commands/vibe/index.js +38 -4
- package/dist/commands/vibe/index.js.map +1 -1
- package/package.json +15 -13
- package/LICENSE +0 -21
|
@@ -80,6 +80,21 @@ What it writes:
|
|
|
80
80
|
mock/scenarios/.gitkeep empty until vibe writes story-N.ts files
|
|
81
81
|
`);
|
|
82
82
|
}
|
|
83
|
+
function detectMockPackageName(args) {
|
|
84
|
+
// Try the parent package.json's name; fall back to "slowcook-mock".
|
|
85
|
+
// npm rejects `${...}` in name, so the previous literal placeholder
|
|
86
|
+
// broke `npm install` — bug fix in 0.16.0-alpha.11.
|
|
87
|
+
try {
|
|
88
|
+
const parent = JSON.parse(readFileSync(join(args.cwd, "package.json"), "utf8"));
|
|
89
|
+
if (parent.name && /^[a-z0-9_-]/i.test(parent.name)) {
|
|
90
|
+
// Strip leading @scope/
|
|
91
|
+
const base = parent.name.replace(/^@[^/]+\//, "");
|
|
92
|
+
return `${base}-mock`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch { /* ignore */ }
|
|
96
|
+
return "slowcook-mock";
|
|
97
|
+
}
|
|
83
98
|
export function planMockFiles(args) {
|
|
84
99
|
const productionGlobals = join(args.cwd, "src/app/globals.css");
|
|
85
100
|
let globalsContents;
|
|
@@ -98,8 +113,9 @@ export function planMockFiles(args) {
|
|
|
98
113
|
globalsContents = MINIMAL_GLOBALS_CSS;
|
|
99
114
|
globalsNote = "(no src/app/globals.css found; wrote minimal Tailwind directives — extend manually)";
|
|
100
115
|
}
|
|
116
|
+
const pkgName = detectMockPackageName(args);
|
|
101
117
|
return [
|
|
102
|
-
{ path: "mock/package.json", contents: PACKAGE_JSON(args.runtimeVersion), skipIfExists: true },
|
|
118
|
+
{ path: "mock/package.json", contents: PACKAGE_JSON(args.runtimeVersion, pkgName), skipIfExists: true },
|
|
103
119
|
{ path: "mock/Dockerfile", contents: DOCKERFILE, skipIfExists: true },
|
|
104
120
|
{ path: "mock/tsconfig.json", contents: TSCONFIG, skipIfExists: true },
|
|
105
121
|
{ path: "mock/next.config.js", contents: NEXT_CONFIG, skipIfExists: true },
|
|
@@ -171,11 +187,13 @@ export async function initMock(argv, cliVersion) {
|
|
|
171
187
|
* here. After 0.16 the cli's package.json could carry a peer-pin field.
|
|
172
188
|
*/
|
|
173
189
|
function mockRuntimeVersionFor(_cliVersion) {
|
|
174
|
-
|
|
190
|
+
// Pin to ^0.1.0 — what's actually on npm. ^ picks up 0.1.x patches
|
|
191
|
+
// when they publish; bumping past 0.2 needs an intentional cli release.
|
|
192
|
+
return "^0.1.0";
|
|
175
193
|
}
|
|
176
194
|
// ---------------- templates ----------------
|
|
177
|
-
const PACKAGE_JSON = (runtimeVersion) => `{
|
|
178
|
-
"name": "${
|
|
195
|
+
const PACKAGE_JSON = (runtimeVersion, name) => `{
|
|
196
|
+
"name": "${name}",
|
|
179
197
|
"version": "0.0.0",
|
|
180
198
|
"private": true,
|
|
181
199
|
"description": "Singular UI mock app. Run with \`npm run dev\` on :3100. See mock/README.md.",
|
|
@@ -330,6 +348,7 @@ body {
|
|
|
330
348
|
const LAYOUT_TSX = `import type { Metadata } from "next";
|
|
331
349
|
import type { ReactNode } from "react";
|
|
332
350
|
import { ScenarioRegistryProvider } from "@slowcook-ai/mock-runtime";
|
|
351
|
+
import { SlowcookReviewOverlay } from "@slowcook-ai/review-overlay/react";
|
|
333
352
|
import { registry } from "@/lib/scenario-registry";
|
|
334
353
|
import "./globals.css";
|
|
335
354
|
|
|
@@ -345,19 +364,23 @@ export default function RootLayout({ children }: { children: ReactNode }) {
|
|
|
345
364
|
<ScenarioRegistryProvider registry={registry}>
|
|
346
365
|
{children}
|
|
347
366
|
{/*
|
|
348
|
-
Review-overlay
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
367
|
+
Review-overlay (review-overlay 0.5.1+ auto-detects all
|
|
368
|
+
props from process.env.NEXT_PUBLIC_SLOWCOOK_*). Set those
|
|
369
|
+
in dev (\`slowcook run-mock\` does it for you) to activate.
|
|
370
|
+
Production builds keep them unset so the overlay
|
|
371
|
+
short-circuits to null + tree-shakes out cleanly.
|
|
353
372
|
*/}
|
|
373
|
+
<SlowcookReviewOverlay />
|
|
354
374
|
</ScenarioRegistryProvider>
|
|
355
375
|
</body>
|
|
356
376
|
</html>
|
|
357
377
|
);
|
|
358
378
|
}
|
|
359
379
|
`;
|
|
360
|
-
const PAGE_TSX = `
|
|
380
|
+
const PAGE_TSX = `"use client";
|
|
381
|
+
|
|
382
|
+
import { ScenarioPicker } from "@slowcook-ai/mock-runtime";
|
|
383
|
+
import { useScenarioCommentStats } from "@slowcook-ai/review-overlay/react";
|
|
361
384
|
|
|
362
385
|
/**
|
|
363
386
|
* Mock app homepage = scenario picker (provided by the runtime).
|
|
@@ -365,9 +388,19 @@ const PAGE_TSX = `import { ScenarioPicker } from "@slowcook-ai/mock-runtime";
|
|
|
365
388
|
* Replaces this with a custom picker if you want different grouping/
|
|
366
389
|
* filtering. The runtime's hooks + registry API are stable; this UI
|
|
367
390
|
* is a default that consumers can swap.
|
|
391
|
+
*
|
|
392
|
+
* The \`useScenarioCommentStats\` hook (review-overlay 0.4.0+) walks
|
|
393
|
+
* every mockup PR's comments + groups by story_id. Cards then show
|
|
394
|
+
* comment / applied / unresolved / spec-altering counts. Only fires
|
|
395
|
+
* when NEXT_PUBLIC_SLOWCOOK_REVIEW=1 + a PAT is in localStorage.
|
|
368
396
|
*/
|
|
369
397
|
export default function Page() {
|
|
370
|
-
|
|
398
|
+
const stats = useScenarioCommentStats({
|
|
399
|
+
owner: process.env["NEXT_PUBLIC_SLOWCOOK_OWNER"] ?? "",
|
|
400
|
+
repo: process.env["NEXT_PUBLIC_SLOWCOOK_REPO"] ?? "",
|
|
401
|
+
enabled: process.env["NEXT_PUBLIC_SLOWCOOK_REVIEW"] === "1",
|
|
402
|
+
});
|
|
403
|
+
return <ScenarioPicker commentStats={stats ?? undefined} />;
|
|
371
404
|
}
|
|
372
405
|
`;
|
|
373
406
|
const SCENARIO_REGISTRY = `import { defineScenarios } from "@slowcook-ai/mock-runtime";
|
|
@@ -385,7 +418,7 @@ const SCENARIO_REGISTRY = `import { defineScenarios } from "@slowcook-ai/mock-ru
|
|
|
385
418
|
|
|
386
419
|
// Vibe-managed imports below this line. Don't reorder; vibe inserts
|
|
387
420
|
// new lines at the bottom of the import block.
|
|
388
|
-
// e.g. import story017 from "../../scenarios/story-017
|
|
421
|
+
// e.g. import story017 from "../../scenarios/story-017";
|
|
389
422
|
|
|
390
423
|
export const registry = defineScenarios([
|
|
391
424
|
// story017,
|
|
@@ -429,6 +462,7 @@ clicking or refreshes to start over).
|
|
|
429
462
|
\`\`\`ts
|
|
430
463
|
// mock/scenarios/story-017.ts
|
|
431
464
|
import type { Scenario } from "@slowcook-ai/mock-runtime";
|
|
465
|
+
// (no \`.js\` extensions in TS imports — Next/Turbopack uses bundler resolution)
|
|
432
466
|
|
|
433
467
|
const scenario: Scenario = {
|
|
434
468
|
id: "017",
|
|
@@ -452,7 +486,7 @@ Then add to the registry in \`mock/src/lib/scenario-registry.ts\`:
|
|
|
452
486
|
|
|
453
487
|
\`\`\`ts
|
|
454
488
|
import { defineScenarios } from "@slowcook-ai/mock-runtime";
|
|
455
|
-
import story017 from "../../scenarios/story-017
|
|
489
|
+
import story017 from "../../scenarios/story-017";
|
|
456
490
|
|
|
457
491
|
export const registry = defineScenarios([story017]);
|
|
458
492
|
\`\`\`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.js","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAY,MAAM,SAAS,CAAC;AACvF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAmBpD,MAAM,UAAU,iBAAiB,CAAC,IAAc,EAAE,cAAsB;IACtE,MAAM,IAAI,GAAiB;QACzB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK;QACb,cAAc;KACf,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,OAAO,IAAI,IAAI,EAAE,CAAC;YAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;YAAC,CAAC,EAAE,CAAC;QAAC,CAAC;aAC/C,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAAC,CAAC;aAC3C,IAAI,CAAC,KAAK,WAAW,EAAE,CAAC;YAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC;aAC9C,IAAI,CAAC,KAAK,mBAAmB,IAAI,IAAI,EAAE,CAAC;YAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAAC,CAAC,EAAE,CAAC;QAAC,CAAC;aAC3E,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACtC,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Bb,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAkB;IAC9C,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;IAChE,IAAI,eAAuB,CAAC;IAC5B,IAAI,WAAmB,CAAC;IACxB,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,eAAe,GAAG,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;YAC1D,WAAW,GAAG,0EAA0E,CAAC;QAC3F,CAAC;QAAC,MAAM,CAAC;YACP,eAAe,GAAG,mBAAmB,CAAC;YACtC,WAAW,GAAG,2FAA2F,CAAC;QAC5G,CAAC;IACH,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,mBAAmB,CAAC;QACtC,WAAW,GAAG,qFAAqF,CAAC;IACtG,CAAC;IACD,OAAO;QACL,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"mock.js","sourceRoot":"","sources":["../../../src/commands/init/mock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `slowcook on-mockup-approved --pr <number>` — 0.16.0-α.25.
|
|
3
|
+
*
|
|
4
|
+
* Called from a workflow that fires on `pull_request.labeled` with
|
|
5
|
+
* label = `slowcook-mockup-approved`. Walks every cost source for the
|
|
6
|
+
* story (refine on the source issue, refine + spec-merge on the spec
|
|
7
|
+
* PR, recipe on the tests PR, vibe + plate on the mockup PR), itemizes
|
|
8
|
+
* each run, and posts (or UPDATES) a cost-rollup audit comment on the
|
|
9
|
+
* originating GitHub issue.
|
|
10
|
+
*
|
|
11
|
+
* α.25 changes vs α.23:
|
|
12
|
+
* - Walks ALL related sources, not just the mockup PR. Captures
|
|
13
|
+
* refine + recipe runs that previously went uncounted.
|
|
14
|
+
* - Itemizes each run (one row per cost marker) instead of grouping
|
|
15
|
+
* by agent. Includes timestamp, agent, model, $, source link, and
|
|
16
|
+
* commit SHA when available (parsed from plate's breadcrumb JSON).
|
|
17
|
+
* - Idempotent: looks for an existing `slowcook:on-mockup-approved`
|
|
18
|
+
* marker in the issue's comments; updates that comment in place
|
|
19
|
+
* instead of double-posting.
|
|
20
|
+
*
|
|
21
|
+
* Pairs with on-spec-merged / on-tests-merged / on-brew-merged so the
|
|
22
|
+
* issue thread tells the full pipeline story end-to-end.
|
|
23
|
+
*/
|
|
24
|
+
export declare function onMockupApproved(argv: string[]): Promise<void>;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/on-mockup-approved/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAuOH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0KpE"}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `slowcook on-mockup-approved --pr <number>` — 0.16.0-α.25.
|
|
3
|
+
*
|
|
4
|
+
* Called from a workflow that fires on `pull_request.labeled` with
|
|
5
|
+
* label = `slowcook-mockup-approved`. Walks every cost source for the
|
|
6
|
+
* story (refine on the source issue, refine + spec-merge on the spec
|
|
7
|
+
* PR, recipe on the tests PR, vibe + plate on the mockup PR), itemizes
|
|
8
|
+
* each run, and posts (or UPDATES) a cost-rollup audit comment on the
|
|
9
|
+
* originating GitHub issue.
|
|
10
|
+
*
|
|
11
|
+
* α.25 changes vs α.23:
|
|
12
|
+
* - Walks ALL related sources, not just the mockup PR. Captures
|
|
13
|
+
* refine + recipe runs that previously went uncounted.
|
|
14
|
+
* - Itemizes each run (one row per cost marker) instead of grouping
|
|
15
|
+
* by agent. Includes timestamp, agent, model, $, source link, and
|
|
16
|
+
* commit SHA when available (parsed from plate's breadcrumb JSON).
|
|
17
|
+
* - Idempotent: looks for an existing `slowcook:on-mockup-approved`
|
|
18
|
+
* marker in the issue's comments; updates that comment in place
|
|
19
|
+
* instead of double-posting.
|
|
20
|
+
*
|
|
21
|
+
* Pairs with on-spec-merged / on-tests-merged / on-brew-merged so the
|
|
22
|
+
* issue thread tells the full pipeline story end-to-end.
|
|
23
|
+
*/
|
|
24
|
+
import { execSync } from "node:child_process";
|
|
25
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import YAML from "yaml";
|
|
28
|
+
import { Octokit } from "@octokit/rest";
|
|
29
|
+
function parseArgs(argv) {
|
|
30
|
+
const args = { prNumber: 0, repoRoot: process.cwd() };
|
|
31
|
+
for (let i = 0; i < argv.length; i++) {
|
|
32
|
+
const arg = argv[i];
|
|
33
|
+
const next = argv[i + 1];
|
|
34
|
+
if (arg === "--pr" && next) {
|
|
35
|
+
args.prNumber = parseInt(next, 10);
|
|
36
|
+
i++;
|
|
37
|
+
}
|
|
38
|
+
else if (arg === "--cwd" && next) {
|
|
39
|
+
args.repoRoot = next;
|
|
40
|
+
i++;
|
|
41
|
+
}
|
|
42
|
+
else if (arg === "--owner" && next) {
|
|
43
|
+
args.owner = next;
|
|
44
|
+
i++;
|
|
45
|
+
}
|
|
46
|
+
else if (arg === "--repo" && next) {
|
|
47
|
+
args.repo = next;
|
|
48
|
+
i++;
|
|
49
|
+
}
|
|
50
|
+
else if (arg === "--help" || arg === "-h") {
|
|
51
|
+
printHelp();
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!args.prNumber || isNaN(args.prNumber)) {
|
|
56
|
+
console.error("Missing required --pr <number>");
|
|
57
|
+
printHelp();
|
|
58
|
+
process.exit(64);
|
|
59
|
+
}
|
|
60
|
+
return args;
|
|
61
|
+
}
|
|
62
|
+
function printHelp() {
|
|
63
|
+
console.log(`
|
|
64
|
+
slowcook on-mockup-approved — post (or update) a cost rollup on the source issue
|
|
65
|
+
|
|
66
|
+
Triggered by a workflow listening for pull_request.labeled events on
|
|
67
|
+
PRs labeled \`slowcook-mockup\` when the \`slowcook-mockup-approved\`
|
|
68
|
+
label is added. Walks every related source (issue, spec PR, tests PR,
|
|
69
|
+
mockup PR), itemizes every cost marker, posts a chronological table.
|
|
70
|
+
|
|
71
|
+
Idempotent: re-running updates the existing rollup comment on the
|
|
72
|
+
issue rather than posting a new one.
|
|
73
|
+
|
|
74
|
+
Usage:
|
|
75
|
+
slowcook on-mockup-approved --pr <number> [options]
|
|
76
|
+
|
|
77
|
+
Options:
|
|
78
|
+
--pr <number> Mockup PR number (required)
|
|
79
|
+
--cwd <path> Repo working directory (default: .)
|
|
80
|
+
--owner <login> Repo owner (default: detected from git remote)
|
|
81
|
+
--repo <name> Repo name (default: detected from git remote)
|
|
82
|
+
|
|
83
|
+
Environment:
|
|
84
|
+
GITHUB_TOKEN (required) Token with issues:write + pull-requests:read
|
|
85
|
+
|
|
86
|
+
Exit codes:
|
|
87
|
+
0 comment posted/updated (or nothing to do)
|
|
88
|
+
2 script error
|
|
89
|
+
`);
|
|
90
|
+
}
|
|
91
|
+
function detectOwnerRepo(cwd) {
|
|
92
|
+
try {
|
|
93
|
+
const url = execSync("git remote get-url origin", {
|
|
94
|
+
cwd,
|
|
95
|
+
encoding: "utf8",
|
|
96
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
97
|
+
}).trim();
|
|
98
|
+
const m = url.match(/github\.com[:/]([^/]+)\/([^/.]+)(?:\.git)?$/);
|
|
99
|
+
if (m && m[1] && m[2])
|
|
100
|
+
return { owner: m[1], repo: m[2] };
|
|
101
|
+
}
|
|
102
|
+
catch { /* ignore */ }
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const COST_MARKER_RE = /<!--\s*slowcook:cost\s+([^>]+?)\s*-->/g;
|
|
106
|
+
const ROLLUP_MARKER = "slowcook:on-mockup-approved";
|
|
107
|
+
/** Parse `key1=value1 key2=value2` pairs from a cost-marker body. */
|
|
108
|
+
function parseMarkerKvs(s) {
|
|
109
|
+
const out = {};
|
|
110
|
+
for (const m of s.matchAll(/(\w+)=([^\s]+)/g)) {
|
|
111
|
+
out[m[1]] = m[2];
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 0.16.0-α.25 — legacy-prose fallback for vibe runs that pre-date α.24's
|
|
117
|
+
* structured `<!-- slowcook:cost -->` emission. Vibe ≤α.11 wrote
|
|
118
|
+
* "Generated by `slowcook vibe@VERSION` (spend $X.XXXX)" in its PR
|
|
119
|
+
* body. We pluck that out so dogfood rollups stay accurate.
|
|
120
|
+
*/
|
|
121
|
+
const VIBE_LEGACY_PROSE_RE = /Generated by `slowcook vibe@([^`]+)`[^(]*\(spend \$([0-9.]+)\)/;
|
|
122
|
+
function extractCostRunsFromBody(body, source, timestamp) {
|
|
123
|
+
const out = [];
|
|
124
|
+
// Legacy prose vibe — only fires when no structured vibe marker
|
|
125
|
+
// also exists (so we don't double-count post-α.24 vibe runs).
|
|
126
|
+
if (!/slowcook:cost\s+agent=vibe/.test(body)) {
|
|
127
|
+
const proseMatch = body.match(VIBE_LEGACY_PROSE_RE);
|
|
128
|
+
if (proseMatch) {
|
|
129
|
+
const usd = parseFloat(proseMatch[2]);
|
|
130
|
+
if (!Number.isNaN(usd)) {
|
|
131
|
+
out.push({
|
|
132
|
+
agent: "vibe",
|
|
133
|
+
usd,
|
|
134
|
+
cli: proseMatch[1],
|
|
135
|
+
timestamp,
|
|
136
|
+
source,
|
|
137
|
+
commitSha: null,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
COST_MARKER_RE.lastIndex = 0;
|
|
143
|
+
// For plate-reply breadcrumbs, look for the amendment_commit so we
|
|
144
|
+
// can link to the diff. Same comment body usually carries both
|
|
145
|
+
// markers (cost + breadcrumb).
|
|
146
|
+
let amendmentCommit = null;
|
|
147
|
+
const breadcrumbMatch = body.match(/slowcook:plate-reply\s*\n\s*(\{[\s\S]*?\})\s*\n\s*-->/);
|
|
148
|
+
if (breadcrumbMatch && breadcrumbMatch[1]) {
|
|
149
|
+
try {
|
|
150
|
+
const payload = JSON.parse(breadcrumbMatch[1]);
|
|
151
|
+
if (payload.amendment_commit)
|
|
152
|
+
amendmentCommit = payload.amendment_commit;
|
|
153
|
+
}
|
|
154
|
+
catch { /* ignore */ }
|
|
155
|
+
}
|
|
156
|
+
let m;
|
|
157
|
+
while ((m = COST_MARKER_RE.exec(body)) !== null) {
|
|
158
|
+
const kvs = parseMarkerKvs(m[1]);
|
|
159
|
+
const usd = parseFloat(kvs["usd"] ?? "0");
|
|
160
|
+
if (!kvs["agent"] || Number.isNaN(usd))
|
|
161
|
+
continue;
|
|
162
|
+
out.push({
|
|
163
|
+
agent: kvs["agent"],
|
|
164
|
+
usd,
|
|
165
|
+
model: kvs["model"],
|
|
166
|
+
cli: kvs["cli"],
|
|
167
|
+
timestamp,
|
|
168
|
+
source,
|
|
169
|
+
commitSha: amendmentCommit,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
async function fetchPrComments(octokit, owner, repo, prNumber) {
|
|
175
|
+
return octokit.paginate(octokit.rest.issues.listComments, {
|
|
176
|
+
owner, repo, issue_number: prNumber, per_page: 100,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async function fetchIssueComments(octokit, owner, repo, issueNumber) {
|
|
180
|
+
return octokit.paginate(octokit.rest.issues.listComments, {
|
|
181
|
+
owner, repo, issue_number: issueNumber, per_page: 100,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async function findRelatedPrs(octokit, owner, repo, storyId) {
|
|
185
|
+
// Search PRs by title for `story-{id}`. Captures spec, tests,
|
|
186
|
+
// mockup, brew PRs all in one pass. Excludes superseded specs etc.
|
|
187
|
+
const q = `repo:${owner}/${repo} is:pr in:title story-${storyId}`;
|
|
188
|
+
const res = await octokit.rest.search.issuesAndPullRequests({ q, per_page: 50 });
|
|
189
|
+
const out = [];
|
|
190
|
+
for (const item of res.data.items) {
|
|
191
|
+
if (!item.pull_request)
|
|
192
|
+
continue;
|
|
193
|
+
const title = item.title.toLowerCase();
|
|
194
|
+
let kind;
|
|
195
|
+
if (title.startsWith("spec:"))
|
|
196
|
+
kind = "spec";
|
|
197
|
+
else if (title.startsWith("tests:") || title.startsWith("recipe:"))
|
|
198
|
+
kind = "tests";
|
|
199
|
+
else if (title.startsWith("mockup:"))
|
|
200
|
+
kind = "mockup";
|
|
201
|
+
else if (title.startsWith("brew") || title.startsWith("brew ("))
|
|
202
|
+
kind = "brew";
|
|
203
|
+
else
|
|
204
|
+
continue; // unknown — likely a manual PR; skip
|
|
205
|
+
out.push({
|
|
206
|
+
kind,
|
|
207
|
+
number: item.number,
|
|
208
|
+
url: item.html_url,
|
|
209
|
+
body: item.body,
|
|
210
|
+
bodyTimestamp: item.created_at,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
export async function onMockupApproved(argv) {
|
|
216
|
+
const args = parseArgs(argv);
|
|
217
|
+
const token = process.env["GITHUB_TOKEN"];
|
|
218
|
+
if (!token) {
|
|
219
|
+
console.error("GITHUB_TOKEN environment variable is not set.");
|
|
220
|
+
process.exit(2);
|
|
221
|
+
}
|
|
222
|
+
let owner = args.owner;
|
|
223
|
+
let repo = args.repo;
|
|
224
|
+
if (!owner || !repo) {
|
|
225
|
+
const detected = detectOwnerRepo(args.repoRoot);
|
|
226
|
+
if (!detected) {
|
|
227
|
+
console.error("Could not detect owner/repo from git remote. Pass --owner and --repo.");
|
|
228
|
+
process.exit(2);
|
|
229
|
+
}
|
|
230
|
+
owner = owner ?? detected.owner;
|
|
231
|
+
repo = repo ?? detected.repo;
|
|
232
|
+
}
|
|
233
|
+
const octokit = new Octokit({ auth: token, userAgent: "slowcook-ai/cli" });
|
|
234
|
+
// 1. Fetch the mockup PR to get its head ref + verify shape.
|
|
235
|
+
const pr = await octokit.rest.pulls.get({ owner, repo, pull_number: args.prNumber });
|
|
236
|
+
const headRef = pr.data.head.ref;
|
|
237
|
+
const headRefMatch = headRef.match(/^slowcook\/mockup\/story-([\w-]+)$/);
|
|
238
|
+
if (!headRefMatch || !headRefMatch[1]) {
|
|
239
|
+
console.error(`PR #${args.prNumber} head ref "${headRef}" doesn't match slowcook/mockup/story-N. Skipping.`);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const storyId = headRefMatch[1];
|
|
243
|
+
// 2. Read the spec to find source_issue.
|
|
244
|
+
const specPath = join(args.repoRoot, "specs", `story-${storyId}.yaml`);
|
|
245
|
+
if (!existsSync(specPath)) {
|
|
246
|
+
console.error(`Spec not found at ${specPath}; cannot resolve source_issue.`);
|
|
247
|
+
process.exit(0);
|
|
248
|
+
}
|
|
249
|
+
const spec = YAML.parse(readFileSync(specPath, "utf8"));
|
|
250
|
+
if (!spec.source_issue) {
|
|
251
|
+
console.log(`Spec story-${storyId} has no source_issue. Nothing to bill.`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const issueMatchYaml = spec.source_issue.match(/^#?(\d+)$/);
|
|
255
|
+
if (!issueMatchYaml || !issueMatchYaml[1]) {
|
|
256
|
+
console.error(`spec source_issue "${spec.source_issue}" not numeric.`);
|
|
257
|
+
process.exit(0);
|
|
258
|
+
}
|
|
259
|
+
const issueNumber = parseInt(issueMatchYaml[1], 10);
|
|
260
|
+
// 3. Walk every related source for cost markers.
|
|
261
|
+
const issue = await octokit.rest.issues.get({ owner, repo, issue_number: issueNumber });
|
|
262
|
+
const issueUrl = issue.data.html_url;
|
|
263
|
+
const allRuns = [];
|
|
264
|
+
// 3a. Issue body + comments (refine often posts here).
|
|
265
|
+
if (issue.data.body) {
|
|
266
|
+
allRuns.push(...extractCostRunsFromBody(issue.data.body, { kind: "issue", number: issueNumber, url: issueUrl }, issue.data.created_at));
|
|
267
|
+
}
|
|
268
|
+
const issueComments = await fetchIssueComments(octokit, owner, repo, issueNumber);
|
|
269
|
+
for (const c of issueComments) {
|
|
270
|
+
if (!c.body)
|
|
271
|
+
continue;
|
|
272
|
+
allRuns.push(...extractCostRunsFromBody(c.body, { kind: "issue", number: issueNumber, url: c.html_url ?? issueUrl }, c.created_at ?? ""));
|
|
273
|
+
}
|
|
274
|
+
// 3b. Every PR matching `story-{id}` in title (spec / tests / mockup / brew).
|
|
275
|
+
const relatedPrs = await findRelatedPrs(octokit, owner, repo, storyId);
|
|
276
|
+
for (const pr of relatedPrs) {
|
|
277
|
+
// PR body (vibe's initial cost lives here for the mockup PR).
|
|
278
|
+
if (pr.body) {
|
|
279
|
+
allRuns.push(...extractCostRunsFromBody(pr.body, { kind: pr.kind, number: pr.number, url: pr.url }, pr.bodyTimestamp ?? ""));
|
|
280
|
+
}
|
|
281
|
+
// PR comments.
|
|
282
|
+
const prComments = await fetchPrComments(octokit, owner, repo, pr.number);
|
|
283
|
+
for (const c of prComments) {
|
|
284
|
+
if (!c.body)
|
|
285
|
+
continue;
|
|
286
|
+
allRuns.push(...extractCostRunsFromBody(c.body, { kind: pr.kind, number: pr.number, url: c.html_url ?? pr.url }, c.created_at ?? ""));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// Sort chronologically.
|
|
290
|
+
allRuns.sort((a, b) => (a.timestamp || "").localeCompare(b.timestamp || ""));
|
|
291
|
+
// 4. Build the rollup body.
|
|
292
|
+
const total = allRuns.reduce((s, r) => s + r.usd, 0);
|
|
293
|
+
const totalsByAgent = new Map();
|
|
294
|
+
for (const r of allRuns) {
|
|
295
|
+
const t = totalsByAgent.get(r.agent) ?? { runs: 0, usd: 0 };
|
|
296
|
+
t.runs += 1;
|
|
297
|
+
t.usd += r.usd;
|
|
298
|
+
totalsByAgent.set(r.agent, t);
|
|
299
|
+
}
|
|
300
|
+
const lines = [];
|
|
301
|
+
lines.push(`### slowcook · mockup approved (story-${storyId})`);
|
|
302
|
+
lines.push("");
|
|
303
|
+
lines.push(`Mockup PR #${args.prNumber} signed off; \`slowcook-mockup-approved\` label applied. ` +
|
|
304
|
+
`Plate refuses further amendments. **Next**: merge the PR to fire \`brew --mode plate\` ` +
|
|
305
|
+
`(once the recipe-tests PR is also merged).`);
|
|
306
|
+
lines.push("");
|
|
307
|
+
// Itemized rollup — one row per cost marker.
|
|
308
|
+
lines.push(`#### Itemised runs (${allRuns.length})`);
|
|
309
|
+
lines.push("");
|
|
310
|
+
if (allRuns.length === 0) {
|
|
311
|
+
lines.push("_No cost markers found across this story's PRs + issue. (Likely a pre-α.24 vibe run that didn't emit the structured marker.)_");
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
lines.push("| # | When | Agent | Model | Source | $ | Diff |");
|
|
315
|
+
lines.push("|--:|---|---|---|---|---:|---|");
|
|
316
|
+
let i = 1;
|
|
317
|
+
for (const r of allRuns) {
|
|
318
|
+
const when = r.timestamp ? new Date(r.timestamp).toISOString().slice(0, 16).replace("T", " ") : "—";
|
|
319
|
+
const sourceLabel = `${r.source.kind} #${r.source.number}`;
|
|
320
|
+
const sourceLink = `[${sourceLabel}](${r.source.url})`;
|
|
321
|
+
const diff = r.commitSha
|
|
322
|
+
? `[\`${r.commitSha.slice(0, 7)}\`](https://github.com/${owner}/${repo}/commit/${r.commitSha})`
|
|
323
|
+
: "—";
|
|
324
|
+
lines.push(`| ${i} | ${when} | \`${r.agent}\` | ${r.model ? `\`${r.model}\`` : "—"} | ${sourceLink} | $${r.usd.toFixed(4)} | ${diff} |`);
|
|
325
|
+
i++;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
lines.push("");
|
|
329
|
+
// Totals by agent.
|
|
330
|
+
lines.push(`#### Totals by agent`);
|
|
331
|
+
lines.push("");
|
|
332
|
+
lines.push("| Agent | Runs | $ |");
|
|
333
|
+
lines.push("|---|---:|---:|");
|
|
334
|
+
for (const [agent, t] of [...totalsByAgent.entries()].sort()) {
|
|
335
|
+
lines.push(`| \`${agent}\` | ${t.runs} | $${t.usd.toFixed(4)} |`);
|
|
336
|
+
}
|
|
337
|
+
lines.push(`| **Total so far** | **${allRuns.length}** | **$${total.toFixed(4)}** |`);
|
|
338
|
+
lines.push("");
|
|
339
|
+
lines.push(`_Post-merge brew run will add its own line; \`on-brew-merged\` updates this comment when that lands._`);
|
|
340
|
+
lines.push("");
|
|
341
|
+
lines.push(`<!-- ${ROLLUP_MARKER} pr=${args.prNumber} story=${storyId} usd=${total.toFixed(4)} runs=${allRuns.length} -->`);
|
|
342
|
+
const newBody = lines.join("\n");
|
|
343
|
+
// 5. Post or update the rollup comment on the source issue.
|
|
344
|
+
const existingComments = await fetchIssueComments(octokit, owner, repo, issueNumber);
|
|
345
|
+
const existing = existingComments.find((c) => (c.body ?? "").includes(ROLLUP_MARKER));
|
|
346
|
+
if (existing) {
|
|
347
|
+
await octokit.rest.issues.updateComment({
|
|
348
|
+
owner, repo, comment_id: existing.id, body: newBody,
|
|
349
|
+
});
|
|
350
|
+
console.log(`Updated existing rollup comment on issue #${issueNumber} (story-${storyId}, ${allRuns.length} runs / $${total.toFixed(4)} total).`);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
await octokit.rest.issues.createComment({
|
|
354
|
+
owner, repo, issue_number: issueNumber, body: newBody,
|
|
355
|
+
});
|
|
356
|
+
console.log(`Posted new rollup comment on issue #${issueNumber} (story-${storyId}, ${allRuns.length} runs / $${total.toFixed(4)} total).`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/on-mockup-approved/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PM-comment classifier — 0.16.0-α.7.
|
|
3
|
+
*
|
|
4
|
+
* Each element-anchored review-overlay comment on a slowcook-mockup PR
|
|
5
|
+
* gets categorized so plate knows what to do with it:
|
|
6
|
+
*
|
|
7
|
+
* - "cosmetic" → amend the mock with minimum diff
|
|
8
|
+
* - "spec-altering" → ESCALATE: would invalidate a spec assertion or
|
|
9
|
+
* acceptance scenario; PM must confirm the spec
|
|
10
|
+
* change before plate touches the mock
|
|
11
|
+
* - "mock-divergence" → the mock diverged from the spec; align mock
|
|
12
|
+
* to spec; note in summary why the PM ask is
|
|
13
|
+
* being interpreted this way
|
|
14
|
+
*
|
|
15
|
+
* α.7 ships a deterministic heuristic. Each classification has a clear
|
|
16
|
+
* rationale string so the escalation comment can quote the trigger.
|
|
17
|
+
*
|
|
18
|
+
* Heuristic structure:
|
|
19
|
+
* 1. Parse the spec YAML to extract the salient assertion targets:
|
|
20
|
+
* - acceptance_scenarios prose lines
|
|
21
|
+
* - api_contract response field names
|
|
22
|
+
* - invariants prose
|
|
23
|
+
* - ui_behavior viewport prose
|
|
24
|
+
* → a flat set of "spec terms" (lowercased, normalized words).
|
|
25
|
+
* 2. Score the comment prose against those terms:
|
|
26
|
+
* - any direct mention of an acceptance keyword phrase → spec-altering
|
|
27
|
+
* - mention of a domain noun + a "remove/change/replace" → spec-altering
|
|
28
|
+
* - mentions only adjective/style words (color, padding, → cosmetic
|
|
29
|
+
* font, spacing, alignment, shadow, etc.)
|
|
30
|
+
* - else → mock-divergence
|
|
31
|
+
*
|
|
32
|
+
* The heuristic is intentionally conservative on spec-altering: false
|
|
33
|
+
* positives only cost a PM confirm round; false negatives let plate
|
|
34
|
+
* silently weaken the spec, which is the failure mode the architecture
|
|
35
|
+
* is designed to prevent. When in doubt → escalate.
|
|
36
|
+
*
|
|
37
|
+
* No LLM dep here — pure functions over inputs. LLM-backed classifier
|
|
38
|
+
* is a future α.7.1 upgrade if heuristic shows real misses.
|
|
39
|
+
*/
|
|
40
|
+
export type Classification = "cosmetic" | "spec-altering" | "mock-divergence";
|
|
41
|
+
export interface ClassifyResult {
|
|
42
|
+
classification: Classification;
|
|
43
|
+
/** Why this classification — included verbatim in escalation comments. */
|
|
44
|
+
rationale: string;
|
|
45
|
+
/** The spec terms (if any) that matched in the comment prose. */
|
|
46
|
+
matchedSpecTerms: string[];
|
|
47
|
+
}
|
|
48
|
+
export interface ClassifyArgs {
|
|
49
|
+
/** Free prose written by the PM in the review-overlay comment. */
|
|
50
|
+
prose: string;
|
|
51
|
+
/**
|
|
52
|
+
* Spec YAML body. Hand-parsed for the assertion targets; we don't
|
|
53
|
+
* need a full YAML parser since the heuristic only needs salient
|
|
54
|
+
* words from acceptance_scenarios / invariants / api_contract.
|
|
55
|
+
*/
|
|
56
|
+
specYaml: string;
|
|
57
|
+
}
|
|
58
|
+
export declare function classifyComment(args: ClassifyArgs): ClassifyResult;
|
|
59
|
+
/**
|
|
60
|
+
* Extract candidate "spec terms" — lowercase, deduplicated significant
|
|
61
|
+
* tokens from the spec sections plate cares about. Used by the
|
|
62
|
+
* classifier to detect overlap between PM prose and spec assertions.
|
|
63
|
+
*/
|
|
64
|
+
export declare function extractSpecTerms(specYaml: string): string[];
|
|
65
|
+
//# sourceMappingURL=classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../../src/commands/plate/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE9E,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAyBD,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,CAgElE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAe3D"}
|