@drunkcoding/agents-and-skills 0.0.44 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/.claude-plugin/marketplace.json +2 -47
  2. package/README.md +3 -6
  3. package/package.json +4 -1
  4. package/plugins/multica-tool/.claude-plugin/plugin.json +1 -1
  5. package/plugins/multica-tool/scripts/lib.mjs +53 -4
  6. package/plugins/multica-tool/scripts/multica-export.mjs +170 -50
  7. package/plugins/multica-tool/scripts/multica-import.mjs +209 -27
  8. package/plugins/multica-tool/skills/export/SKILL.md +91 -22
  9. package/plugins/multica-tool/skills/import/SKILL.md +24 -9
  10. package/plugins/multica-tool/skills/sync/SKILL.md +1 -1
  11. package/plugins/plugin-validator/.claude-plugin/plugin.json +1 -1
  12. package/plugins/html-effectiveness/.claude-plugin/plugin.json +0 -17
  13. package/plugins/html-effectiveness/README.md +0 -28
  14. package/plugins/html-effectiveness/agents/report-builder.md +0 -66
  15. package/plugins/html-effectiveness/assets/base.css +0 -51
  16. package/plugins/html-effectiveness/assets/base.js +0 -11
  17. package/plugins/html-effectiveness/assets/charts.js +0 -1
  18. package/plugins/html-effectiveness/assets/components.css +0 -10
  19. package/plugins/html-effectiveness/commands/html-report.md +0 -13
  20. package/plugins/html-effectiveness/docs/template-gallery.md +0 -28
  21. package/plugins/html-effectiveness/package.json +0 -6
  22. package/plugins/html-effectiveness/scripts/_tmp.js +0 -37
  23. package/plugins/html-effectiveness/scripts/catalog.js +0 -47
  24. package/plugins/html-effectiveness/scripts/extract.js +0 -104
  25. package/plugins/html-effectiveness/scripts/mustache.js +0 -90
  26. package/plugins/html-effectiveness/scripts/render.js +0 -176
  27. package/plugins/html-effectiveness/skills/html-effectiveness/SKILL.md +0 -94
  28. package/plugins/html-effectiveness/templates/01-exploration-code-approaches.html.tmpl +0 -400
  29. package/plugins/html-effectiveness/templates/02-exploration-visual-designs.html.tmpl +0 -456
  30. package/plugins/html-effectiveness/templates/03-code-review-pr.html.tmpl +0 -581
  31. package/plugins/html-effectiveness/templates/04-code-understanding.html.tmpl +0 -443
  32. package/plugins/html-effectiveness/templates/05-design-system.html.tmpl +0 -578
  33. package/plugins/html-effectiveness/templates/06-component-variants.html.tmpl +0 -557
  34. package/plugins/html-effectiveness/templates/07-prototype-animation.html.tmpl +0 -417
  35. package/plugins/html-effectiveness/templates/08-prototype-interaction.html.tmpl +0 -363
  36. package/plugins/html-effectiveness/templates/09-slide-deck.html.tmpl +0 -535
  37. package/plugins/html-effectiveness/templates/10-svg-illustrations.html.tmpl +0 -444
  38. package/plugins/html-effectiveness/templates/11-status-report.html.tmpl +0 -152
  39. package/plugins/html-effectiveness/templates/12-incident-report.html.tmpl +0 -547
  40. package/plugins/html-effectiveness/templates/13-flowchart-diagram.html.tmpl +0 -361
  41. package/plugins/html-effectiveness/templates/14-research-feature-explainer.html.tmpl +0 -348
  42. package/plugins/html-effectiveness/templates/15-research-concept-explainer.html.tmpl +0 -334
  43. package/plugins/html-effectiveness/templates/16-implementation-plan.html.tmpl +0 -657
  44. package/plugins/html-effectiveness/templates/17-pr-writeup.html.tmpl +0 -553
  45. package/plugins/html-effectiveness/templates/18-editor-triage-board.html.tmpl +0 -541
  46. package/plugins/html-effectiveness/templates/19-editor-feature-flags.html.tmpl +0 -627
  47. package/plugins/html-effectiveness/templates/20-editor-prompt-tuner.html.tmpl +0 -687
  48. package/plugins/html-effectiveness/templates/manifest.json +0 -441
  49. package/plugins/team-share/.claude-plugin/plugin.json +0 -18
  50. package/plugins/team-share/README.md +0 -46
  51. package/plugins/team-share/agents/team-share.md +0 -53
  52. package/plugins/team-share/commands/team-share.md +0 -4
  53. package/plugins/team-share/skills/claude-config/SKILL.md +0 -143
  54. package/plugins/team-share/skills/codegraph-setup/SKILL.md +0 -81
  55. package/plugins/team-share/skills/understand-setup/SKILL.md +0 -115
  56. package/plugins/tech-graph/.claude-plugin/plugin.json +0 -17
  57. package/plugins/tech-graph/README.md +0 -66
  58. package/plugins/tech-graph/agents/tech-graph.md +0 -97
  59. package/plugins/tech-graph/commands/tech-graph.md +0 -13
  60. package/plugins/tech-graph/scripts/check-deps.sh +0 -55
  61. package/plugins/tech-graph/skills/tech-graph/LICENSE +0 -21
  62. package/plugins/tech-graph/skills/tech-graph/README.md +0 -555
  63. package/plugins/tech-graph/skills/tech-graph/README.zh.md +0 -514
  64. package/plugins/tech-graph/skills/tech-graph/SKILL.md +0 -263
  65. package/plugins/tech-graph/skills/tech-graph/agents/openai.yaml +0 -4
  66. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style1-flat.png +0 -0
  67. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style2-dark.png +0 -0
  68. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style3-blueprint.png +0 -0
  69. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style4-notion.png +0 -0
  70. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style5-glass.png +0 -0
  71. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style6-claude.png +0 -0
  72. package/plugins/tech-graph/skills/tech-graph/assets/samples/sample-style7-openai.png +0 -0
  73. package/plugins/tech-graph/skills/tech-graph/fixtures/agent-memory-types-style4.json +0 -181
  74. package/plugins/tech-graph/skills/tech-graph/fixtures/api-flow-style7.json +0 -40
  75. package/plugins/tech-graph/skills/tech-graph/fixtures/mem0-style1.json +0 -297
  76. package/plugins/tech-graph/skills/tech-graph/fixtures/microservices-style3.json +0 -64
  77. package/plugins/tech-graph/skills/tech-graph/fixtures/multi-agent-style5.json +0 -45
  78. package/plugins/tech-graph/skills/tech-graph/fixtures/system-architecture-style6.json +0 -48
  79. package/plugins/tech-graph/skills/tech-graph/fixtures/tool-call-style2.json +0 -182
  80. package/plugins/tech-graph/skills/tech-graph/package.json +0 -42
  81. package/plugins/tech-graph/skills/tech-graph/references/diagram-types.md +0 -171
  82. package/plugins/tech-graph/skills/tech-graph/references/icons.md +0 -406
  83. package/plugins/tech-graph/skills/tech-graph/references/style-1-flat-icon.md +0 -108
  84. package/plugins/tech-graph/skills/tech-graph/references/style-2-dark-terminal.md +0 -107
  85. package/plugins/tech-graph/skills/tech-graph/references/style-3-blueprint.md +0 -113
  86. package/plugins/tech-graph/skills/tech-graph/references/style-4-notion-clean.md +0 -95
  87. package/plugins/tech-graph/skills/tech-graph/references/style-5-glassmorphism.md +0 -125
  88. package/plugins/tech-graph/skills/tech-graph/references/style-6-claude-official.md +0 -209
  89. package/plugins/tech-graph/skills/tech-graph/references/style-7-openai.md +0 -215
  90. package/plugins/tech-graph/skills/tech-graph/references/style-diagram-matrix.md +0 -135
  91. package/plugins/tech-graph/skills/tech-graph/references/svg-layout-best-practices.md +0 -100
  92. package/plugins/tech-graph/skills/tech-graph/references/svg-to-png.md +0 -115
  93. package/plugins/tech-graph/skills/tech-graph/scripts/README.md +0 -269
  94. package/plugins/tech-graph/skills/tech-graph/scripts/generate-diagram.sh +0 -181
  95. package/plugins/tech-graph/skills/tech-graph/scripts/generate-from-template.py +0 -1587
  96. package/plugins/tech-graph/skills/tech-graph/scripts/test-all-styles.sh +0 -143
  97. package/plugins/tech-graph/skills/tech-graph/scripts/validate-svg.sh +0 -306
  98. package/plugins/tech-graph/skills/tech-graph/templates/agent-architecture.svg +0 -28
  99. package/plugins/tech-graph/skills/tech-graph/templates/architecture.svg +0 -23
  100. package/plugins/tech-graph/skills/tech-graph/templates/comparison-matrix.svg +0 -14
  101. package/plugins/tech-graph/skills/tech-graph/templates/data-flow.svg +0 -28
  102. package/plugins/tech-graph/skills/tech-graph/templates/er-diagram.svg +0 -21
  103. package/plugins/tech-graph/skills/tech-graph/templates/flowchart.svg +0 -21
  104. package/plugins/tech-graph/skills/tech-graph/templates/sequence.svg +0 -20
  105. package/plugins/tech-graph/skills/tech-graph/templates/state-machine.svg +0 -20
  106. package/plugins/tech-graph/skills/tech-graph/templates/timeline.svg +0 -19
  107. package/plugins/tech-graph/skills/tech-graph/templates/use-case.svg +0 -21
