From 6eec05858f3183821267f6598ff65dfd635a154b Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Fri, 8 May 2026 17:28:29 -0700 Subject: [PATCH] feat(ce-plan,_shared): add --html flag and shared HTML output reference Adds an opt-in `--html` flag to ce-plan and a shared HTML output reference at plugins/compound-engineering/skills/_shared/html-output.md that the remaining 13 document-producing ce-* skills can layer onto in follow-up PRs. Default ce-plan behavior is unchanged. When invoked with `--html` (or a bare `html` keyword for harnesses that strip dashes), ce-plan writes a self-contained HTML5 document at docs/plans/YYYY-MM-DD-NNN---plan.html with embedded CSS, real tables for Requirements traceability and Test Scenarios, inline SVG for diagrams, anchored navigation, status pills, dark-mode and mobile breakpoints. No external CSS, JS, fonts, or images. Phase 1 of a planned 6-phase rollout. Subsequent phases extend `--html` to ce-brainstorm, ce-strategy, ce-ideate, ce-debug, ce-doc-review, ce-code-review, ce-compound, ce-product-pulse, ce-sessions, plus the document tail. Each phase ships as its own PR after this lands and the shared infrastructure design is validated. --- plugins/compound-engineering/README.md | 2 +- .../skills/_shared/html-output.md | 619 ++++++++++++++++++ .../skills/ce-plan/SKILL.md | 47 +- .../ce-plan/references/html-plan-template.md | 251 +++++++ .../references/visual-communication.md | 14 + tests/fixtures/ce-plan/sample-plan.html | 326 +++++++++ tests/skill-agent-ce-prefix.test.ts | 10 +- tests/skills/ce-plan-html-output.test.ts | 121 ++++ 8 files changed, 1386 insertions(+), 4 deletions(-) create mode 100644 plugins/compound-engineering/skills/_shared/html-output.md create mode 100644 plugins/compound-engineering/skills/ce-plan/references/html-plan-template.md create mode 100644 tests/fixtures/ce-plan/sample-plan.html create mode 100644 tests/skills/ce-plan-html-output.test.ts diff --git a/plugins/compound-engineering/README.md b/plugins/compound-engineering/README.md index 78c416013..4fb8d74f9 100644 --- a/plugins/compound-engineering/README.md +++ b/plugins/compound-engineering/README.md @@ -26,7 +26,7 @@ The primary entry points for engineering work, invoked as slash commands. Detail | [`/ce-strategy`](../../docs/skills/ce-strategy.md) | Create or maintain `STRATEGY.md` — the product's target problem, approach, persona, key metrics, and tracks. Re-runnable to update. Read as grounding by `/ce-ideate`, `/ce-brainstorm`, and `/ce-plan` when present | | [`/ce-ideate`](../../docs/skills/ce-ideate.md) | Optional big-picture ideation: generate and critically evaluate grounded ideas, then route the strongest one into brainstorming | | [`/ce-brainstorm`](../../docs/skills/ce-brainstorm.md) | Interactive Q&A to think through a feature or problem and write a right-sized requirements doc before planning | -| [`/ce-plan`](../../docs/skills/ce-plan.md) | Create structured plans for any multi-step task -- software features, research workflows, events, study plans -- with automatic confidence checking | +| [`/ce-plan`](../../docs/skills/ce-plan.md) | Create structured plans for any multi-step task -- software features, research workflows, events, study plans -- with automatic confidence checking and optional `--html` read-mode output | | [`/ce-code-review`](../../docs/skills/ce-code-review.md) | Structured code review with tiered persona agents, confidence gating, and dedup pipeline | | [`/ce-work`](../../docs/skills/ce-work.md) | Execute work items systematically | | [`/ce-debug`](../../docs/skills/ce-debug.md) | Systematically find root causes and fix bugs -- traces causal chains, forms testable hypotheses, and implements test-first fixes | diff --git a/plugins/compound-engineering/skills/_shared/html-output.md b/plugins/compound-engineering/skills/_shared/html-output.md new file mode 100644 index 000000000..d944256c7 --- /dev/null +++ b/plugins/compound-engineering/skills/_shared/html-output.md @@ -0,0 +1,619 @@ +# Shared HTML Output Reference + +Use this reference when a document-producing skill supports an opt-in HTML view. The output is a single self-contained HTML5 file intended for human reading and sharing. Markdown remains the workflow source of truth unless the consuming skill explicitly supports HTML. + +## Document Skeleton + +Fill placeholders before writing the artifact. Keep the skeleton static unless a skill needs a section-specific override. + +```html + + + + + + {{title}} + + + +
+

{{skill_name}}

+

{{title}}

+

{{summary}}

+
+ {{frontmatter_pills}} +
+ +
+ + + +
+

{{origin_note}}

