@drunkcoding/agents-and-skills 0.0.12 → 0.0.14
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/.claude-plugin/marketplace.json +9 -6
- package/README.md +1 -1
- package/package.json +1 -1
- package/plugins/html-effectiveness/.claude-plugin/plugin.json +1 -1
- package/plugins/html-effectiveness/README.md +9 -4
- package/plugins/html-effectiveness/agents/report-builder.md +4 -0
- package/plugins/html-effectiveness/assets/base.css +40 -20
- package/plugins/html-effectiveness/docs/template-gallery.md +28 -0
- package/plugins/html-effectiveness/scripts/_tmp.js +37 -0
- package/plugins/html-effectiveness/scripts/catalog.js +47 -0
- package/plugins/html-effectiveness/scripts/extract.js +104 -0
- package/plugins/html-effectiveness/scripts/render.js +2 -2
- package/plugins/html-effectiveness/skills/html-effectiveness/SKILL.md +4 -4
- package/plugins/html-effectiveness/templates/01-exploration-code-approaches.html.tmpl +400 -0
- package/plugins/html-effectiveness/templates/02-exploration-visual-designs.html.tmpl +456 -0
- package/plugins/html-effectiveness/templates/03-code-review-pr.html.tmpl +581 -0
- package/plugins/html-effectiveness/templates/04-code-understanding.html.tmpl +443 -0
- package/plugins/html-effectiveness/templates/05-design-system.html.tmpl +578 -0
- package/plugins/html-effectiveness/templates/06-component-variants.html.tmpl +557 -0
- package/plugins/html-effectiveness/templates/07-prototype-animation.html.tmpl +417 -0
- package/plugins/html-effectiveness/templates/08-prototype-interaction.html.tmpl +363 -0
- package/plugins/html-effectiveness/templates/09-slide-deck.html.tmpl +535 -0
- package/plugins/html-effectiveness/templates/10-svg-illustrations.html.tmpl +444 -0
- package/plugins/html-effectiveness/templates/11-status-report.html.tmpl +152 -0
- package/plugins/html-effectiveness/templates/12-incident-report.html.tmpl +547 -0
- package/plugins/html-effectiveness/templates/13-flowchart-diagram.html.tmpl +361 -0
- package/plugins/html-effectiveness/templates/14-research-feature-explainer.html.tmpl +348 -0
- package/plugins/html-effectiveness/templates/15-research-concept-explainer.html.tmpl +334 -0
- package/plugins/html-effectiveness/templates/16-implementation-plan.html.tmpl +657 -0
- package/plugins/html-effectiveness/templates/17-pr-writeup.html.tmpl +553 -0
- package/plugins/html-effectiveness/templates/18-editor-triage-board.html.tmpl +541 -0
- package/plugins/html-effectiveness/templates/19-editor-feature-flags.html.tmpl +627 -0
- package/plugins/html-effectiveness/templates/20-editor-prompt-tuner.html.tmpl +687 -0
- package/plugins/html-effectiveness/templates/manifest.json +436 -2
- package/plugins/html-effectiveness/tests/_tmp.test.js +58 -0
- package/plugins/html-effectiveness/tests/fixtures/01-exploration-code-approaches.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/02-exploration-visual-designs.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/03-code-review-pr.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/04-code-understanding.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/05-design-system.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/06-component-variants.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/07-prototype-animation.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/08-prototype-interaction.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/09-slide-deck.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/10-svg-illustrations.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/11-status-report.data.json +37 -0
- package/plugins/html-effectiveness/tests/fixtures/12-incident-report.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/13-flowchart-diagram.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/14-research-feature-explainer.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/15-research-concept-explainer.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/16-implementation-plan.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/17-pr-writeup.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/18-editor-triage-board.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/19-editor-feature-flags.data.json +3 -0
- package/plugins/html-effectiveness/tests/fixtures/20-editor-prompt-tuner.data.json +3 -0
- package/plugins/html-effectiveness/tests/manifest.test.js +61 -0
- package/plugins/plugin-validator/.claude-plugin/plugin.json +1 -1
- package/plugins/plugin-validator/skills/validate-agents/SKILL.md +2 -2
- package/plugins/plugin-validator/skills/validate-commands/SKILL.md +2 -2
- package/plugins/plugin-validator/skills/validate-hooks/SKILL.md +57 -18
- package/plugins/team-superpower/.claude-plugin/plugin.json +7 -39
- package/plugins/team-superpower/README.md +73 -19
- package/plugins/team-superpower/agents/backend-developer.md +33 -0
- package/plugins/team-superpower/agents/designer.md +5 -1
- package/plugins/team-superpower/agents/frontend-developer.md +33 -0
- package/plugins/team-superpower/agents/planner.md +31 -11
- package/plugins/team-superpower/agents/qa-engineer.md +30 -0
- package/plugins/team-superpower/agents/reviewer.md +37 -21
- package/plugins/team-superpower/agents/security-engineer.md +30 -0
- package/plugins/team-superpower/agents/software-architect.md +30 -0
- package/plugins/team-superpower/assets/ESCALATION.md +19 -5
- package/plugins/team-superpower/assets/SESSION_README.md +31 -11
- package/plugins/team-superpower/commands/team-feature-resume.md +40 -5
- package/plugins/team-superpower/commands/team-feature.md +148 -22
- package/plugins/team-superpower/hooks/hooks.json +0 -3
- package/plugins/tech-graph/.claude-plugin/plugin.json +1 -1
- package/plugins/tech-graph/agents/tech-graph.md +8 -0
- package/plugins/team-superpower/agents/implementer.md +0 -46
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"name": "tech-graph",
|
|
13
13
|
"source": "./plugins/tech-graph",
|
|
14
14
|
"description": "6-step wizard for technical diagrams (SVG/PNG) via fireworks-tech-graph",
|
|
15
|
-
"version": "0.0.
|
|
15
|
+
"version": "0.0.14",
|
|
16
16
|
"category": "diagram",
|
|
17
17
|
"keywords": [
|
|
18
18
|
"diagram",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"name": "html-effectiveness",
|
|
27
27
|
"source": "./plugins/html-effectiveness",
|
|
28
28
|
"description": "Generate self-contained interactive HTML reports from 20 upstream templates via a conversational agent.",
|
|
29
|
-
"version": "0.0.
|
|
29
|
+
"version": "0.0.14",
|
|
30
30
|
"category": "reports",
|
|
31
31
|
"keywords": [
|
|
32
32
|
"html",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
{
|
|
41
41
|
"name": "team-superpower",
|
|
42
42
|
"source": "./plugins/team-superpower",
|
|
43
|
-
"description": "
|
|
44
|
-
"version": "0.0.
|
|
43
|
+
"description": "Full-stack engineering team that runs the Superpowers skill chain across 8 roles — designer, planner, software-architect, security-engineer, backend-developer, frontend-developer, qa-engineer, reviewer — with a pre-impl architecture+security gate and a post-impl QA gate.",
|
|
44
|
+
"version": "0.0.14",
|
|
45
45
|
"category": "workflow",
|
|
46
46
|
"keywords": [
|
|
47
47
|
"agent-teams",
|
|
@@ -50,14 +50,17 @@
|
|
|
50
50
|
"orchestration",
|
|
51
51
|
"workflow",
|
|
52
52
|
"brainstorming",
|
|
53
|
-
"code-review"
|
|
53
|
+
"code-review",
|
|
54
|
+
"architecture",
|
|
55
|
+
"security",
|
|
56
|
+
"qa"
|
|
54
57
|
]
|
|
55
58
|
},
|
|
56
59
|
{
|
|
57
60
|
"name": "plugin-validator",
|
|
58
61
|
"source": "./plugins/plugin-validator",
|
|
59
62
|
"description": "Orchestrated validator for Claude Code plugins — validates skills, agents, commands, and hooks across every plugin under plugins/**.",
|
|
60
|
-
"version": "0.0.
|
|
63
|
+
"version": "0.0.14",
|
|
61
64
|
"category": "tooling",
|
|
62
65
|
"keywords": [
|
|
63
66
|
"validation",
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Published on npm as [`@drunkcoding/agents-and-skills`](https://www.npmjs.com/pac
|
|
|
10
10
|
|--------|-------------|
|
|
11
11
|
| [`tech-graph`](plugins/tech-graph) | 6-step wizard for technical diagrams (SVG + PNG). |
|
|
12
12
|
| [`html-effectiveness`](plugins/html-effectiveness) | Conversational agent that generates self-contained interactive HTML reports from 20 templates. |
|
|
13
|
-
| [`team-superpower`](plugins/team-superpower) |
|
|
13
|
+
| [`team-superpower`](plugins/team-superpower) | Full-stack engineering team running the Superpowers skill chain — 8 roles (designer, planner, software-architect, security-engineer, backend-developer, frontend-developer, qa-engineer, reviewer) with a pre-impl arch+security gate and a post-impl QA gate. |
|
|
14
14
|
| [`plugin-validator`](plugins/plugin-validator) | Orchestrated validator that checks every plugin's skills, agents, commands, and hooks for spec compliance — runs in parallel and proposes batched fixes. |
|
|
15
15
|
|
|
16
16
|
## Install
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "html-effectiveness",
|
|
3
3
|
"displayName": "HTML Effectiveness Reports",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.14",
|
|
5
5
|
"description": "Generate self-contained interactive HTML reports from 20 upstream templates via a conversational agent.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Steven Hoang"
|
|
@@ -12,12 +12,17 @@ Override output dir in repo `CLAUDE.md`:
|
|
|
12
12
|
html-effectiveness.reportDir: my/custom/reports
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Vendored templates
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Templates are vendored from `ThariqS/html-effectiveness`. The pinned SHA lives in `templates/manifest.json` (`_meta.upstream_sha`). Re-fetch is **manual** — only run when you want to refresh the snapshot:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
node plugins/html-effectiveness/scripts/
|
|
20
|
+
node plugins/html-effectiveness/scripts/extract.js fetch <id>.html
|
|
21
|
+
node plugins/html-effectiveness/scripts/extract.js split <id>.html
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Files land under `.tmp/html-effectiveness/extract/` and are cleaned up automatically. Hand-merge any changes back into `templates/<id>.html.tmpl`.
|
|
25
|
+
|
|
26
|
+
## Scratch convention
|
|
27
|
+
|
|
28
|
+
All plugin scratch lives under `.tmp/html-effectiveness/<purpose>/` (gitignored). Helper API: `scripts/_tmp.js` exports `getTmpDir`, `cleanup`, and `withTmp` for try/finally + signal-handler cleanup.
|
|
@@ -42,6 +42,10 @@ On every run:
|
|
|
42
42
|
5. On success: print the absolute path; offer `snip render --format html < <path>` to preview in the browser.
|
|
43
43
|
6. On render error: surface stderr; locate the offending slot from the `template:slot` prefix; ask the user to fix; retry.
|
|
44
44
|
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
A self-contained interactive HTML report at `<reportDir>/YYYY-MM-DD-<slug>.html` plus a `<slug>.html.data.json` sidecar for later re-rendering. The absolute path is printed to the user on success, with an offer to preview via `snip render --format html`.
|
|
48
|
+
|
|
45
49
|
## Regen path
|
|
46
50
|
|
|
47
51
|
If the user invokes the agent on an existing `<name>.data.json`:
|
|
@@ -1,27 +1,47 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* Shared design tokens + page baseline. Vendored from ThariqS/html-effectiveness. */
|
|
2
2
|
:root {
|
|
3
|
-
--
|
|
4
|
-
--
|
|
5
|
-
--
|
|
6
|
-
--
|
|
7
|
-
--
|
|
8
|
-
--
|
|
9
|
-
--
|
|
10
|
-
--
|
|
3
|
+
--ivory: #FAF9F5;
|
|
4
|
+
--slate: #141413;
|
|
5
|
+
--clay: #D97757;
|
|
6
|
+
--oat: #E3DACC;
|
|
7
|
+
--olive: #788C5D;
|
|
8
|
+
--rust: #B04A3F;
|
|
9
|
+
--gray-100: #F0EEE6;
|
|
10
|
+
--gray-300: #D1CFC5;
|
|
11
|
+
--gray-500: #87867F;
|
|
12
|
+
--gray-700: #3D3D3A;
|
|
13
|
+
--white: #FFFFFF;
|
|
14
|
+
|
|
15
|
+
--serif: ui-serif, Georgia, serif;
|
|
16
|
+
--sans: system-ui, -apple-system, sans-serif;
|
|
17
|
+
--mono: ui-monospace, "SF Mono", Menlo, monospace;
|
|
18
|
+
|
|
19
|
+
--radius-panel: 12px;
|
|
20
|
+
--radius-row: 8px;
|
|
21
|
+
--border-thick: 1.5px solid var(--gray-300);
|
|
22
|
+
|
|
23
|
+
/* legacy aliases for components.css stubs */
|
|
24
|
+
--bg: var(--ivory);
|
|
25
|
+
--fg: var(--slate);
|
|
26
|
+
--muted: var(--gray-500);
|
|
27
|
+
--accent: var(--clay);
|
|
28
|
+
--border: 1px solid var(--gray-300);
|
|
29
|
+
--radius: var(--radius-panel);
|
|
30
|
+
--font: var(--sans);
|
|
11
31
|
--transition: 150ms ease;
|
|
12
32
|
}
|
|
13
|
-
@media (prefers-color-scheme: dark) {
|
|
14
|
-
:root {
|
|
15
|
-
--bg: #0b0b0c;
|
|
16
|
-
--fg: #f5f5f7;
|
|
17
|
-
--muted: #9aa0a6;
|
|
18
|
-
--accent: #60a5fa;
|
|
19
|
-
--border: #2a2a2c;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
33
|
* { box-sizing: border-box; }
|
|
23
|
-
html, body {
|
|
24
|
-
|
|
34
|
+
html, body {
|
|
35
|
+
margin: 0;
|
|
36
|
+
padding: 0;
|
|
37
|
+
background: var(--ivory);
|
|
38
|
+
color: var(--slate);
|
|
39
|
+
font-family: var(--sans);
|
|
40
|
+
font-size: 15px;
|
|
41
|
+
line-height: 1.6;
|
|
42
|
+
-webkit-font-smoothing: antialiased;
|
|
43
|
+
}
|
|
44
|
+
a { color: var(--clay); text-decoration: none; }
|
|
25
45
|
a:hover { text-decoration: underline; }
|
|
26
46
|
@media print {
|
|
27
47
|
details { display: block; }
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Template Gallery
|
|
2
|
+
|
|
3
|
+
Generated from `templates/manifest.json`. Upstream: `ThariqS/html-effectiveness@a1fb5673c26f87be9b833e1876cf4fd0f30f5f2d` (fetched 2026-05-13).
|
|
4
|
+
|
|
5
|
+
| ID | Title | Pattern | Use cases | Required slots |
|
|
6
|
+
|----|-------|---------|-----------|----------------|
|
|
7
|
+
| `01-exploration-code-approaches` | Code-Approaches Exploration | `comparison_board` | "compare implementations", "approach trade-offs", "design alternatives" | `title` |
|
|
8
|
+
| `02-exploration-visual-designs` | Visual Design Exploration | `comparison_board` | "compare designs", "UI alternatives", "visual options" | `title` |
|
|
9
|
+
| `03-code-review-pr` | PR Code Review Board | `code_review_board` | "PR review", "code review", "diff review" | `title` |
|
|
10
|
+
| `04-code-understanding` | Code Walkthrough | `knowledge_explorer` | "explain code", "walk through architecture", "trace logic" | `title` |
|
|
11
|
+
| `05-design-system` | Design System Sheet | `design_system_sheet` | "design tokens", "color palette", "typography" | `title` |
|
|
12
|
+
| `06-component-variants` | Component Variant Matrix | `design_system_sheet` | "component variants", "states gallery" | `title` |
|
|
13
|
+
| `07-prototype-animation` | Animation Prototype | `interactive_report` | "animation prototype", "motion preview" | `title` |
|
|
14
|
+
| `08-prototype-interaction` | Interaction Prototype | `interactive_report` | "interaction prototype", "ux flow" | `title` |
|
|
15
|
+
| `09-slide-deck` | Slide Deck | `slide_deck` | "slide deck", "presentation", "pitch" | `title` |
|
|
16
|
+
| `10-svg-illustrations` | SVG Illustration Gallery | `knowledge_explorer` | "illustrate concept", "svg gallery" | `title` |
|
|
17
|
+
| `11-status-report` | Status Report | `interactive_report` | "weekly status", "project update", "team digest", "monthly recap", "engineering status" | `title`, `date_range` |
|
|
18
|
+
| `12-incident-report` | Incident Report | `interactive_report` | "incident report", "post-mortem", "outage writeup" | `title` |
|
|
19
|
+
| `13-flowchart-diagram` | Flowchart Diagram | `knowledge_explorer` | "flowchart", "process diagram", "decision tree" | `title` |
|
|
20
|
+
| `14-research-feature-explainer` | Feature Explainer | `knowledge_explorer` | "explain feature", "feature deep-dive" | `title` |
|
|
21
|
+
| `15-research-concept-explainer` | Concept Explainer | `knowledge_explorer` | "explain concept", "tutorial", "primer" | `title` |
|
|
22
|
+
| `16-implementation-plan` | Implementation Plan | `annotated_timeline` | "implementation plan", "phased rollout", "roadmap" | `title` |
|
|
23
|
+
| `17-pr-writeup` | PR Writeup | `interactive_report` | "PR description", "release notes", "change writeup" | `title` |
|
|
24
|
+
| `18-editor-triage-board` | Triage Board | `kanban_board` | "bug triage", "issue board", "kanban" | `title` |
|
|
25
|
+
| `19-editor-feature-flags` | Feature Flags Matrix | `decision_matrix` | "feature flags", "rollout matrix" | `title` |
|
|
26
|
+
| `20-editor-prompt-tuner` | Prompt Tuner | `interactive_report` | "prompt tuning", "LLM config" | `title` |
|
|
27
|
+
|
|
28
|
+
_20 templates._
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { mkdirSync, rmSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const REPO_ROOT = resolve(HERE, '..', '..', '..');
|
|
7
|
+
export const ROOT = join(REPO_ROOT, '.tmp', 'html-effectiveness');
|
|
8
|
+
|
|
9
|
+
export function getTmpDir(purpose) {
|
|
10
|
+
if (!purpose || /[\\/]/.test(purpose)) {
|
|
11
|
+
throw new Error(`purpose must be a single path segment, got: ${purpose}`);
|
|
12
|
+
}
|
|
13
|
+
const dir = join(ROOT, purpose);
|
|
14
|
+
rmSync(dir, { recursive: true, force: true });
|
|
15
|
+
mkdirSync(dir, { recursive: true });
|
|
16
|
+
return dir;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function cleanup(purpose) {
|
|
20
|
+
rmSync(join(ROOT, purpose), { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function withTmp(purpose, fn) {
|
|
24
|
+
const dir = getTmpDir(purpose);
|
|
25
|
+
const onSig = () => {
|
|
26
|
+
try { cleanup(purpose); } finally { process.exit(130); }
|
|
27
|
+
};
|
|
28
|
+
process.once('SIGINT', onSig);
|
|
29
|
+
process.once('SIGTERM', onSig);
|
|
30
|
+
try {
|
|
31
|
+
return fn(dir);
|
|
32
|
+
} finally {
|
|
33
|
+
cleanup(purpose);
|
|
34
|
+
process.off('SIGINT', onSig);
|
|
35
|
+
process.off('SIGTERM', onSig);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Generate docs/template-gallery.md from templates/manifest.json.
|
|
3
|
+
// Idempotent. Run after editing manifest.
|
|
4
|
+
|
|
5
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
6
|
+
import { dirname, join, resolve } from 'node:path';
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
8
|
+
|
|
9
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const PLUGIN_ROOT = dirname(HERE);
|
|
11
|
+
|
|
12
|
+
function build() {
|
|
13
|
+
const manifest = JSON.parse(readFileSync(join(PLUGIN_ROOT, 'templates/manifest.json'), 'utf8'));
|
|
14
|
+
const meta = manifest._meta || {};
|
|
15
|
+
const rows = Object.entries(manifest)
|
|
16
|
+
.filter(([k]) => k !== '_meta')
|
|
17
|
+
.sort(([a], [b]) => a.localeCompare(b));
|
|
18
|
+
|
|
19
|
+
const lines = [];
|
|
20
|
+
lines.push('# Template Gallery');
|
|
21
|
+
lines.push('');
|
|
22
|
+
lines.push(`Generated from \`templates/manifest.json\`. Upstream: \`${meta.upstream_repo}@${meta.upstream_sha}\` (fetched ${meta.fetched_at}).`);
|
|
23
|
+
lines.push('');
|
|
24
|
+
lines.push('| ID | Title | Pattern | Use cases | Required slots |');
|
|
25
|
+
lines.push('|----|-------|---------|-----------|----------------|');
|
|
26
|
+
for (const [id, e] of rows) {
|
|
27
|
+
const reqSlots = Object.entries(e.slots || {})
|
|
28
|
+
.filter(([, s]) => (typeof s === 'object' ? s.required : false))
|
|
29
|
+
.map(([n]) => `\`${n}\``)
|
|
30
|
+
.join(', ') || '—';
|
|
31
|
+
const use = (e.use_cases || []).map((u) => `"${u}"`).join(', ');
|
|
32
|
+
lines.push(`| \`${id}\` | ${e.title} | \`${e.pattern}\` | ${use} | ${reqSlots} |`);
|
|
33
|
+
}
|
|
34
|
+
lines.push('');
|
|
35
|
+
lines.push(`_${rows.length} templates._`);
|
|
36
|
+
lines.push('');
|
|
37
|
+
return lines.join('\n');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function main() {
|
|
41
|
+
const out = join(PLUGIN_ROOT, 'docs/template-gallery.md');
|
|
42
|
+
mkdirSync(dirname(out), { recursive: true });
|
|
43
|
+
writeFileSync(out, build(), 'utf8');
|
|
44
|
+
process.stdout.write(out + '\n');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) main();
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeFileSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { getTmpDir, ROOT } from './_tmp.js';
|
|
6
|
+
|
|
7
|
+
const UPSTREAM_REPO = 'ThariqS/html-effectiveness';
|
|
8
|
+
const API_BASE = 'https://api.github.com';
|
|
9
|
+
const RAW_BASE = 'https://raw.githubusercontent.com';
|
|
10
|
+
|
|
11
|
+
async function ghFetch(url, accept = 'application/vnd.github+json') {
|
|
12
|
+
const headers = { 'Accept': accept, 'User-Agent': 'html-effectiveness-vendor' };
|
|
13
|
+
if (process.env.GITHUB_TOKEN) headers['Authorization'] = `Bearer ${process.env.GITHUB_TOKEN}`;
|
|
14
|
+
const res = await fetch(url, { headers });
|
|
15
|
+
if (!res.ok) {
|
|
16
|
+
throw new Error(`HTTP ${res.status} ${res.statusText} for ${url}`);
|
|
17
|
+
}
|
|
18
|
+
return res;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function fetchUpstreamFile(filename, ref = 'main') {
|
|
22
|
+
const url = `${RAW_BASE}/${UPSTREAM_REPO}/${ref}/${filename}`;
|
|
23
|
+
const res = await ghFetch(url, 'text/plain');
|
|
24
|
+
return await res.text();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function fetchUpstreamSha(ref = 'main') {
|
|
28
|
+
const url = `${API_BASE}/repos/${UPSTREAM_REPO}/commits/${ref}`;
|
|
29
|
+
const res = await ghFetch(url);
|
|
30
|
+
const json = await res.json();
|
|
31
|
+
return json.sha;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function listUpstreamFiles(ref = 'main') {
|
|
35
|
+
const url = `${API_BASE}/repos/${UPSTREAM_REPO}/contents?ref=${ref}`;
|
|
36
|
+
const res = await ghFetch(url);
|
|
37
|
+
const json = await res.json();
|
|
38
|
+
return json.filter((e) => e.type === 'file').map((e) => e.name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function extractParts(html) {
|
|
42
|
+
const styles = [];
|
|
43
|
+
const scripts = [];
|
|
44
|
+
let body = html;
|
|
45
|
+
body = body.replace(/<style[^>]*>([\s\S]*?)<\/style>/g, (_, css) => {
|
|
46
|
+
styles.push(css.trim());
|
|
47
|
+
return '';
|
|
48
|
+
});
|
|
49
|
+
body = body.replace(/<script[^>]*>([\s\S]*?)<\/script>/g, (_, js) => {
|
|
50
|
+
if (js.trim()) scripts.push(js.trim());
|
|
51
|
+
return '';
|
|
52
|
+
});
|
|
53
|
+
body = body
|
|
54
|
+
.replace(/<!doctype[^>]*>/i, '')
|
|
55
|
+
.replace(/<\/?html[^>]*>/gi, '')
|
|
56
|
+
.replace(/<head[\s\S]*?<\/head>/gi, '')
|
|
57
|
+
.replace(/<\/?body[^>]*>/gi, '');
|
|
58
|
+
return { styles, scripts, body: body.trim() };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function ensureWorkdir() {
|
|
62
|
+
return getTmpDir('extract');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function readFromWorkdir(name) {
|
|
66
|
+
return readFileSync(join(ROOT, 'extract', name), 'utf8');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function writeToWorkdir(dir, name, content) {
|
|
70
|
+
writeFileSync(join(dir, name), content);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function cli() {
|
|
74
|
+
const [, , cmd, arg] = process.argv;
|
|
75
|
+
if (cmd === 'fetch') {
|
|
76
|
+
if (!arg) { process.stderr.write('usage: extract.js fetch <file>\n'); process.exit(1); }
|
|
77
|
+
const dir = ensureWorkdir();
|
|
78
|
+
const html = await fetchUpstreamFile(arg);
|
|
79
|
+
writeToWorkdir(dir, arg, html);
|
|
80
|
+
process.stdout.write(`${join(dir, arg)}\n`);
|
|
81
|
+
} else if (cmd === 'sha') {
|
|
82
|
+
process.stdout.write(await fetchUpstreamSha() + '\n');
|
|
83
|
+
} else if (cmd === 'list') {
|
|
84
|
+
const files = await listUpstreamFiles();
|
|
85
|
+
process.stdout.write(files.join('\n') + '\n');
|
|
86
|
+
} else if (cmd === 'split') {
|
|
87
|
+
if (!arg) { process.stderr.write('usage: extract.js split <file>\n'); process.exit(1); }
|
|
88
|
+
const html = readFromWorkdir(arg);
|
|
89
|
+
const { styles, scripts, body } = extractParts(html);
|
|
90
|
+
const base = arg.replace(/\.html$/, '');
|
|
91
|
+
const dir = join(ROOT, 'extract');
|
|
92
|
+
writeToWorkdir(dir, `${base}.body.html`, body + '\n');
|
|
93
|
+
writeToWorkdir(dir, `${base}.styles.css`, styles.join('\n\n/* --- */\n\n') + '\n');
|
|
94
|
+
writeToWorkdir(dir, `${base}.scripts.js`, scripts.join('\n\n/* --- */\n\n') + '\n');
|
|
95
|
+
process.stdout.write(`${dir}/${base}.{body.html,styles.css,scripts.js}\n`);
|
|
96
|
+
} else {
|
|
97
|
+
process.stderr.write('usage: extract.js {fetch <file>|sha|list|split <file>}\n');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
103
|
+
cli().catch((e) => { process.stderr.write(e.stack + '\n'); process.exit(1); });
|
|
104
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
6
6
|
import { dirname, resolve, join } from 'node:path';
|
|
7
|
-
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
8
8
|
import { parseArgs } from 'node:util';
|
|
9
9
|
import { render as mustache } from './mustache.js';
|
|
10
10
|
|
|
@@ -173,4 +173,4 @@ function cli() {
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
if (import.meta.url ===
|
|
176
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) cli();
|
|
@@ -26,7 +26,7 @@ If the request fits a report-style output and rendering as HTML would be clearer
|
|
|
26
26
|
|
|
27
27
|
## Template catalog
|
|
28
28
|
|
|
29
|
-
20 templates ship with this plugin.
|
|
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
30
|
|
|
31
31
|
- `01` / `02` — exploration comparisons (code approaches, visual designs)
|
|
32
32
|
- `03` — code review board
|
|
@@ -77,7 +77,7 @@ Preserved from upstream `ThariqS/html-effectiveness`:
|
|
|
77
77
|
## Technical requirements
|
|
78
78
|
|
|
79
79
|
- Single `.html` file, fully self-contained.
|
|
80
|
-
- CSS variables for light
|
|
80
|
+
- CSS variables for theming (light-only baseline, matching upstream palette).
|
|
81
81
|
- System font stack and 150ms smooth transitions.
|
|
82
82
|
- Responsive design 375px–1440px.
|
|
83
83
|
- Semantic HTML5 with ARIA labels.
|
|
@@ -89,6 +89,6 @@ Preserved from upstream `ThariqS/html-effectiveness`:
|
|
|
89
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
90
|
- **Render error**: surface `template:slot expected <type> got <type>` to the user; fix the slot value; retry.
|
|
91
91
|
|
|
92
|
-
##
|
|
92
|
+
## Vendored templates
|
|
93
93
|
|
|
94
|
-
|
|
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.
|