@@ -1,90 +0,0 @@
1
- // Hand-rolled mustache subset: {{var}}, {{{raw}}}, {{#section}}…{{/section}}, {{^inverted}}…{{/inverted}}
2
- // Zero runtime dependencies.
3
-
4
- const ESCAPE_MAP = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
5
- const escapeHtml = (s) => String(s).replace(/[&<>"']/g, (c) => ESCAPE_MAP[c]);
6
-
7
- function tokenize(template) {
8
- const tokens = [];
9
- const re = /\{\{(\{?)([\^#\/]?)\s*([\w.-]+)\s*\}?\}\}/g;
10
- let lastIndex = 0;
11
- let m;
12
- while ((m = re.exec(template)) !== null) {
13
- if (m.index > lastIndex) tokens.push({ type: 'text', value: template.slice(lastIndex, m.index) });
14
- const [, triple, sigil, name] = m;
15
- if (sigil === '#') tokens.push({ type: 'section', name });
16
- else if (sigil === '^') tokens.push({ type: 'inverted', name });
17
- else if (sigil === '/') tokens.push({ type: 'close', name });
18
- else if (triple === '{') tokens.push({ type: 'raw', name });
19
- else tokens.push({ type: 'var', name });
20
- lastIndex = re.lastIndex;
21
- }
22
- if (lastIndex < template.length) tokens.push({ type: 'text', value: template.slice(lastIndex) });
23
- return tokens;
24
- }
25
-
26
- function parse(tokens, end = null) {
27
- const nodes = [];
28
- while (tokens.length) {
29
- const t = tokens.shift();
30
- if (t.type === 'close') {
31
- if (t.name !== end) throw new Error(`Mismatched close tag: expected ${end}, got ${t.name}`);
32
- return nodes;
33
- }
34
- if (t.type === 'section' || t.type === 'inverted') {
35
- const children = parse(tokens, t.name);
36
- nodes.push({ ...t, children });
37
- } else {
38
- nodes.push(t);
39
- }
40
- }
41
- if (end !== null) throw new Error(`Unclosed section: ${end}`);
42
- return nodes;
43
- }
44
-
45
- function lookup(ctxStack, name) {
46
- if (name === '.') return ctxStack[ctxStack.length - 1];
47
- const parts = name.split('.');
48
- for (let i = ctxStack.length - 1; i >= 0; i--) {
49
- let cur = ctxStack[i];
50
- let ok = true;
51
- for (const p of parts) {
52
- if (cur == null || typeof cur !== 'object' || !Object.prototype.hasOwnProperty.call(cur, p)) { ok = false; break; }
53
- cur = cur[p];
54
- }
55
- if (ok) return cur;
56
- }
57
- return undefined;
58
- }
59
-
60
- function emit(nodes, ctxStack) {
61
- let out = '';
62
- for (const n of nodes) {
63
- if (n.type === 'text') out += n.value;
64
- else if (n.type === 'var') {
65
- const v = lookup(ctxStack, n.name);
66
- out += v == null ? '' : escapeHtml(v);
67
- } else if (n.type === 'raw') {
68
- const v = lookup(ctxStack, n.name);
69
- out += v == null ? '' : String(v);
70
- } else if (n.type === 'section') {
71
- const v = lookup(ctxStack, n.name);
72
- if (Array.isArray(v)) {
73
- for (const item of v) out += emit(n.children, [...ctxStack, item]);
74
- } else if (v && (typeof v !== 'object' || Object.keys(v).length > 0)) {
75
- out += emit(n.children, [...ctxStack, v]);
76
- }
77
- } else if (n.type === 'inverted') {
78
- const v = lookup(ctxStack, n.name);
79
- const empty = v == null || v === false || (Array.isArray(v) && v.length === 0);
80
- if (empty) out += emit(n.children, ctxStack);
81
- }
82
- }
83
- return out;
84
- }
85
-
86
- export function render(template, data) {
87
- const tokens = tokenize(template);
88
- const tree = parse(tokens);
89
- return emit(tree, [data]);
90
- }
@@ -1,176 +0,0 @@
1
- #!/usr/bin/env node
2
- // CLI + library: render a template + data into a self-contained HTML file.
3
- // Exit codes: 0 ok, 1 generic, 2 template-not-found, 3 slot schema mismatch, 4 fs write error.
4
-
5
- import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
6
- import { dirname, resolve, join } from 'node:path';
7
- import { fileURLToPath, pathToFileURL } from 'node:url';
8
- import { parseArgs } from 'node:util';
9
- import { render as mustache } from './mustache.js';
10
-
11
- const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
12
- const PLUGIN_ROOT = dirname(SCRIPT_DIR);
13
-
14
- const ASSET_BUNDLES = {
15
- base: { css: 'assets/base.css', js: 'assets/base.js' },
16
- components: { css: 'assets/components.css' },
17
- charts: { js: 'assets/charts.js' },
18
- };
19
-
20
- function validateSlot(templateId, slotPath, schema, value) {
21
- if (schema.required && (value === undefined || value === null)) {
22
- const err = new Error(`${templateId}:${slotPath} required but missing`);
23
- err.code = 3;
24
- throw err;
25
- }
26
- if (value === undefined || value === null) return;
27
- const type = schema.type;
28
- if (type === 'string' || type === 'html') {
29
- if (typeof value !== 'string') {
30
- const err = new Error(`${templateId}:${slotPath} expected string got ${typeof value}`);
31
- err.code = 3;
32
- throw err;
33
- }
34
- } else if (type === 'number') {
35
- if (typeof value !== 'number') {
36
- const err = new Error(`${templateId}:${slotPath} expected number got ${typeof value}`);
37
- err.code = 3;
38
- throw err;
39
- }
40
- } else if (type === 'boolean') {
41
- if (typeof value !== 'boolean') {
42
- const err = new Error(`${templateId}:${slotPath} expected boolean got ${typeof value}`);
43
- err.code = 3;
44
- throw err;
45
- }
46
- } else if (type === 'array') {
47
- if (!Array.isArray(value)) {
48
- const err = new Error(`${templateId}:${slotPath} expected array got ${typeof value}`);
49
- err.code = 3;
50
- throw err;
51
- }
52
- if (schema.of) {
53
- value.forEach((item, i) => {
54
- for (const [k, subType] of Object.entries(schema.of)) {
55
- const subSchema = typeof subType === 'string' ? { type: subType } : subType;
56
- validateSlot(templateId, `${slotPath}[${i}].${k}`, subSchema, item?.[k]);
57
- }
58
- });
59
- }
60
- } else if (type === 'object') {
61
- if (typeof value !== 'object' || Array.isArray(value)) {
62
- const err = new Error(`${templateId}:${slotPath} expected object got ${typeof value}`);
63
- err.code = 3;
64
- throw err;
65
- }
66
- }
67
- }
68
-
69
- function validate(templateId, slots, data) {
70
- for (const [name, schemaRaw] of Object.entries(slots)) {
71
- const schema = typeof schemaRaw === 'string' ? { type: schemaRaw } : schemaRaw;
72
- validateSlot(templateId, name, schema, data[name]);
73
- }
74
- }
75
-
76
- function loadAssets(pluginRoot, bundles, extraJs) {
77
- const css = [];
78
- const js = [];
79
- for (const name of bundles || []) {
80
- const b = ASSET_BUNDLES[name];
81
- if (!b) continue;
82
- if (b.css) css.push(readFileSync(join(pluginRoot, b.css), 'utf8'));
83
- if (b.js) js.push(readFileSync(join(pluginRoot, b.js), 'utf8'));
84
- }
85
- if (extraJs) js.push(readFileSync(join(pluginRoot, extraJs), 'utf8'));
86
- return { css: css.join('\n'), js: js.join('\n') };
87
- }
88
-
89
- function escapeForTitle(s) {
90
- return String(s).replace(/[&<>"']/g, (c) => ({
91
- '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;',
92
- }[c]));
93
- }
94
-
95
- export function renderReport({ templateId, data, outPath, manifestPath, pluginRoot }) {
96
- const root = pluginRoot || PLUGIN_ROOT;
97
- const mPath = manifestPath || join(root, 'templates/manifest.json');
98
- const manifest = JSON.parse(readFileSync(mPath, 'utf8'));
99
- const entry = manifest[templateId];
100
- if (!entry) {
101
- const ids = Object.keys(manifest).filter((k) => k !== '_meta');
102
- const err = new Error(`template not found: ${templateId}. valid: ${ids.join(', ')}`);
103
- err.code = 2;
104
- throw err;
105
- }
106
-
107
- validate(templateId, entry.slots, data);
108
-
109
- const tmplRelPath = entry.tmpl || `templates/${templateId}.html.tmpl`;
110
- const tmpl = readFileSync(join(root, tmplRelPath), 'utf8');
111
- const body = mustache(tmpl, data);
112
-
113
- const { css, js } = loadAssets(root, entry.asset_bundles, entry.extra_js);
114
- const title = escapeForTitle(data.title || entry.title || 'Report');
115
-
116
- const html = `<!doctype html>
117
- <html lang="en">
118
- <head>
119
- <meta charset="utf-8">
120
- <meta name="viewport" content="width=device-width,initial-scale=1">
121
- <title>${title}</title>
122
- <style>${css}</style>
123
- </head>
124
- <body>
125
- ${body}
126
- <script>${js}</script>
127
- </body>
128
- </html>
129
- `;
130
-
131
- try {
132
- mkdirSync(dirname(outPath), { recursive: true });
133
- writeFileSync(outPath, html, 'utf8');
134
- const sidecar = {
135
- template: templateId,
136
- rendered_at: new Date().toISOString(),
137
- render_version: '0.1.0',
138
- data,
139
- };
140
- writeFileSync(outPath + '.data.json', JSON.stringify(sidecar, null, 2), 'utf8');
141
- } catch (e) {
142
- const err = new Error(`failed to write ${outPath}: ${e.message}`);
143
- err.code = 4;
144
- throw err;
145
- }
146
-
147
- return outPath;
148
- }
149
-
150
- function cli() {
151
- const { values } = parseArgs({
152
- options: {
153
- template: { type: 'string' },
154
- data: { type: 'string' },
155
- out: { type: 'string' },
156
- },
157
- });
158
- if (!values.template || !values.data || !values.out) {
159
- process.stderr.write('usage: render.js --template=<id> --data=<json-path> --out=<html-path>\n');
160
- process.exit(1);
161
- }
162
- try {
163
- const data = JSON.parse(readFileSync(resolve(values.data), 'utf8'));
164
- const finalPath = renderReport({
165
- templateId: values.template,
166
- data,
167
- outPath: resolve(values.out),
168
- });
169
- process.stdout.write(finalPath + '\n');
170
- } catch (e) {
171
- process.stderr.write((e.stack || e.message) + '\n');
172
- process.exit(e.code ?? 1);
173
- }
174
- }
175
-
176
- if (import.meta.url === pathToFileURL(process.argv[1]).href) cli();
@@ -1,94 +0,0 @@
1
- ---
2
- name: html-effectiveness
3
- description: Use when the user wants dense information, status, comparison, plan, code review, or research output rendered as a self-contained interactive HTML report instead of plain markdown. Renders via plugin templates and scripts/render.js into a single HTML file under docs/reports/ (overridable via CLAUDE.md).
4
- ---
5
-
6
- # HTML Effectiveness — Interactive Output
7
-
8
- Turn dense information into a self-contained, browser-based HTML document the user can explore interactively. Markdown is a wall of text; HTML is a spatial, interactive document. Zero dependencies, single file, opens anywhere.
9
-
10
- ## When to invoke
11
-
12
- Invoke this skill when the user asks for any of:
13
-
14
- - "Make a report", "render as HTML", "interactive view"
15
- - Status updates: weekly status, monthly recap, project digest
16
- - Incident: post-mortem, outage writeup
17
- - Code: PR review, code understanding, exploration of implementation approaches
18
- - Design: design system, component variants, prototypes
19
- - Research: feature explainer, concept explainer, tutorial
20
- - Planning: implementation plan, rollout, roadmap
21
- - Decisions: comparison board, decision matrix
22
- - Visual: slide deck, flowchart, SVG illustration
23
- - Editor tooling: triage board, feature flags, prompt tuner
24
-
25
- If the request fits a report-style output and rendering as HTML would be clearer than markdown, invoke the skill and delegate to the `report-builder` agent.
26
-
27
- ## Template catalog
28
-
29
- 20 templates ship with this plugin. Full table in `plugins/html-effectiveness/docs/template-gallery.md` (regen via `node plugins/html-effectiveness/scripts/catalog.js`). Highlights:
30
-
31
- - `01` / `02` — exploration comparisons (code approaches, visual designs)
32
- - `03` — code review board
33
- - `04` — code understanding / architecture walk-through
34
- - `05` / `06` — design system, component variants
35
- - `07` / `08` — prototype animation, prototype interaction
36
- - `09` — slide deck (arrow-key nav)
37
- - `10` — SVG illustrations
38
- - `11` — status report
39
- - `12` — incident report
40
- - `13` — flowchart diagram
41
- - `14` / `15` — research explainers (feature, concept)
42
- - `16` — implementation plan (annotated timeline)
43
- - `17` — PR writeup
44
- - `18` / `19` / `20` — editor tools (triage board, feature flags, prompt tuner)
45
-
46
- ## Render contract
47
-
48
- Always uphold these invariants:
49
-
50
- 1. **Inline-bundle** — the final HTML is single-file, self-contained. No `<link>` or `<script src>` references. The render script inlines `base.css`, `components.css`, `base.js`, plus any per-template extras.
51
- 2. **Escape strings** — string slots are HTML-escaped. Raw-HTML slots are only allowed when the manifest flags the slot as `"html"`.
52
- 3. **Output path** — read repo `CLAUDE.md` for `html-effectiveness.reportDir`; fallback to `docs/reports/`. Filename: `YYYY-MM-DD-<slug>.html`; slug derived from title (kebab-case, ASCII-only, max 60 chars).
53
- 4. **Sidecar** — `<report>.html.data.json` is always written alongside the HTML so the report can be regenerated by re-running `render.js` on the sidecar.
54
-
55
- ## Workflow
56
-
57
- 1. Pick template via `manifest.json` (match user intent against `use_cases` and `pattern`).
58
- 2. Fill slot data from the conversation; record it as JSON.
59
- 3. Invoke render script:
60
-
61
- ```bash
62
- node plugins/html-effectiveness/scripts/render.js \
63
- --template=<id> \
64
- --data=<data.json> \
65
- --out=<reportDir>/YYYY-MM-DD-<slug>.html
66
- ```
67
-
68
- 4. Confirm output path to the user; offer `snip render --format html < <path>` to preview in browser.
69
-
70
- ## Design principles
71
-
72
- Preserved from upstream `ThariqS/html-effectiveness`:
73
-
74
- - Avoid purple/blue gradient backgrounds, generic feature grids, center-everything layouts, decorative patterns.
75
- - Prioritize real data, scannable hierarchy, spatial grouping, progressive disclosure over decoration.
76
-
77
- ## Technical requirements
78
-
79
- - Single `.html` file, fully self-contained.
80
- - CSS variables for theming (light-only baseline, matching upstream palette).
81
- - System font stack and 150ms smooth transitions.
82
- - Responsive design 375px–1440px.
83
- - Semantic HTML5 with ARIA labels.
84
- - Print styles that expand all hidden content.
85
-
86
- ## Failure modes
87
-
88
- - **No template fits**: present the top 2 closest matches with one-line summaries; ask the user to confirm, or offer plain-markdown fallback. Never silently force a poor fit.
89
- - **Missing slot data**: ask one question at a time; respect the cap of 6 questions before forcing render with best-guess defaults plus a note of what was assumed.
90
- - **Render error**: surface `template:slot expected <type> got <type>` to the user; fix the slot value; retry.
91
-
92
- ## Vendored templates
93
-
94
- Templates are vendored, not auto-synced. The pinned upstream SHA lives at `templates/manifest.json` → `_meta.upstream_sha`. To refresh a single template: `node plugins/html-effectiveness/scripts/extract.js fetch <id>.html` then `split <id>.html`. Files land in `.tmp/html-effectiveness/extract/` (gitignored). Hand-merge the diff back into `templates/<id>.html.tmpl` and update `_meta.upstream_sha` if pinning a new revision.