+
+ + +``` + +## Embedded CSS Theme + +Embed the CSS directly in the generated document. Do not link external stylesheets, fonts, scripts, or images. + +```css +:root { + color-scheme: light dark; + --bg: #f8fafc; + --surface: #ffffff; + --surface-soft: #f1f5f9; + --surface-strong: #e2e8f0; + --text: #111827; + --text-muted: #475569; + --border: #cbd5e1; + --accent: #0f766e; + --accent-soft: #ccfbf1; + --accent-text: #115e59; + --danger: #b91c1c; + --danger-soft: #fee2e2; + --warning: #a16207; + --warning-soft: #fef3c7; + --success: #166534; + --success-soft: #dcfce7; + --code-bg: #0f172a; + --code-text: #e2e8f0; + --shadow: 0 1px 2px rgb(15 23 42 / 0.08); + --radius: 8px; +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + margin: 0; + background: var(--bg); + color: var(--text); + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + font-size: 16px; + line-height: 1.6; +} + +a { + color: var(--accent); + text-decoration-thickness: 0.08em; + text-underline-offset: 0.18em; +} + +.doc-header, +.doc-footer { + max-width: 1180px; + margin: 0 auto; + padding: 32px 24px 24px; +} + +.doc-header h1 { + margin: 0; + font-size: clamp(2rem, 4vw, 3.5rem); + line-height: 1.05; + letter-spacing: 0; +} + +.eyebrow { + margin: 0 0 10px; + color: var(--accent-text); + font-size: 0.78rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.summary { + max-width: 760px; + margin: 16px 0 0; + color: var(--text-muted); + font-size: 1.05rem; +} + +.pill-row { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 22px; +} + +.pill { + display: inline-flex; + align-items: center; + min-height: 28px; + border: 1px solid var(--border); + border-radius: 999px; + padding: 3px 10px; + background: var(--surface); + color: var(--text-muted); + font-size: 0.82rem; + font-weight: 650; +} + +.pill-status-active, +.pill-type-feat { + border-color: color-mix(in srgb, var(--accent) 35%, var(--border)); + background: var(--accent-soft); + color: var(--accent-text); +} + +.pill-status-draft, +.pill-type-refactor { + background: var(--surface-soft); +} + +.pill-status-blocked, +.pill-type-fix { + border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); + background: var(--danger-soft); + color: var(--danger); +} + +.layout { + display: grid; + grid-template-columns: minmax(180px, 240px) minmax(0, 1fr); + gap: 24px; + max-width: 1180px; + margin: 0 auto; + padding: 0 24px 40px; +} + +.toc { + position: sticky; + top: 16px; + align-self: start; + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 10px; + background: var(--surface); + box-shadow: var(--shadow); +} + +.toc a { + display: block; + border-radius: 6px; + padding: 7px 9px; + color: var(--text-muted); + font-size: 0.9rem; + text-decoration: none; +} + +.toc a:hover, +.toc a:focus { + background: var(--surface-soft); + color: var(--text); +} + +main { + min-width: 0; +} + +section, +article, +.notice, +.risk, +.table-wrap { + border: 1px solid var(--border); + border-radius: var(--radius); + background: var(--surface); + box-shadow: var(--shadow); +} + +section { + margin-bottom: 18px; + padding: 24px; +} + +article { + margin-top: 14px; + padding: 20px; +} + +h2, +h3, +h4 { + margin: 0 0 12px; + line-height: 1.25; + letter-spacing: 0; +} + +h2 { + font-size: 1.45rem; +} + +h3 { + font-size: 1.12rem; +} + +p, +ul, +ol { + margin-top: 0; +} + +ul, +ol { + padding-left: 1.35rem; +} + +.notice { + margin-bottom: 18px; + padding: 14px 16px; + background: var(--accent-soft); + color: var(--accent-text); +} + +.risk { + margin-top: 12px; + padding: 14px 16px; +} + +.risk-high { + border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); + background: var(--danger-soft); +} + +.risk-medium { + border-color: color-mix(in srgb, var(--warning) 40%, var(--border)); + background: var(--warning-soft); +} + +.status-ok { + color: var(--success); + font-weight: 700; +} + +.table-wrap { + overflow-x: auto; + margin: 14px 0; +} + +table { + width: 100%; + min-width: 620px; + border-collapse: collapse; + font-size: 0.94rem; +} + +thead { + background: var(--surface-soft); +} + +th, +td { + border-bottom: 1px solid var(--border); + padding: 10px 12px; + text-align: left; + vertical-align: top; +} + +th { + color: var(--text); + font-weight: 700; +} + +tbody tr:nth-child(even) { + background: color-mix(in srgb, var(--surface-soft) 55%, transparent); +} + +code, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; +} + +code { + border-radius: 5px; + padding: 0.12em 0.34em; + background: var(--surface-soft); +} + +pre { + overflow-x: auto; + border-radius: var(--radius); + padding: 14px 16px; + background: var(--code-bg); + color: var(--code-text); + font-size: 0.9rem; + line-height: 1.5; +} + +pre code { + padding: 0; + background: transparent; + color: inherit; +} + +.token-keyword { color: #93c5fd; } +.token-string { color: #86efac; } +.token-comment { color: #94a3b8; } +.token-symbol { color: #fbbf24; } + +details { + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 10px 12px; + background: var(--surface-soft); +} + +summary { + cursor: pointer; + font-weight: 700; +} + +.diagram { + width: 100%; + height: auto; + margin: 12px 0; +} + +.diagram text { + fill: currentColor; + font-family: ui-sans-serif, system-ui, sans-serif; + font-size: 13px; +} + +.doc-footer { + color: var(--text-muted); + font-size: 0.9rem; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg: #0b1120; + --surface: #111827; + --surface-soft: #1f2937; + --surface-strong: #334155; + --text: #f8fafc; + --text-muted: #cbd5e1; + --border: #334155; + --accent: #2dd4bf; + --accent-soft: #143a3a; + --accent-text: #99f6e4; + --danger: #fca5a5; + --danger-soft: #3f1d1d; + --warning: #facc15; + --warning-soft: #3b2f13; + --success: #86efac; + --success-soft: #12351f; + --code-bg: #020617; + --code-text: #e2e8f0; + --shadow: 0 1px 2px rgb(0 0 0 / 0.35); + } +} + +@media (max-width: 768px) { + .doc-header, + .doc-footer, + .layout { + padding-left: 16px; + padding-right: 16px; + } + + .layout { + display: block; + } + + .toc { + position: static; + margin-bottom: 16px; + } + + section { + padding: 18px; + } + + article { + padding: 16px; + } + + table { + min-width: 0; + } + + thead { + display: none; + } + + table, + tbody, + tr, + td { + display: block; + width: 100%; + } + + tr { + border-bottom: 1px solid var(--border); + padding: 8px 0; + } + + td { + border-bottom: 0; + padding: 6px 10px; + } + + td::before { + content: attr(data-label); + display: block; + color: var(--text-muted); + font-size: 0.76rem; + font-weight: 700; + text-transform: uppercase; + } +} +``` + +## Frontmatter Contract + +Preserve frontmatter in two places: + +- Human-readable pills in the header, one chip per top-level frontmatter key that is useful to scan. +- Machine-readable JSON inside ` + + +
+ + +
+ + +
+

Summary

+

[Forward-looking summary of the planned work.]

+
+ +
+

Problem Frame

+

[Situational context and pain that motivate the plan.]

+
+ +
+

Requirements

+
+ + + + + + + + + + + + + + + +
R-IDRequirementOrigin trace
R1[Requirement or success criterion][Prompt, origin doc, issue, or assumption]
+
+
+ +
+

Scope Boundaries

+
    +
  • [Explicit non-goal or exclusion]
  • +
+
+ +
+

Context & Research

+

Relevant Code and Patterns

+
    +
  • [Existing file, class, component, or pattern to follow]
  • +
+

Institutional Learnings

+
    +
  • [Relevant docs/solutions insight]
  • +
+

External References

+
    +
  • [External docs or best-practice source, if used]
  • +
+
+ +
+

Key Technical Decisions

+
    +
  • [Decision]: [Rationale]
  • +
+
+ +
+

Implementation Units

+ +
+

U1. [Name]

+

Goal: [What this unit accomplishes]

+

Requirements: [R1, R2]

+

Dependencies: [None / U1 / external prerequisite]

+ +

Files

+
    +
  • Create: path/to/new_file
  • +
  • Modify: path/to/existing_file
  • +
  • Test: path/to/test_file
  • +
+ +

Approach

+
    +
  • [Key design or sequencing decision]
  • +
+ +

Test Scenarios

+
+ + + + + + + + + + + + + + + +
CategoryScenarioExpected
Happy path[Specific input/action][Expected outcome]
+
+ +

Acceptance

+
    +
  • [Outcome that should hold when this unit is complete]
  • +
+
+
+ +
+

System-Wide Impact

+
    +
  • Interaction graph: [Callbacks, middleware, observers, or entry points]
  • +
  • Error propagation: [How failures should travel across layers]
  • +
  • State lifecycle risks: [Partial-write, cache, duplicate, or cleanup concerns]
  • +
  • API surface parity: [Other interfaces that may require the same change]
  • +
+
+ +
+

Test Scenarios

+
+ + + + + + + + + + + + + + + + + +
UnitCategoryScenarioExpected
U1Happy path[Specific input/action][Expected outcome]
+
+
+ +
+

Risks & Open Questions

+ +

Deferred to Implementation

+
    +
  • [Question or unknown]: [Why it is intentionally deferred]
  • +
+
+ +
+

Sources & References

+ +
+
+
+ +
+

Generated by ce-plan. Markdown remains the workflow source until downstream skills support HTML inputs.

+
+ + +``` + +## Rendering Rules + +- Preserve every applicable section from `references/plan-template.md`; omit only sections that the markdown template marks optional and inapplicable. +- Render Implementation Units as `
`, where `N` matches the stable U-ID. +- Render Requirements traceability and Test Scenarios as real tables with ``, ``, and scoped header cells. +- Use `