mewkit 1.16.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/build-plugin.d.ts +6 -0
- package/dist/commands/build-plugin.d.ts.map +1 -1
- package/dist/commands/build-plugin.js +3 -3
- package/dist/commands/build-plugin.js.map +1 -1
- package/dist/commands/plan.d.ts +7 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +124 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/providers.js +15 -0
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/validate.d.ts +7 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +58 -1
- package/dist/commands/validate.js.map +1 -1
- package/dist/core/build-inventory.d.ts +16 -0
- package/dist/core/build-inventory.d.ts.map +1 -1
- package/dist/core/build-inventory.js +35 -0
- package/dist/core/build-inventory.js.map +1 -1
- package/dist/core/capability.d.ts +24 -24
- package/dist/core/check-agent-conformance.d.ts +14 -0
- package/dist/core/check-agent-conformance.d.ts.map +1 -0
- package/dist/core/check-agent-conformance.js +118 -0
- package/dist/core/check-agent-conformance.js.map +1 -0
- package/dist/core/check-docs-references.d.ts.map +1 -1
- package/dist/core/check-docs-references.js +6 -0
- package/dist/core/check-docs-references.js.map +1 -1
- package/dist/core/check-gate-authority.d.ts +40 -0
- package/dist/core/check-gate-authority.d.ts.map +1 -0
- package/dist/core/check-gate-authority.js +313 -0
- package/dist/core/check-gate-authority.js.map +1 -0
- package/dist/core/check-plugin-parity.d.ts +15 -0
- package/dist/core/check-plugin-parity.d.ts.map +1 -0
- package/dist/core/check-plugin-parity.js +130 -0
- package/dist/core/check-plugin-parity.js.map +1 -0
- package/dist/core/check-pseudo-capabilities.d.ts +15 -0
- package/dist/core/check-pseudo-capabilities.d.ts.map +1 -0
- package/dist/core/check-pseudo-capabilities.js +89 -0
- package/dist/core/check-pseudo-capabilities.js.map +1 -0
- package/dist/core/plan-parser.d.ts +40 -0
- package/dist/core/plan-parser.d.ts.map +1 -0
- package/dist/core/plan-parser.js +126 -0
- package/dist/core/plan-parser.js.map +1 -0
- package/dist/core/plugin-payload.d.ts.map +1 -1
- package/dist/core/plugin-payload.js +9 -0
- package/dist/core/plugin-payload.js.map +1 -1
- package/dist/core/provider-adapter.d.ts +4 -0
- package/dist/core/provider-adapter.d.ts.map +1 -1
- package/dist/core/provider-adapter.js +2 -0
- package/dist/core/provider-adapter.js.map +1 -1
- package/dist/core/provider-operations.d.ts +51 -0
- package/dist/core/provider-operations.d.ts.map +1 -0
- package/dist/core/provider-operations.js +171 -0
- package/dist/core/provider-operations.js.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/migrate/model-taxonomy.d.ts +32 -0
- package/dist/migrate/model-taxonomy.d.ts.map +1 -1
- package/dist/migrate/model-taxonomy.js +59 -0
- package/dist/migrate/model-taxonomy.js.map +1 -1
- package/dist/visual-plan/application/export-plan.d.ts.map +1 -1
- package/dist/visual-plan/application/export-plan.js +25 -10
- package/dist/visual-plan/application/export-plan.js.map +1 -1
- package/dist/visual-plan/domain/wireframe-theme.d.ts +24 -0
- package/dist/visual-plan/domain/wireframe-theme.d.ts.map +1 -0
- package/dist/visual-plan/domain/wireframe-theme.js +169 -0
- package/dist/visual-plan/domain/wireframe-theme.js.map +1 -0
- package/dist/visual-plan-web/index.css +1 -1
- package/dist/visual-plan-web/index.js +150 -14
- package/package.json +1 -1
|
@@ -7,10 +7,42 @@ export interface ModelResolveResult {
|
|
|
7
7
|
resolved: ResolvedModel | null;
|
|
8
8
|
warning?: string;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* A NAMED model profile — resolved before tier mapping and deliberately
|
|
12
|
+
* ORTHOGONAL to `ModelTier`.
|
|
13
|
+
*
|
|
14
|
+
* Why not a tier: a tier answers "how much capability does this task need",
|
|
15
|
+
* and every consumer maps the closed `ModelTier` union exhaustively
|
|
16
|
+
* (`Record<ModelTier, …>` in model-routing-config.ts). Growing that union to
|
|
17
|
+
* express "this specific model" would compile-break every such map and conflate
|
|
18
|
+
* two different questions. A profile answers "this named model specifically" —
|
|
19
|
+
* so it resolves first and leaves the tier ladder untouched.
|
|
20
|
+
*
|
|
21
|
+
* Why not `if (model === "fable")` next to resolveModel: a one-off branch is a
|
|
22
|
+
* parallel schema that the next named profile has to copy. A table means the
|
|
23
|
+
* second profile is a row, not a rewrite.
|
|
24
|
+
*/
|
|
25
|
+
export interface ModelProfile {
|
|
26
|
+
/** The verified runtime identifier on providers that support it. */
|
|
27
|
+
identifier: string;
|
|
28
|
+
/** Providers that resolve this profile natively. Everything else falls back. */
|
|
29
|
+
supportedProviders: readonly string[];
|
|
30
|
+
/** Tier used for the DISCLOSED fallback on unsupported providers. */
|
|
31
|
+
fallbackTier: ModelTier;
|
|
32
|
+
/** How `identifier` was verified — so a rename is traceable, not archaeology. */
|
|
33
|
+
evidence: string;
|
|
34
|
+
}
|
|
10
35
|
export declare function setTaxonomyOverrides(overrides: Record<string, Record<string, ResolvedModel>> | undefined): void;
|
|
11
36
|
export declare function resolveOpenCodeDefaultModel(): string | undefined;
|
|
12
37
|
export declare function getOpenCodeDefaultModelOverride(): string | undefined;
|
|
13
38
|
export declare function resolveModel(sourceModel: string | undefined, targetProvider: string): ModelResolveResult;
|
|
39
|
+
/** Every named profile, for diagnostics and tests. Read-only view of the table. */
|
|
40
|
+
export declare function listModelProfiles(): ReadonlyArray<{
|
|
41
|
+
name: string;
|
|
42
|
+
profile: ModelProfile;
|
|
43
|
+
}>;
|
|
44
|
+
/** True when `targetProvider` resolves `name` natively (vs. taking a disclosed fallback). */
|
|
45
|
+
export declare function providerSupportsProfile(name: string, targetProvider: string): boolean;
|
|
14
46
|
export declare function resolveProviderDefaultModel(targetProvider: string): ResolvedModel | null;
|
|
15
47
|
export declare function rewriteConfiguredModelReferences(content: string, targetProvider: string): string;
|
|
16
48
|
//# sourceMappingURL=model-taxonomy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-taxonomy.d.ts","sourceRoot":"","sources":["../../src/migrate/model-taxonomy.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"model-taxonomy.d.ts","sourceRoot":"","sources":["../../src/migrate/model-taxonomy.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC5B,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,qEAAqE;IACrE,YAAY,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAC;CACjB;AAwDD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAE/G;AAED,wBAAgB,2BAA2B,IAAI,MAAM,GAAG,SAAS,CAEhE;AAED,wBAAgB,+BAA+B,IAAI,MAAM,GAAG,SAAS,CAEpE;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,cAAc,EAAE,MAAM,GAAG,kBAAkB,CAiCxG;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,IAAI,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAE1F;AAED,6FAA6F;AAC7F,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAErF;AAED,wBAAgB,2BAA2B,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAExF;AAED,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAKhG"}
|
|
@@ -5,6 +5,51 @@ const SOURCE_TIER_MAP = {
|
|
|
5
5
|
sonnet: "balanced",
|
|
6
6
|
haiku: "light",
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Named profiles, keyed by the string that appears in frontmatter (`model: fable`).
|
|
10
|
+
*
|
|
11
|
+
* The identifier lives in exactly one place: a model rename is a one-line edit
|
|
12
|
+
* here, not a grep across converters.
|
|
13
|
+
*/
|
|
14
|
+
const NAMED_PROFILES = {
|
|
15
|
+
fable: {
|
|
16
|
+
identifier: "claude-fable-5",
|
|
17
|
+
// Claude Code resolves Claude model ids natively. Every other target in
|
|
18
|
+
// ProviderType is a different vendor's host: asserting they can run a
|
|
19
|
+
// Claude model would be an over-claim, so they take the disclosed fallback.
|
|
20
|
+
supportedProviders: ["claude-code"],
|
|
21
|
+
fallbackTier: "heavy",
|
|
22
|
+
evidence: "claude-api skill model table (cached 2026-06-24) + its shared/models.md — exact id, no date suffix",
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a named profile for a target provider.
|
|
27
|
+
*
|
|
28
|
+
* Two honest outcomes, never a third: the provider supports the profile and gets
|
|
29
|
+
* the verified identifier, or it does not and gets a fallback that SAYS SO.
|
|
30
|
+
* Silently substituting a different model would mean a skill that asked for a
|
|
31
|
+
* specific model quietly ran on another one.
|
|
32
|
+
*/
|
|
33
|
+
function resolveNamedProfile(name, profile, targetProvider) {
|
|
34
|
+
if (profile.supportedProviders.includes(targetProvider)) {
|
|
35
|
+
return { resolved: { model: profile.identifier } };
|
|
36
|
+
}
|
|
37
|
+
const fallback = userOverrides?.[targetProvider]?.[profile.fallbackTier];
|
|
38
|
+
if (fallback) {
|
|
39
|
+
return {
|
|
40
|
+
resolved: fallback,
|
|
41
|
+
warning: `Model profile "${name}" (${profile.identifier}) is not available on ${targetProvider} — ` +
|
|
42
|
+
`falling back to the configured "${profile.fallbackTier}" model "${fallback.model}". ` +
|
|
43
|
+
`This is a substitution, not an equivalent.`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
resolved: null,
|
|
48
|
+
warning: `Model profile "${name}" (${profile.identifier}) is not available on ${targetProvider}, ` +
|
|
49
|
+
`and no "${profile.fallbackTier}" model is configured for it — the target will inherit its default. ` +
|
|
50
|
+
`To pin one, set modelRouting.providers.${targetProvider}.tiers.${profile.fallbackTier} in .meowkit.config.json.`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
8
53
|
let userOverrides;
|
|
9
54
|
export function setTaxonomyOverrides(overrides) {
|
|
10
55
|
userOverrides = overrides;
|
|
@@ -27,6 +72,12 @@ export function resolveModel(sourceModel, targetProvider) {
|
|
|
27
72
|
const trimmed = sourceModel.trim();
|
|
28
73
|
if (!trimmed || trimmed === "inherit")
|
|
29
74
|
return { resolved: null };
|
|
75
|
+
// Named profiles resolve BEFORE tier mapping: they name a specific model, which
|
|
76
|
+
// the tier ladder cannot express. Keeping this ahead of SOURCE_TIER_MAP is what
|
|
77
|
+
// makes the profile tier-orthogonal rather than a fourth tier.
|
|
78
|
+
const profile = NAMED_PROFILES[trimmed];
|
|
79
|
+
if (profile)
|
|
80
|
+
return resolveNamedProfile(trimmed, profile, targetProvider);
|
|
30
81
|
const tier = SOURCE_TIER_MAP[trimmed];
|
|
31
82
|
if (!tier) {
|
|
32
83
|
return { resolved: null, warning: `Unknown model "${trimmed}" — not in taxonomy, commented out` };
|
|
@@ -42,6 +93,14 @@ export function resolveModel(sourceModel, targetProvider) {
|
|
|
42
93
|
warning: `No configured ${targetProvider} model for source tier "${trimmed}" — target will inherit its default`,
|
|
43
94
|
};
|
|
44
95
|
}
|
|
96
|
+
/** Every named profile, for diagnostics and tests. Read-only view of the table. */
|
|
97
|
+
export function listModelProfiles() {
|
|
98
|
+
return Object.entries(NAMED_PROFILES).map(([name, profile]) => ({ name, profile }));
|
|
99
|
+
}
|
|
100
|
+
/** True when `targetProvider` resolves `name` natively (vs. taking a disclosed fallback). */
|
|
101
|
+
export function providerSupportsProfile(name, targetProvider) {
|
|
102
|
+
return NAMED_PROFILES[name]?.supportedProviders.includes(targetProvider) ?? false;
|
|
103
|
+
}
|
|
45
104
|
export function resolveProviderDefaultModel(targetProvider) {
|
|
46
105
|
return userOverrides?.[targetProvider]?.default ?? null;
|
|
47
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-taxonomy.js","sourceRoot":"","sources":["../../src/migrate/model-taxonomy.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,4FAA4F;AAc5F,MAAM,eAAe,GAA8B;IAClD,IAAI,EAAE,OAAO;IACb,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,OAAO;CACd,CAAC;AAEF,IAAI,aAAwE,CAAC;AAE7E,MAAM,UAAU,oBAAoB,CAAC,SAAoE;IACxG,aAAa,GAAG,SAAS,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,2BAA2B;IAC1C,OAAO,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,+BAA+B;IAC9C,OAAO,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,WAA+B,EAAE,cAAsB;IACnF,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjF,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO;YACN,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,yCAAyC,OAAO,WAAW,GAAG;SACvE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAEjE,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,OAAO,oCAAoC,EAAE,CAAC;IACnG,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC,cAAc,CAAC,CAAC;IACpD,IAAI,WAAW,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,QAAQ;YAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO;QACN,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,iBAAiB,cAAc,2BAA2B,OAAO,qCAAqC;KAC/G,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,cAAsB;IACjE,OAAO,aAAa,EAAE,CAAC,cAAc,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,OAAe,EAAE,cAAsB;IACvF,OAAO,OAAO,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,OAAO,EAAE,MAAc,EAAE,QAAgB,EAAE,EAAE;QAC3G,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC,CAAC,QAAQ,CAAC;QAC/E,OAAO,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"model-taxonomy.js","sourceRoot":"","sources":["../../src/migrate/model-taxonomy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-plan.d.ts","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"export-plan.d.ts","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAoDD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAS5D"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { readArtifactRaw } from "../infrastructure/visual-plan-repository.js";
|
|
13
13
|
import { sanitizeWireframeHtml } from "../infrastructure/wireframe-sanitizer.js";
|
|
14
14
|
import { computeCoverage } from "../domain/coverage.js";
|
|
15
|
+
import { WIREFRAME_THEME_CSS } from "../domain/wireframe-theme.js";
|
|
15
16
|
import { VisualPlanSchema } from "../domain/schemas.js";
|
|
16
17
|
/** HTML-entity-encode a plan-sourced string for safe text/attribute placement. */
|
|
17
18
|
function esc(s) {
|
|
@@ -22,11 +23,11 @@ function coverageSection(plan) {
|
|
|
22
23
|
const rows = plan.uiCoverage.surfaces
|
|
23
24
|
.flatMap((s) => s.states.map((st) => `<tr><td>${esc(s.label ?? s.id)}</td><td>${esc(st.label ?? st.id)}</td><td>${st.frameIds.length > 0 ? "framed" : st.omitted ? esc(st.omitted.reason) : "unresolved"}</td></tr>`))
|
|
24
25
|
.join("");
|
|
25
|
-
return `<h2>Coverage</h2><p class="vp-sum">${summary.resolved} resolved · ${summary.planned} planned · ${summary.omitted} omitted · ${summary.unresolved} unresolved</p><table><thead><tr><th>Surface</th><th>State</th><th>Closure</th></tr></thead><tbody>${rows}</tbody></table>`;
|
|
26
|
+
return `<h2>Coverage</h2><p class="vp-sum">${summary.resolved} resolved · ${summary.planned} planned · ${summary.omitted} omitted · ${summary.unresolved} unresolved</p><table class="vp-coverage-table"><thead><tr><th>Surface</th><th>State</th><th>Closure</th></tr></thead><tbody>${rows}</tbody></table>`;
|
|
26
27
|
}
|
|
27
28
|
function framesSection(plan) {
|
|
28
29
|
const cards = plan.canvas.frames
|
|
29
|
-
.map((f) => `<article class="vp-frame"><header><strong>${esc(f.label)}</strong> <span class="vp-badge">${esc(f.surface)} · ${esc(f.changeMode)}</span></header><div class="wf-root">${sanitizeWireframeHtml(f.wireframe.html)}</div></article>`)
|
|
30
|
+
.map((f) => `<article class="vp-frame" data-surface="${esc(f.surface)}"><header><strong>${esc(f.label)}</strong> <span class="vp-badge">${esc(f.surface)} · ${esc(f.changeMode)}</span></header><div class="vp-frame-body"><div class="wf-root">${sanitizeWireframeHtml(f.wireframe.html)}</div></div></article>`)
|
|
30
31
|
.join("");
|
|
31
32
|
return `<h2>Frames</h2><div class="vp-frames">${cards}</div>`;
|
|
32
33
|
}
|
|
@@ -36,14 +37,28 @@ function docsSection(plan) {
|
|
|
36
37
|
const items = plan.documentBlocks.map((b) => `<li>${b.title ? `<strong>${esc(b.title)}:</strong> ` : ""}${esc(b.body)}</li>`).join("");
|
|
37
38
|
return `<h2>Mechanics</h2><ul>${items}</ul>`;
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.
|
|
40
|
+
/**
|
|
41
|
+
* Page shell CSS; the wireframe look itself comes from the SHARED theme.
|
|
42
|
+
* Shell selectors are scoped (`body>h2`, `.vp-coverage-table`) so they never
|
|
43
|
+
* leak into `.wf-root` wireframe content — parity with the studio. Frame
|
|
44
|
+
* bodies are auto-height (plan content is never clipped); widths follow the
|
|
45
|
+
* surface footprint so mobile frames keep their studio aspect.
|
|
46
|
+
*/
|
|
47
|
+
const PAGE_STYLE = `body{font:14px/1.5 system-ui,sans-serif;margin:0;padding:24px;background:#eef0f3;color:#1c2430}
|
|
48
|
+
body>h1{margin:0 0 4px}body>h2{margin:24px 0 8px;border-bottom:1px solid #d7dbe0;padding-bottom:4px}
|
|
49
|
+
.vp-coverage-table{border-collapse:collapse;width:100%}
|
|
50
|
+
.vp-coverage-table th,.vp-coverage-table td{border:1px solid #d7dbe0;padding:4px 8px;text-align:left;font-size:13px}
|
|
51
|
+
.vp-sum{color:#64707d}.vp-frames{display:flex;flex-wrap:wrap;gap:28px;align-items:flex-start}
|
|
52
|
+
.vp-frame{width:420px;max-width:100%}
|
|
53
|
+
.vp-frame[data-surface="mobile"]{width:300px}
|
|
54
|
+
.vp-frame[data-surface="popover"]{width:360px}
|
|
55
|
+
.vp-frame header{padding:0 2px 6px;font-size:13px}
|
|
56
|
+
.vp-frame-body{border:1.5px solid #d3d9e0;border-radius:14px;overflow:hidden;box-shadow:0 1px 3px rgba(16,22,32,.06)}
|
|
57
|
+
.vp-frame-body .wf-root{height:auto;min-height:120px}
|
|
58
|
+
.vp-frame[data-surface="mobile"] .vp-frame-body{border-radius:30px}
|
|
59
|
+
.vp-badge{color:#64707d;font-size:11px}
|
|
60
|
+
@media (prefers-color-scheme: dark){body{background:#0b0e13;color:#e8edf3}body>h2{border-color:#263041}.vp-frame-body{border-color:#2c3646}}`;
|
|
61
|
+
const STYLE = `${PAGE_STYLE}\n${WIREFRAME_THEME_CSS}`;
|
|
47
62
|
/** Build the self-contained plan.html string from the artifact at `planDir`. */
|
|
48
63
|
export function exportPlanHtml(planDir) {
|
|
49
64
|
const read = readArtifactRaw(planDir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export-plan.js","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAmB,MAAM,sBAAsB,CAAC;AAQzE,kFAAkF;AAClF,SAAS,GAAG,CAAC,CAAS;IACrB,OAAO,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAW,CAAC,CAAC;AAC7H,CAAC;AAED,SAAS,eAAe,CAAC,IAAgB;IACxC,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ;SACnC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,YAAY,CAAC,CAAC;SACrN,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,OAAO,sCAAsC,OAAO,CAAC,QAAQ,eAAe,OAAO,CAAC,OAAO,cAAc,OAAO,CAAC,OAAO,cAAc,OAAO,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"export-plan.js","sourceRoot":"","sources":["../../../src/visual-plan/application/export-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared wireframe theme — the SINGLE source of truth for how sanitized
|
|
3
|
+
* `.wf-*` semantic HTML looks, consumed by BOTH renderers (same pattern as
|
|
4
|
+
* sanitizer-config.ts): the studio injects it at boot, `export --format html`
|
|
5
|
+
* embeds it in the exported page. One theme, two surfaces, no drift.
|
|
6
|
+
*
|
|
7
|
+
* Visual language follows the agent-native plan renderer (ISC), re-expressed
|
|
8
|
+
* for MeowKit's vocabulary: a scoped ink/paper/card/accent token palette with
|
|
9
|
+
* soft variants, hand-drawn font by DEFAULT (sketchy is the primary register;
|
|
10
|
+
* `[data-style="clean"]` swaps to the sans stack), 1.4px strokes, 9px radii,
|
|
11
|
+
* and a `[data-rough-ready]` hook that hides crisp borders once the rough.js
|
|
12
|
+
* overlay has redrawn them so outlines are never doubled.
|
|
13
|
+
*
|
|
14
|
+
* Pure data — no DOM, no imports — so the Node exporter and the Vite bundle
|
|
15
|
+
* can both consume it.
|
|
16
|
+
*/
|
|
17
|
+
export declare const WIREFRAME_THEME_CSS = "\n/* ---- tokens (scoped to .wf-root; light + dark) ---- */\n.wf-root {\n --wf-ink: #222b38; --wf-ink-soft: #6b7684; --wf-line: #d3d9e0; --wf-sketch: #94a0ad;\n --wf-paper: #ffffff; --wf-card: #f6f8fa;\n --wf-accent: #4c6ef5; --wf-accent-fg: #ffffff; --wf-accent-soft: rgba(76, 110, 245, 0.12);\n --wf-warn: #d64545; --wf-warn-soft: rgba(214, 69, 69, 0.12); --wf-ok: #2f9e63;\n --wf-radius: 9px; --wf-stroke: 1.4px;\n --wf-font-hand: \"Architects Daughter\", \"Comic Sans MS\", \"Bradley Hand\", \"Marker Felt\", cursive;\n --wf-font-clean: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif;\n --wf-font: var(--wf-font-hand);\n background: var(--wf-paper); color: var(--wf-ink);\n font-family: var(--wf-font); font-size: 14px; line-height: 1.45;\n padding: 14px; height: 100%; overflow: hidden; position: relative;\n}\n.wf-root, .wf-root * { box-sizing: border-box; min-width: 0; }\n[data-style=\"clean\"] .wf-root { --wf-font: var(--wf-font-clean); }\n@media (prefers-color-scheme: dark) {\n .wf-root {\n --wf-ink: #e9edf3; --wf-ink-soft: #93a0ae; --wf-line: #2c3646; --wf-sketch: #5d6a7a;\n --wf-paper: #171d26; --wf-card: #1e2733;\n --wf-accent: #7c9aff; --wf-accent-fg: #10141c; --wf-accent-soft: rgba(124, 154, 255, 0.16);\n --wf-warn: #ef7070; --wf-warn-soft: rgba(239, 112, 112, 0.16); --wf-ok: #52c184;\n }\n}\n\n/* ---- bare semantic elements ---- */\n.wf-root h1 { font-size: 21px; font-weight: 700; line-height: 1.15; margin: 0 0 8px; }\n.wf-root h2 { font-size: 17px; font-weight: 700; line-height: 1.2; margin: 0 0 6px; }\n.wf-root h3, .wf-root h4, .wf-root h5, .wf-root h6 { font-size: 14px; font-weight: 700; margin: 0 0 4px; }\n.wf-root p { margin: 0 0 8px; }\n.wf-root small { color: var(--wf-ink-soft); font-size: 12.5px; }\n.wf-root a { color: var(--wf-accent); text-decoration: none; }\n.wf-root hr { border: 0; border-top: var(--wf-stroke) solid var(--wf-line); margin: 10px 0; }\n.wf-root ul, .wf-root ol { margin: 0 0 8px; padding-left: 1.2em; }\n.wf-root li { margin: 2px 0; }\n.wf-root label { font-size: 12.5px; font-weight: 700; color: var(--wf-ink-soft); }\n.wf-root blockquote { margin: 0 0 8px; padding: 6px 12px; border-left: 3px solid var(--wf-line); color: var(--wf-ink-soft); }\n.wf-root code, .wf-root pre { font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; background: var(--wf-card); border-radius: 5px; }\n.wf-root pre { padding: 8px 10px; overflow: auto; margin: 0 0 8px; }\n.wf-root table { width: 100%; border-collapse: collapse; margin: 0 0 8px; font-size: 13px; }\n.wf-root th { text-align: left; font-weight: 700; border-bottom: var(--wf-stroke) solid var(--wf-line); padding: 6px 8px; }\n.wf-root td { padding: 6px 8px; border-bottom: 1px solid var(--wf-line); }\n.wf-root figure { margin: 0 0 8px; }\n.wf-root figcaption { font-size: 12.5px; color: var(--wf-ink-soft); }\n\n/* ---- structure ---- */\n.wf-root .wf-screen { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }\n.wf-root .wf-topbar, .wf-root header { display: flex; align-items: center; gap: 10px; border-bottom: var(--wf-stroke) solid var(--wf-line); padding-bottom: 8px; }\n.wf-root .wf-topbar :is(h1, h2, h3, p), .wf-root header :is(h1, h2, h3, p) { margin: 0; }\n.wf-root .wf-content, .wf-root main { display: flex; flex-direction: column; gap: 10px; flex: 1; min-height: 0; }\n.wf-root footer, .wf-root .wf-footer { display: flex; align-items: center; gap: 10px; border-top: var(--wf-stroke) solid var(--wf-line); padding-top: 8px; margin-top: auto; }\n.wf-root nav, .wf-root .wf-nav { display: flex; align-items: center; gap: 12px; }\n.wf-root aside, .wf-root .wf-sidebar { display: flex; flex-direction: column; gap: 8px; border-right: var(--wf-stroke) solid var(--wf-line); padding-right: 10px; }\n.wf-root .wf-row { display: flex; align-items: center; gap: 8px; }\n.wf-root .wf-col { display: flex; flex-direction: column; gap: 8px; }\n.wf-root .wf-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }\n.wf-root .wf-spacer { flex: 1; }\n\n/* ---- surfaces & controls ---- */\n.wf-root .wf-card, .wf-root .wf-box, .wf-root .wf-panel {\n background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);\n border-radius: var(--wf-radius); padding: 12px;\n}\n.wf-root .wf-button {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n font: inherit; font-weight: 700; color: var(--wf-ink); background: var(--wf-paper);\n border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);\n padding: 7px 14px; text-decoration: none; cursor: default; width: fit-content;\n}\n.wf-root .wf-button:is(.primary, .wf-primary) {\n background: var(--wf-accent); border-color: var(--wf-accent); color: var(--wf-accent-fg);\n}\n.wf-root .wf-input, .wf-root .wf-field, .wf-root .wf-select, .wf-root .wf-textarea {\n display: flex; align-items: center; min-height: 34px; width: 100%;\n color: var(--wf-ink-soft); background: var(--wf-card);\n border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius); padding: 6px 10px;\n}\n.wf-root .wf-textarea { min-height: 64px; align-items: flex-start; }\n.wf-root .wf-form { display: flex; flex-direction: column; gap: 8px; }\n.wf-root .wf-checkbox, .wf-root .wf-radio {\n display: inline-block; width: 15px; height: 15px; flex: 0 0 auto;\n border: var(--wf-stroke) solid var(--wf-sketch); background: var(--wf-paper);\n}\n.wf-root .wf-checkbox { border-radius: 4px; }\n.wf-root .wf-radio { border-radius: 999px; }\n\n/* ---- chips, badges, status ---- */\n.wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag) {\n display: inline-flex; align-items: center; gap: 5px; width: fit-content; max-width: 100%;\n border: var(--wf-stroke) solid var(--wf-line); border-radius: 999px;\n padding: 2px 10px; font-size: 12.5px; background: var(--wf-paper);\n}\n.wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag).accent { border-color: var(--wf-accent); color: var(--wf-accent); background: var(--wf-accent-soft); }\n.wf-root .wf-muted { color: var(--wf-ink-soft); }\n.wf-root .wf-hint { color: var(--wf-ink-soft); font-size: 12.5px; }\n.wf-root .wf-error { color: var(--wf-warn); }\n.wf-root :is(.wf-alert, .wf-banner) { background: var(--wf-warn-soft); border: var(--wf-stroke) solid var(--wf-warn); border-radius: var(--wf-radius); padding: 8px 12px; color: var(--wf-warn); }\n\n/* ---- lists ---- */\n.wf-root .wf-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; }\n.wf-root .wf-list-item {\n display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0;\n background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);\n border-radius: var(--wf-radius); padding: 9px 12px;\n}\n\n/* ---- media & placeholders ---- */\n.wf-root :is(.wf-image, .wf-img, .wf-media) {\n display: block; min-height: 84px; background: var(--wf-card);\n background-image: linear-gradient(to top right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%),\n linear-gradient(to bottom right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%);\n border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);\n}\n.wf-root .wf-avatar {\n display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;\n width: 32px; height: 32px; border-radius: 999px; font-size: 12px; font-weight: 700;\n background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);\n}\n.wf-root .wf-loading {\n display: block; height: 12px; width: 70%; border-radius: 999px; border: 0;\n background: var(--wf-line);\n}\n@media (prefers-reduced-motion: no-preference) {\n .wf-root .wf-loading { animation: wf-pulse 1.6s ease-in-out infinite; }\n}\n@keyframes wf-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }\n\n/* ---- rough handoff: once the overlay has drawn hand-drawn outlines, hide the\n crisp borders it replaced (fills and text stay) so nothing is doubled. ---- */\n[data-rough-ready=\"true\"] .wf-root :is(\n .wf-button, .wf-input, .wf-field, .wf-select, .wf-textarea,\n .wf-card, .wf-box, .wf-panel, .wf-badge, .wf-chip, .wf-pill, .wf-tag,\n .wf-list-item, .wf-avatar, .wf-image, .wf-img, .wf-media, .wf-alert, .wf-banner,\n .wf-checkbox, .wf-radio, hr\n) { border-color: transparent !important; }\n";
|
|
18
|
+
/**
|
|
19
|
+
* Class names the theme MUST style (superset of the generation contract's
|
|
20
|
+
* common vocabulary). The coverage test asserts each appears in the CSS so a
|
|
21
|
+
* generated artifact can never render a bare, unstyled block again.
|
|
22
|
+
*/
|
|
23
|
+
export declare const WIREFRAME_THEME_CLASSES: readonly string[];
|
|
24
|
+
//# sourceMappingURL=wireframe-theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wireframe-theme.d.ts","sourceRoot":"","sources":["../../../src/visual-plan/domain/wireframe-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,mBAAmB,2uQAwI/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EASpD,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared wireframe theme — the SINGLE source of truth for how sanitized
|
|
3
|
+
* `.wf-*` semantic HTML looks, consumed by BOTH renderers (same pattern as
|
|
4
|
+
* sanitizer-config.ts): the studio injects it at boot, `export --format html`
|
|
5
|
+
* embeds it in the exported page. One theme, two surfaces, no drift.
|
|
6
|
+
*
|
|
7
|
+
* Visual language follows the agent-native plan renderer (ISC), re-expressed
|
|
8
|
+
* for MeowKit's vocabulary: a scoped ink/paper/card/accent token palette with
|
|
9
|
+
* soft variants, hand-drawn font by DEFAULT (sketchy is the primary register;
|
|
10
|
+
* `[data-style="clean"]` swaps to the sans stack), 1.4px strokes, 9px radii,
|
|
11
|
+
* and a `[data-rough-ready]` hook that hides crisp borders once the rough.js
|
|
12
|
+
* overlay has redrawn them so outlines are never doubled.
|
|
13
|
+
*
|
|
14
|
+
* Pure data — no DOM, no imports — so the Node exporter and the Vite bundle
|
|
15
|
+
* can both consume it.
|
|
16
|
+
*/
|
|
17
|
+
export const WIREFRAME_THEME_CSS = `
|
|
18
|
+
/* ---- tokens (scoped to .wf-root; light + dark) ---- */
|
|
19
|
+
.wf-root {
|
|
20
|
+
--wf-ink: #222b38; --wf-ink-soft: #6b7684; --wf-line: #d3d9e0; --wf-sketch: #94a0ad;
|
|
21
|
+
--wf-paper: #ffffff; --wf-card: #f6f8fa;
|
|
22
|
+
--wf-accent: #4c6ef5; --wf-accent-fg: #ffffff; --wf-accent-soft: rgba(76, 110, 245, 0.12);
|
|
23
|
+
--wf-warn: #d64545; --wf-warn-soft: rgba(214, 69, 69, 0.12); --wf-ok: #2f9e63;
|
|
24
|
+
--wf-radius: 9px; --wf-stroke: 1.4px;
|
|
25
|
+
--wf-font-hand: "Architects Daughter", "Comic Sans MS", "Bradley Hand", "Marker Felt", cursive;
|
|
26
|
+
--wf-font-clean: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
27
|
+
--wf-font: var(--wf-font-hand);
|
|
28
|
+
background: var(--wf-paper); color: var(--wf-ink);
|
|
29
|
+
font-family: var(--wf-font); font-size: 14px; line-height: 1.45;
|
|
30
|
+
padding: 14px; height: 100%; overflow: hidden; position: relative;
|
|
31
|
+
}
|
|
32
|
+
.wf-root, .wf-root * { box-sizing: border-box; min-width: 0; }
|
|
33
|
+
[data-style="clean"] .wf-root { --wf-font: var(--wf-font-clean); }
|
|
34
|
+
@media (prefers-color-scheme: dark) {
|
|
35
|
+
.wf-root {
|
|
36
|
+
--wf-ink: #e9edf3; --wf-ink-soft: #93a0ae; --wf-line: #2c3646; --wf-sketch: #5d6a7a;
|
|
37
|
+
--wf-paper: #171d26; --wf-card: #1e2733;
|
|
38
|
+
--wf-accent: #7c9aff; --wf-accent-fg: #10141c; --wf-accent-soft: rgba(124, 154, 255, 0.16);
|
|
39
|
+
--wf-warn: #ef7070; --wf-warn-soft: rgba(239, 112, 112, 0.16); --wf-ok: #52c184;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* ---- bare semantic elements ---- */
|
|
44
|
+
.wf-root h1 { font-size: 21px; font-weight: 700; line-height: 1.15; margin: 0 0 8px; }
|
|
45
|
+
.wf-root h2 { font-size: 17px; font-weight: 700; line-height: 1.2; margin: 0 0 6px; }
|
|
46
|
+
.wf-root h3, .wf-root h4, .wf-root h5, .wf-root h6 { font-size: 14px; font-weight: 700; margin: 0 0 4px; }
|
|
47
|
+
.wf-root p { margin: 0 0 8px; }
|
|
48
|
+
.wf-root small { color: var(--wf-ink-soft); font-size: 12.5px; }
|
|
49
|
+
.wf-root a { color: var(--wf-accent); text-decoration: none; }
|
|
50
|
+
.wf-root hr { border: 0; border-top: var(--wf-stroke) solid var(--wf-line); margin: 10px 0; }
|
|
51
|
+
.wf-root ul, .wf-root ol { margin: 0 0 8px; padding-left: 1.2em; }
|
|
52
|
+
.wf-root li { margin: 2px 0; }
|
|
53
|
+
.wf-root label { font-size: 12.5px; font-weight: 700; color: var(--wf-ink-soft); }
|
|
54
|
+
.wf-root blockquote { margin: 0 0 8px; padding: 6px 12px; border-left: 3px solid var(--wf-line); color: var(--wf-ink-soft); }
|
|
55
|
+
.wf-root code, .wf-root pre { font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; background: var(--wf-card); border-radius: 5px; }
|
|
56
|
+
.wf-root pre { padding: 8px 10px; overflow: auto; margin: 0 0 8px; }
|
|
57
|
+
.wf-root table { width: 100%; border-collapse: collapse; margin: 0 0 8px; font-size: 13px; }
|
|
58
|
+
.wf-root th { text-align: left; font-weight: 700; border-bottom: var(--wf-stroke) solid var(--wf-line); padding: 6px 8px; }
|
|
59
|
+
.wf-root td { padding: 6px 8px; border-bottom: 1px solid var(--wf-line); }
|
|
60
|
+
.wf-root figure { margin: 0 0 8px; }
|
|
61
|
+
.wf-root figcaption { font-size: 12.5px; color: var(--wf-ink-soft); }
|
|
62
|
+
|
|
63
|
+
/* ---- structure ---- */
|
|
64
|
+
.wf-root .wf-screen { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }
|
|
65
|
+
.wf-root .wf-topbar, .wf-root header { display: flex; align-items: center; gap: 10px; border-bottom: var(--wf-stroke) solid var(--wf-line); padding-bottom: 8px; }
|
|
66
|
+
.wf-root .wf-topbar :is(h1, h2, h3, p), .wf-root header :is(h1, h2, h3, p) { margin: 0; }
|
|
67
|
+
.wf-root .wf-content, .wf-root main { display: flex; flex-direction: column; gap: 10px; flex: 1; min-height: 0; }
|
|
68
|
+
.wf-root footer, .wf-root .wf-footer { display: flex; align-items: center; gap: 10px; border-top: var(--wf-stroke) solid var(--wf-line); padding-top: 8px; margin-top: auto; }
|
|
69
|
+
.wf-root nav, .wf-root .wf-nav { display: flex; align-items: center; gap: 12px; }
|
|
70
|
+
.wf-root aside, .wf-root .wf-sidebar { display: flex; flex-direction: column; gap: 8px; border-right: var(--wf-stroke) solid var(--wf-line); padding-right: 10px; }
|
|
71
|
+
.wf-root .wf-row { display: flex; align-items: center; gap: 8px; }
|
|
72
|
+
.wf-root .wf-col { display: flex; flex-direction: column; gap: 8px; }
|
|
73
|
+
.wf-root .wf-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
|
|
74
|
+
.wf-root .wf-spacer { flex: 1; }
|
|
75
|
+
|
|
76
|
+
/* ---- surfaces & controls ---- */
|
|
77
|
+
.wf-root .wf-card, .wf-root .wf-box, .wf-root .wf-panel {
|
|
78
|
+
background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);
|
|
79
|
+
border-radius: var(--wf-radius); padding: 12px;
|
|
80
|
+
}
|
|
81
|
+
.wf-root .wf-button {
|
|
82
|
+
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
|
|
83
|
+
font: inherit; font-weight: 700; color: var(--wf-ink); background: var(--wf-paper);
|
|
84
|
+
border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);
|
|
85
|
+
padding: 7px 14px; text-decoration: none; cursor: default; width: fit-content;
|
|
86
|
+
}
|
|
87
|
+
.wf-root .wf-button:is(.primary, .wf-primary) {
|
|
88
|
+
background: var(--wf-accent); border-color: var(--wf-accent); color: var(--wf-accent-fg);
|
|
89
|
+
}
|
|
90
|
+
.wf-root .wf-input, .wf-root .wf-field, .wf-root .wf-select, .wf-root .wf-textarea {
|
|
91
|
+
display: flex; align-items: center; min-height: 34px; width: 100%;
|
|
92
|
+
color: var(--wf-ink-soft); background: var(--wf-card);
|
|
93
|
+
border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius); padding: 6px 10px;
|
|
94
|
+
}
|
|
95
|
+
.wf-root .wf-textarea { min-height: 64px; align-items: flex-start; }
|
|
96
|
+
.wf-root .wf-form { display: flex; flex-direction: column; gap: 8px; }
|
|
97
|
+
.wf-root .wf-checkbox, .wf-root .wf-radio {
|
|
98
|
+
display: inline-block; width: 15px; height: 15px; flex: 0 0 auto;
|
|
99
|
+
border: var(--wf-stroke) solid var(--wf-sketch); background: var(--wf-paper);
|
|
100
|
+
}
|
|
101
|
+
.wf-root .wf-checkbox { border-radius: 4px; }
|
|
102
|
+
.wf-root .wf-radio { border-radius: 999px; }
|
|
103
|
+
|
|
104
|
+
/* ---- chips, badges, status ---- */
|
|
105
|
+
.wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag) {
|
|
106
|
+
display: inline-flex; align-items: center; gap: 5px; width: fit-content; max-width: 100%;
|
|
107
|
+
border: var(--wf-stroke) solid var(--wf-line); border-radius: 999px;
|
|
108
|
+
padding: 2px 10px; font-size: 12.5px; background: var(--wf-paper);
|
|
109
|
+
}
|
|
110
|
+
.wf-root :is(.wf-badge, .wf-chip, .wf-pill, .wf-tag).accent { border-color: var(--wf-accent); color: var(--wf-accent); background: var(--wf-accent-soft); }
|
|
111
|
+
.wf-root .wf-muted { color: var(--wf-ink-soft); }
|
|
112
|
+
.wf-root .wf-hint { color: var(--wf-ink-soft); font-size: 12.5px; }
|
|
113
|
+
.wf-root .wf-error { color: var(--wf-warn); }
|
|
114
|
+
.wf-root :is(.wf-alert, .wf-banner) { background: var(--wf-warn-soft); border: var(--wf-stroke) solid var(--wf-warn); border-radius: var(--wf-radius); padding: 8px 12px; color: var(--wf-warn); }
|
|
115
|
+
|
|
116
|
+
/* ---- lists ---- */
|
|
117
|
+
.wf-root .wf-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
|
|
118
|
+
.wf-root .wf-list-item {
|
|
119
|
+
display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0;
|
|
120
|
+
background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);
|
|
121
|
+
border-radius: var(--wf-radius); padding: 9px 12px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* ---- media & placeholders ---- */
|
|
125
|
+
.wf-root :is(.wf-image, .wf-img, .wf-media) {
|
|
126
|
+
display: block; min-height: 84px; background: var(--wf-card);
|
|
127
|
+
background-image: linear-gradient(to top right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%),
|
|
128
|
+
linear-gradient(to bottom right, transparent 49.55%, var(--wf-line) 49.55%, var(--wf-line) 50.45%, transparent 50.45%);
|
|
129
|
+
border: var(--wf-stroke) solid var(--wf-line); border-radius: var(--wf-radius);
|
|
130
|
+
}
|
|
131
|
+
.wf-root .wf-avatar {
|
|
132
|
+
display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
|
|
133
|
+
width: 32px; height: 32px; border-radius: 999px; font-size: 12px; font-weight: 700;
|
|
134
|
+
background: var(--wf-card); border: var(--wf-stroke) solid var(--wf-line);
|
|
135
|
+
}
|
|
136
|
+
.wf-root .wf-loading {
|
|
137
|
+
display: block; height: 12px; width: 70%; border-radius: 999px; border: 0;
|
|
138
|
+
background: var(--wf-line);
|
|
139
|
+
}
|
|
140
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
141
|
+
.wf-root .wf-loading { animation: wf-pulse 1.6s ease-in-out infinite; }
|
|
142
|
+
}
|
|
143
|
+
@keyframes wf-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
|
|
144
|
+
|
|
145
|
+
/* ---- rough handoff: once the overlay has drawn hand-drawn outlines, hide the
|
|
146
|
+
crisp borders it replaced (fills and text stay) so nothing is doubled. ---- */
|
|
147
|
+
[data-rough-ready="true"] .wf-root :is(
|
|
148
|
+
.wf-button, .wf-input, .wf-field, .wf-select, .wf-textarea,
|
|
149
|
+
.wf-card, .wf-box, .wf-panel, .wf-badge, .wf-chip, .wf-pill, .wf-tag,
|
|
150
|
+
.wf-list-item, .wf-avatar, .wf-image, .wf-img, .wf-media, .wf-alert, .wf-banner,
|
|
151
|
+
.wf-checkbox, .wf-radio, hr
|
|
152
|
+
) { border-color: transparent !important; }
|
|
153
|
+
`;
|
|
154
|
+
/**
|
|
155
|
+
* Class names the theme MUST style (superset of the generation contract's
|
|
156
|
+
* common vocabulary). The coverage test asserts each appears in the CSS so a
|
|
157
|
+
* generated artifact can never render a bare, unstyled block again.
|
|
158
|
+
*/
|
|
159
|
+
export const WIREFRAME_THEME_CLASSES = [
|
|
160
|
+
"wf-screen", "wf-topbar", "wf-content", "wf-footer", "wf-nav", "wf-sidebar",
|
|
161
|
+
"wf-row", "wf-col", "wf-grid", "wf-spacer",
|
|
162
|
+
"wf-card", "wf-box", "wf-panel", "wf-button", "wf-input", "wf-field", "wf-select", "wf-textarea", "wf-form",
|
|
163
|
+
"wf-checkbox", "wf-radio",
|
|
164
|
+
"wf-badge", "wf-chip", "wf-pill", "wf-tag",
|
|
165
|
+
"wf-muted", "wf-hint", "wf-error", "wf-alert", "wf-banner",
|
|
166
|
+
"wf-list", "wf-list-item",
|
|
167
|
+
"wf-image", "wf-img", "wf-media", "wf-avatar", "wf-loading",
|
|
168
|
+
];
|
|
169
|
+
//# sourceMappingURL=wireframe-theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wireframe-theme.js","sourceRoot":"","sources":["../../../src/visual-plan/domain/wireframe-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIlC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACzD,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY;IAC3E,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW;IAC1C,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS;IAC3G,aAAa,EAAE,UAAU;IACzB,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ;IAC1C,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW;IAC1D,SAAS,EAAE,cAAc;IACzB,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY;CAC3D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-ext-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-ext-400-normal.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-400-normal.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--vp-bg: #f4f5f7;--vp-surface: #ffffff;--vp-border: #d7dbe0;--vp-text: #1c2430;--vp-muted: #64707d;--vp-accent: #
|
|
1
|
+
@font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-ext-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-ext-400-normal.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Architects Daughter;font-style:normal;font-display:swap;font-weight:400;src:url(/architects-daughter-latin-400-normal.woff2) format("woff2"),url(/architects-daughter-latin-400-normal.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--vp-bg: #f4f5f7;--vp-canvas: #e9ebef;--vp-grid: rgba(28, 36, 48, .035);--vp-surface: #ffffff;--vp-chrome: rgba(255, 255, 255, .88);--vp-border: #d7dbe0;--vp-text: #1c2430;--vp-muted: #64707d;--vp-accent: #4c6ef5;--vp-warn: #c0392b;--vp-ok: #1f8a4c;--vp-shadow: 0 8px 24px rgba(20, 28, 40, .1)}@media(prefers-color-scheme:dark){:root{--vp-bg: #0b0e13;--vp-canvas: #090c11;--vp-grid: rgba(232, 237, 243, .03);--vp-surface: #141a22;--vp-chrome: rgba(20, 26, 34, .88);--vp-border: #263041;--vp-text: #e8edf3;--vp-muted: #93a1b0;--vp-accent: #7c9aff;--vp-warn: #ef7070;--vp-ok: #52c184;--vp-shadow: 0 8px 24px rgba(0, 0, 0, .45)}}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font-family:system-ui,-apple-system,Segoe UI,sans-serif;background:var(--vp-bg);color:var(--vp-text)}.vp-app{display:flex;flex-direction:column;height:100%}.vp-loading,.vp-error{padding:2rem;color:var(--vp-muted)}.vp-error{color:var(--vp-warn)}.vp-toolbar{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;background:var(--vp-surface);border-bottom:1px solid var(--vp-border)}.vp-toolbar-title{font-weight:600}.vp-toolbar-meta{color:var(--vp-muted);font-size:.85rem}.vp-error-banner{font-size:.75rem;color:#fff;background:var(--vp-warn);padding:.1rem .6rem;border-radius:6px}.vp-save-status{font-size:.75rem;color:var(--vp-muted);padding:.1rem .5rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-save-status[data-state=saving]{color:var(--vp-accent)}.vp-save-status[data-state=stale],.vp-save-status[data-state=error]{color:var(--vp-warn);border-color:var(--vp-warn)}.vp-mode-toggle{font-size:.78rem;padding:.15rem .6rem;border:1px solid var(--vp-border);border-radius:6px;background:var(--vp-surface);color:var(--vp-text);cursor:pointer}.vp-mode-toggle:hover{border-color:var(--vp-accent);color:var(--vp-accent)}.vp-toolbar-review{margin-left:auto;font-size:.8rem;padding:.1rem .5rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-toolbar-review[data-status=approved]{color:var(--vp-ok);border-color:var(--vp-ok)}.vp-body{display:grid;grid-template-columns:1fr 260px 260px;flex:1;min-height:0}.vp-viewport{position:relative;overflow:hidden;outline:none;background-color:var(--vp-canvas);background-image:linear-gradient(var(--vp-grid) 1px,transparent 1px),linear-gradient(90deg,var(--vp-grid) 1px,transparent 1px)}.vp-world{position:absolute;top:0;left:0}@media(prefers-reduced-motion:no-preference){.vp-world{transition:transform 80ms ease-out}}.vp-lane{border:1px dashed color-mix(in srgb,var(--vp-border) 70%,transparent);border-radius:20px;background:color-mix(in srgb,var(--vp-text) 1.5%,transparent)}.vp-lane-label{font-size:1.05rem;font-weight:600;letter-spacing:-.01em;color:var(--vp-text);padding:.7rem 1.2rem 0}.vp-artboard{cursor:pointer}.vp-artboard-caption{position:absolute;bottom:100%;left:2px;padding-bottom:6px;display:flex;align-items:baseline;gap:8px;white-space:nowrap;pointer-events:none}.vp-artboard-title{font-size:13px;font-weight:600;color:var(--vp-text)}.vp-artboard-surface{font-size:11px;color:var(--vp-muted)}.vp-artboard-surface[data-change=target]{color:var(--vp-accent)}.vp-artboard-body{position:relative;overflow:hidden;height:100%;background:var(--vp-surface);border:1.5px solid var(--vp-border);box-shadow:0 1px 3px #1016200f}.vp-artboard:hover .vp-artboard-body{box-shadow:var(--vp-shadow)}.vp-artboard.is-selected .vp-artboard-body{outline:2px solid var(--vp-accent);outline-offset:3px}.vp-sketch .vp-artboard-body[data-rough-ready=true]{border-color:transparent}.vp-sketch .vp-artboard-title{font-family:Architects Daughter,Comic Sans MS,cursive;font-size:14px}@media(prefers-reduced-motion:no-preference){.vp-sketch .vp-artboard-body{filter:url(#vp-wobble)}}.vp-zoom-controls{position:absolute;bottom:12px;left:12px;z-index:10;display:flex;gap:2px;align-items:center;background:var(--vp-chrome);border:1px solid var(--vp-border);border-radius:10px;padding:3px 5px;box-shadow:var(--vp-shadow);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.vp-zoom-controls button{border:none;background:transparent;color:var(--vp-text);cursor:pointer;font-size:.85rem;padding:2px 7px;border-radius:6px}.vp-zoom-controls button:hover{background:color-mix(in srgb,var(--vp-text) 8%,transparent)}.vp-zoom-level{font-size:.72rem;font-weight:600;font-variant-numeric:tabular-nums;color:var(--vp-muted);min-width:40px;text-align:center}.vp-side{border-left:1px solid var(--vp-border);background:var(--vp-surface);overflow-y:auto;display:flex;flex-direction:column}.vp-edit-controls{padding:.5rem .75rem;border-top:1px solid var(--vp-border);display:flex;gap:10px;flex-wrap:wrap}.vp-edit-field{display:flex;flex-direction:column;font-size:.72rem;color:var(--vp-muted);gap:2px}.vp-edit-field select,.vp-edit-field input{font-size:.8rem;padding:2px 4px;border:1px solid var(--vp-border);border-radius:4px;background:var(--vp-bg);color:var(--vp-text)}.vp-feedback{padding:.75rem;border-top:1px solid var(--vp-border);display:flex;flex-direction:column;gap:6px}.vp-feedback-ops{list-style:none;margin:0;padding:0;font-size:.78rem;display:flex;flex-direction:column;gap:2px}.vp-fb-type{color:var(--vp-muted);font-size:.7rem}.vp-feedback select,.vp-feedback textarea{font-size:.8rem;border:1px solid var(--vp-border);border-radius:4px;background:var(--vp-bg);color:var(--vp-text);padding:4px}.vp-feedback textarea{min-height:48px;resize:vertical}.vp-fb-hint{font-size:.72rem;color:var(--vp-warn);margin:0}.vp-copy-command{display:flex;flex-direction:column;gap:4px;background:var(--vp-bg);border:1px solid var(--vp-border);border-radius:6px;padding:6px}.vp-copy-command code{font-size:.72rem;word-break:break-all}.vp-coverage-panel,.vp-inspector{background:var(--vp-surface);padding:.75rem}.vp-coverage-panel{border-left:1px solid var(--vp-border);overflow-y:auto}.vp-panel-title{font-size:.9rem;margin:0 0 .5rem}.vp-coverage-summary{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:.6rem}.vp-cov-chip{font-size:.7rem;padding:.1rem .4rem;border-radius:999px;border:1px solid var(--vp-border)}.vp-cov-chip[data-mode=unresolved]{color:var(--vp-warn);border-color:var(--vp-warn)}.vp-cov-chip[data-mode=resolved]{color:var(--vp-ok)}.vp-coverage-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.vp-coverage-row{display:flex;gap:6px;font-size:.78rem;padding:.2rem .3rem;border-radius:6px}.vp-coverage-row[data-mode=unresolved]{background:color-mix(in srgb,var(--vp-warn) 12%,transparent)}.vp-cov-surface{color:var(--vp-muted);margin-left:auto}.vp-inspector-fields{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;font-size:.8rem;margin:0}.vp-inspector-fields dt{color:var(--vp-muted)}.vp-inspector-refs{margin:0;padding-left:1rem}.vp-inspector-empty{color:var(--vp-muted);font-size:.85rem}.vp-connector-path{stroke:var(--vp-accent);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;fill:none}.vp-connector-head{stroke:var(--vp-accent);stroke-width:2.4;stroke-linecap:round;fill:none}.vp-connector-label-box{fill:var(--vp-chrome);stroke:var(--vp-border);stroke-width:1}.vp-connector-label{fill:var(--vp-accent);font-size:12px;font-weight:600}@media(prefers-reduced-motion:no-preference){.vp-sketch .vp-connector-path,.vp-sketch .vp-connector-head{filter:url(#vp-wobble)}}.vp-annotation-layer{position:absolute;top:0;left:0}.vp-note{width:240px;font-size:13px;line-height:1.55;color:var(--vp-muted)}.vp-note:before{content:"✎ ";color:var(--vp-accent)}.vp-sketch .vp-note{font-family:Architects Daughter,Comic Sans MS,cursive}.vp-markup{max-width:280px;font-size:12.5px;color:var(--vp-text);background:var(--vp-chrome);border:1px solid color-mix(in srgb,var(--vp-accent) 35%,transparent);border-radius:8px;padding:6px 10px;box-shadow:var(--vp-shadow);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}
|