@tritard/waterbrother 0.8.21 → 0.8.22
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/package.json +1 -1
- package/src/agent.js +7 -4
- package/src/frontend.js +52 -16
package/package.json
CHANGED
package/src/agent.js
CHANGED
|
@@ -59,12 +59,11 @@ When you use tools:
|
|
|
59
59
|
- define the typography, color system, spacing rhythm, and motion restraint through the code you write
|
|
60
60
|
- avoid fake press badges, fake testimonials, fake founder lore, and placeholder image services unless explicitly requested
|
|
61
61
|
- avoid generic Tailwind CDN template output and default premium-blog serif/sans pairings
|
|
62
|
-
- avoid invented publication brands, named authors, issue numbers, staff credits, or editorial worldbuilding unless the user explicitly asked for fictional framing
|
|
63
62
|
- avoid browser-default Georgia/Times plus system-sans typography as a final design answer
|
|
64
63
|
- avoid fake keyboard shortcuts, fake command palettes, and demo-only interaction chrome
|
|
65
|
-
- avoid generic reflective-editorial copy about slowness, attention, or the examined life unless the user explicitly asked for that voice
|
|
66
|
-
- prefer fewer sections and at least one asymmetrical or compositionally distinctive move over a fully balanced template layout
|
|
67
64
|
- prefer fewer stronger sections over a busy page with fake search, fake filters, or filler widgets
|
|
65
|
+
- adapt the above rules to the site type; docs and dashboards may need clearer repetitive utility layouts than editorial or portfolio pages
|
|
66
|
+
- only apply benchmark-grade strictness about publication framing, reflective-editorial copy, and forced asymmetry when the task is clearly a benchmark/comparison ask
|
|
68
67
|
- After making code or file edits:
|
|
69
68
|
- lead with the file path or paths you changed
|
|
70
69
|
- summarize concrete changes, not vibes or quality claims
|
|
@@ -124,9 +123,13 @@ function buildSystemPrompt(profile, experienceMode = "standard", autonomyMode =
|
|
|
124
123
|
`- tone: ${frontend.tone || "unknown"}`,
|
|
125
124
|
`- content mode: ${frontend.contentMode || "designed-placeholder"}`,
|
|
126
125
|
`- asset policy: ${frontend.assetPolicy || "no-placeholder-images-unless-explicit"}`,
|
|
127
|
-
`- layout starter: ${frontend.layoutStarter || "choose a strong non-generic section grammar"}
|
|
126
|
+
`- layout starter: ${frontend.layoutStarter || "choose a strong non-generic section grammar"}`,
|
|
127
|
+
`- benchmark mode: ${frontend.benchmarkMode ? "on" : "off"}`
|
|
128
128
|
].join("\n")
|
|
129
129
|
);
|
|
130
|
+
if (Array.isArray(frontend.siteTypeRules) && frontend.siteTypeRules.length > 0) {
|
|
131
|
+
ctxLines.push(`Site-type rules:\n- ${frontend.siteTypeRules.join("\n- ")}`);
|
|
132
|
+
}
|
|
130
133
|
}
|
|
131
134
|
if (executionContext.reminders) ctxLines.push(`Scope reminders:\n${executionContext.reminders}`);
|
|
132
135
|
if (ctxLines.length > 0) base += `\n\nExecution context:\n${ctxLines.join("\n")}`;
|
package/src/frontend.js
CHANGED
|
@@ -49,6 +49,22 @@ Rules:
|
|
|
49
49
|
|
|
50
50
|
const BENCHMARK_FRONTEND_PROMPT = /\b(?:benchmark|squarespace quality|ultimate design|first class|on par|codex|claude code|cc)\b/i;
|
|
51
51
|
|
|
52
|
+
const UNIVERSAL_FRONTEND_REMINDERS = [
|
|
53
|
+
"Choose one visual direction and stay consistent across typography, spacing, color, and motion.",
|
|
54
|
+
"Choose a real type system with deliberate character. Browser-default Georgia/Times plus system sans is not an acceptable final design direction.",
|
|
55
|
+
"Prefer hand-authored CSS variables and layout rules over generic template utility sprawl when feasible.",
|
|
56
|
+
"Cut fake credibility elements, fake brands, fake testimonials, and filler interface chrome unless explicitly requested.",
|
|
57
|
+
"Do not add fake keyboard shortcuts, fake command palettes, or demo-only interactive chrome unless the interface truly needs them.",
|
|
58
|
+
"Avoid placeholder image services, Inter/Playfair default pairings, Tailwind CDN starter aesthetics, and generic premium-blog tropes.",
|
|
59
|
+
"Prefer fewer sections with stronger hierarchy over a long page full of low-value widgets."
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
const BENCHMARK_FRONTEND_REMINDERS = [
|
|
63
|
+
"For benchmark frontend tasks, cut generic reflective-editorial copy. Use sharper, more concrete language or neutral structural placeholders instead of atmosphere-writing.",
|
|
64
|
+
"For benchmark frontend tasks, force at least one asymmetrical or compositionally distinctive move instead of a fully balanced template layout.",
|
|
65
|
+
"Benchmark mode: treat fake issue framing, fake publication history, fake keyboard shortcuts, and invented named contributors as disallowed outputs. Use neutral structural placeholders if needed."
|
|
66
|
+
];
|
|
67
|
+
|
|
52
68
|
const SITE_TYPES = [
|
|
53
69
|
["blog", /\b(blog|journal|essays?|articles?|publication|editorial)\b/i],
|
|
54
70
|
["landing", /\b(landing page|homepage|home page|marketing site|product site|launch page|hero section)\b/i],
|
|
@@ -73,6 +89,30 @@ const AUDIENCE_HINTS = [
|
|
|
73
89
|
["operators", /\b(founders?|operators?|engineers?|designers?)\b/i]
|
|
74
90
|
];
|
|
75
91
|
|
|
92
|
+
const SITE_TYPE_RULES = {
|
|
93
|
+
blog: [
|
|
94
|
+
"For blogs and editorial sites, prefer structural placeholder labels over inventing fictional publication brands, named editors, or fake biographical lore.",
|
|
95
|
+
"Do not invent issue numbers, seasonal issue metadata, staff credits, or named authors/photographers unless the user explicitly asked for fictional worldbuilding.",
|
|
96
|
+
"Do not add a newsletter/signup block unless the user explicitly asked for one or the site type clearly requires capture."
|
|
97
|
+
],
|
|
98
|
+
landing: [
|
|
99
|
+
"For landing pages, prioritize the value proposition, proof, and one primary action over editorial atmosphere.",
|
|
100
|
+
"CTA sections are acceptable when they are genuinely part of the requested product flow; avoid fake testimonials or fake customer logos."
|
|
101
|
+
],
|
|
102
|
+
portfolio: [
|
|
103
|
+
"For portfolios, let work samples, case studies, and identity carry the page rather than editorial filler.",
|
|
104
|
+
"Do not add newsletter/signup blocks or publication framing unless explicitly requested."
|
|
105
|
+
],
|
|
106
|
+
docs: [
|
|
107
|
+
"For docs and help centers, clarity and information scent matter more than asymmetry or art direction.",
|
|
108
|
+
"Balanced, repetitive utility layouts are acceptable when they improve scanability."
|
|
109
|
+
],
|
|
110
|
+
dashboard: [
|
|
111
|
+
"For dashboards and app UI, useful controls and information density matter more than editorial composition.",
|
|
112
|
+
"Do not remove necessary navigation or controls just to make the page feel minimal."
|
|
113
|
+
]
|
|
114
|
+
};
|
|
115
|
+
|
|
76
116
|
const ARCHETYPE_RULES = {
|
|
77
117
|
"editorial-minimal": [
|
|
78
118
|
"Use restrained editorial hierarchy with fewer, larger blocks of content.",
|
|
@@ -252,6 +292,10 @@ function inferAssetPolicy(text) {
|
|
|
252
292
|
return "no-placeholder-images-unless-explicit";
|
|
253
293
|
}
|
|
254
294
|
|
|
295
|
+
function getSiteTypeRules(siteType) {
|
|
296
|
+
return SITE_TYPE_RULES[siteType] || [];
|
|
297
|
+
}
|
|
298
|
+
|
|
255
299
|
export function isFrontendGenerationPrompt(promptText = "", profile = "coder") {
|
|
256
300
|
const text = String(promptText || "").trim();
|
|
257
301
|
if (!text) return false;
|
|
@@ -277,23 +321,14 @@ export function buildFrontendExecutionContext({ promptText = "", profile = "code
|
|
|
277
321
|
}
|
|
278
322
|
const assetPolicy = inferAssetPolicy(text);
|
|
279
323
|
const layoutStarter = getLayoutStarter(siteType, archetype);
|
|
324
|
+
const siteTypeRules = getSiteTypeRules(siteType);
|
|
280
325
|
const reminders = [
|
|
281
326
|
`Frontend brief: site type = ${siteType}, archetype = ${archetype}, audience = ${audience}, tone = ${tone}.`,
|
|
282
327
|
`Content mode: ${contentMode}. Asset policy: ${assetPolicy}.`,
|
|
283
328
|
layoutStarter ? `Layout starter: ${layoutStarter[0]}` : "",
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
"Cut fake credibility elements, fake brands, fake testimonials, and filler interface chrome unless explicitly requested.",
|
|
288
|
-
"For blogs and editorial sites, prefer structural placeholder labels over inventing fictional publication brands, named editors, or fake biographical lore.",
|
|
289
|
-
"Do not invent issue numbers, seasonal issue metadata, staff credits, or named authors/photographers unless the user explicitly asked for fictional worldbuilding.",
|
|
290
|
-
"Do not add a newsletter/signup block unless the user explicitly asked for one or the site type clearly requires capture.",
|
|
291
|
-
"Do not add fake keyboard shortcuts, fake command palettes, or demo-only interactive chrome unless the interface truly needs them.",
|
|
292
|
-
"Avoid placeholder image services, Inter/Playfair default pairings, Tailwind CDN starter aesthetics, and generic premium-blog tropes.",
|
|
293
|
-
"Prefer fewer sections with stronger hierarchy over a long page full of low-value widgets.",
|
|
294
|
-
"For benchmark frontend tasks, cut generic reflective-editorial copy. Use sharper, more concrete language or neutral structural placeholders instead of atmosphere-writing.",
|
|
295
|
-
"For benchmark frontend tasks, force at least one asymmetrical or compositionally distinctive move instead of a fully balanced template layout.",
|
|
296
|
-
benchmarkMode ? "Benchmark mode: treat fake issue framing, fake publication history, fake keyboard shortcuts, and invented named contributors as disallowed outputs. Use neutral structural placeholders if needed." : "",
|
|
329
|
+
...UNIVERSAL_FRONTEND_REMINDERS,
|
|
330
|
+
...siteTypeRules,
|
|
331
|
+
...(benchmarkMode ? BENCHMARK_FRONTEND_REMINDERS : []),
|
|
297
332
|
...(layoutStarter ? [layoutStarter[1]] : []),
|
|
298
333
|
...(ARCHETYPE_RULES[archetype] || [])
|
|
299
334
|
].join("\n");
|
|
@@ -307,7 +342,8 @@ export function buildFrontendExecutionContext({ promptText = "", profile = "code
|
|
|
307
342
|
contentMode,
|
|
308
343
|
assetPolicy,
|
|
309
344
|
layoutStarter: layoutStarter ? layoutStarter[0] : null,
|
|
310
|
-
benchmarkMode
|
|
345
|
+
benchmarkMode,
|
|
346
|
+
siteTypeRules
|
|
311
347
|
},
|
|
312
348
|
reminders
|
|
313
349
|
};
|
|
@@ -355,12 +391,12 @@ export function detectFrontendSlop({ promptText = "", assistantText = "", receip
|
|
|
355
391
|
flags.push("fake keyboard or command-palette gimmick");
|
|
356
392
|
score += 3;
|
|
357
393
|
}
|
|
358
|
-
if (siteType === "blog" && benchmarkMode && /\b(?:measure of time in ordinary things|quiet rituals|architecture of memory|cult of productivity|considered writing|the slow accumulation of days|craft of attention|in defense of silence)\b/i.test(haystack)) {
|
|
394
|
+
if (siteType === "blog" && benchmarkMode && /\b(?:measure of time in ordinary things|quiet rituals|architecture of memory|cult of productivity|considered writing|the slow accumulation of days|craft of attention|in defense of silence|meditation on permanence and ephemerality|stillness and the act of looking|deliberate observation)\b/i.test(haystack)) {
|
|
359
395
|
flags.push("benchmark blog fell back to reflective-editorial atmosphere copy");
|
|
360
396
|
score += 3;
|
|
361
397
|
}
|
|
362
398
|
const editorialLayoutHits = GENERIC_EDITORIAL_LAYOUT_PATTERNS.filter((pattern) => pattern.test(haystack)).length;
|
|
363
|
-
if (siteType === "blog" && editorialLayoutHits >= 3) {
|
|
399
|
+
if (siteType === "blog" && benchmarkMode && editorialLayoutHits >= 3) {
|
|
364
400
|
flags.push("generic editorial starter layout");
|
|
365
401
|
score += 2;
|
|
366
402
|
}
|