diff --git a/.claude/commands/own/init.md b/.claude/commands/own/init.md index 64fa11d..1979f67 100644 --- a/.claude/commands/own/init.md +++ b/.claude/commands/own/init.md @@ -730,7 +730,95 @@ To install (takes 30 seconds each): πŸ“– Full setup guide: ownyourcode/guides/context7-setup.md ``` -3. **If available:** Continue silently to Phase 1. +3. **If available:** Continue silently to Phase 0.5. + +--- + +### Phase 0.5: HTML Theme Setup (v2.4.0+) + +Set up the visual theme that all generated HTML files will use. This phase +runs ONCE per project (idempotent: detects existing `.theme/` and skips). + +**Design note:** This phase deliberately does NOT check for or attempt to +install the `frontend-design` plugin. Runtime testing during PR 1 demonstrated +that programmatic plugin detection inside a slash-command flow is unreliable +(stale cache directories from previous uninstalls, agent assumptions, no +in-flow Skill invocation). Instead, this phase always seeds the bundled +fallback CSS β€” which the PR reviewer praised as production-quality β€” and +surfaces an optional upgrade path in the user-facing summary. Users who +want premium styling install the plugin themselves and run `/own:theme` +to regenerate. + +#### Step 1: Detect existing theme + +**Execute this bash command via the Bash tool. Decide based on the literal stdout:** + +```bash +test -d ownyourcode/.theme && echo "exists" || echo "missing" +``` + +- Output is `exists` β†’ Skip the entire Phase 0.5. Continue to Phase 1. +- Output is `missing` β†’ Continue to Step 2. + +#### Step 2: Create `.theme/` directory and seed files from the bundle + +Execute these bash commands via the Bash tool: + +```bash +mkdir -p ownyourcode/.theme/.history +cp ownyourcode/templates/html/theme-prompt.md.template ownyourcode/.theme/theme-prompt.md +cp ownyourcode/templates/html/theme-fallback.css ownyourcode/.theme/theme.css +``` + +(The HTML templates were copied into the user's project during install β€” see `scripts/project-install.sh` STEP 7.5. They live at `ownyourcode/templates/html/` relative to the project root.) + +#### Step 3: Update manifest + +Add this block to `.claude/ownyourcode-manifest.json`: + +```json +{ + "theme": { + "fallback_mode": true, + "last_updated": "[ISO timestamp]", + "prompt_source": "default" + } +} +``` + +- `fallback_mode` is `true` until the user regenerates `theme.css` via `/own:theme` with the `frontend-design` plugin installed. +- `prompt_source` is `"default"` for the bundled prompt; it becomes `"custom"` if the user supplies their own prompt through `/own:theme`. + +#### Step 4: Inform the user with the optional upgrade hint + +Show this message exactly: + +``` +🎨 Theme set up: ownyourcode/.theme/ + β”œβ”€β”€ theme-prompt.md (default Apple Documentation aesthetic) + └── theme.css (bundled fallback CSS β€” production-quality default) + +All HTML files generated by /own:feature will reference this theme. + +──────────────────────────────────────────────────────────────────── +✨ Make it even better (optional, recommended for portfolio work) +──────────────────────────────────────────────────────────────────── + +OwnYourCode ships with a hand-authored fallback CSS that already looks +great. For *fully custom* styling generated from your theme prompt β€” with +Anthropic's official design framework β€” install the `frontend-design` +plugin yourself in a separate message: + + /plugin install frontend-design@claude-plugins-official + +Then run `/own:theme` to regenerate `theme.css` based on your prompt. +You can change the prompt and re-roll the design anytime. + +Skip this for now if you're just trying things out β€” the bundled fallback +is ready to use. +``` + +Continue silently to Phase 1. --- diff --git a/.claude/commands/own/theme.md b/.claude/commands/own/theme.md new file mode 100644 index 0000000..70d1cae --- /dev/null +++ b/.claude/commands/own/theme.md @@ -0,0 +1,326 @@ +--- +name: theme +description: View, change, or regenerate the visual theme of your OwnYourCode HTML files (v2.4.0+) +allowed-tools: Read, Write, Edit, Bash, Glob, AskUserQuestion, Skill +--- + +# /own:theme + +> ⚠️ **PLAN MODE WARNING:** Toggle plan mode off before running this command (`shift+tab`). OwnYourCode commands don't work correctly with plan mode. + +Manage the visual styling of your project's HTML files (mission, stack, roadmap, spec, design, tasks). + +## Overview + +This command lets you: + +1. **View** the current theme prompt +2. **Change** the theme by giving a custom design prompt +3. **Pick** a bundled preset (apple-light, apple-dark, terminal, paper, brutalist) +4. **Regenerate** the theme CSS using the existing prompt (re-roll the design) +5. **Revert** to a previous theme via `/own:theme --revert` + +**The theme is a single CSS file.** All 6 HTML files reference it via ``, so changing the theme is instant β€” no HTML files need regenerating. + +## Files affected + +- `ownyourcode/.theme/theme-prompt.md` β€” the active theme prompt +- `ownyourcode/.theme/theme.css` β€” the generated CSS (overwritten on each run) +- `ownyourcode/.theme/.history/[ISO-timestamp]/` β€” backup of previous theme prompt + CSS (created on every write) +- `.claude/ownyourcode-manifest.json` β€” `theme.fallback_mode` flag, `theme.last_updated` timestamp + +## Hard constraints + +- **Theme = visual styling ONLY.** This command must never alter the workflow, the SDD purpose of any HTML file, or any data-* contract used by other commands. If the user's custom prompt suggests workflow changes, reject those modifications and surface a warning. +- **Backup-before-write is non-negotiable.** Always copy current `theme-prompt.md` and `theme.css` to `.history/[timestamp]/` BEFORE generating new ones. Enables revert. +- **Frontend-design plugin is a soft dependency.** If unavailable, fall back to `theme-fallback.css` (shipped with the install) but never block the user. + +--- + +## Execution Flow + +### Phase 0: Argument detection + +Check if the user invoked with `--revert`: + +- `/own:theme --revert` β†’ jump to **Revert Flow** section below +- `/own:theme` (no args) β†’ continue to Phase 1 + +### Phase 1: Pre-flight check + +Run these checks silently: + +1. **Verify install:** `ownyourcode/.theme/` directory exists. + - If not, this project doesn't have a theme set up yet. Tell the user: + > "Your project doesn't have an HTML theme configured. + > + > - If this is a new project on v2.4.0+, run `/own:init` to set up the theme. + > - If you have an existing Markdown project to convert, `/own:migrate` will land in a future v2.4.0 PR β€” until then, you can manually create `ownyourcode/.theme/` by running `/own:init` in a clean copy." + - **STOP execution.** + +2. **Read current state:** Read `ownyourcode/.theme/theme-prompt.md` (first 8 lines for preview). + +3. **Detect frontend-design plugin:** Run silently: + ```bash + ls ~/.claude/plugins/cache/claude-plugins-official/frontend-design 2>/dev/null + ``` + - Exists β†’ `plugin_available = true` + - Missing β†’ `plugin_available = false`. Note: fallback CSS will be used. + +### Phase 2: Show current state + action menu + +Display: + +``` +🎨 Current theme prompt (preview): + + [first 8 lines of theme-prompt.md, indented] + ... + +Plugin status: [βœ“ frontend-design installed | ⚠️ using fallback CSS] +Last updated: [theme.last_updated from manifest] +``` + +Then use `AskUserQuestion` to present the action menu: + +``` +Question: "What do you want to do?" + +Options: +1. Change theme prompt β€” Provide your own design description (free text) +2. Pick a preset β€” Choose from bundled presets (apple-light, apple-dark, etc.) +3. Regenerate current β€” Re-roll the CSS using the existing prompt +4. View full prompt β€” Read-only display of the current theme-prompt.md +``` + +Branch to the matching phase below. + +### Phase 3a: Change theme prompt (free text) + +Ask the user in chat (NOT AskUserQuestion β€” free text required): + +> "Describe how you want OwnYourCode to look. +> +> Tip: be specific. Mention typography, exact colors, vibe, dark/light mode behavior. Vague prompts ('modern and clean') produce generic AI-looking output. +> +> Example: +> 'A warm paper-like document. Serif headings (Charter or Georgia). Soft cream background (#F8F4E8). No dark mode. Slim 1px borders in #D4CFC0. Inline tables with no zebra striping.' +> +> Your prompt:" + +Wait for the user's free-text response. Then: + +1. Run **Phase 5: Backup-before-write** +2. Write the new prompt to `ownyourcode/.theme/theme-prompt.md` +3. Run **Phase 6: Regenerate CSS** +4. Run **Phase 7: Confirm + preview** + +### Phase 3b: Pick a preset + +Use AskUserQuestion to list the bundled presets. (Presets are stored in `ownyourcode/templates/html/presets/[name].md` β€” load names by listing that directory.) + +``` +Question: "Pick a preset:" + +Options (load dynamically from ownyourcode/templates/html/presets/): +1. apple-light β€” Light-mode Apple Documentation aesthetic +2. apple-dark β€” Dark-mode Apple Documentation aesthetic +3. terminal β€” Retro terminal aesthetic (mono, green-on-black) +4. paper β€” Print-document aesthetic (serif, paper background) +``` + +(If presets don't yet exist in the install β€” v2.4.0 may ship without all presets β€” only show those that exist.) + +When the user picks one: + +1. Run **Phase 5: Backup-before-write** +2. Copy `ownyourcode/templates/html/presets/[name].md` β†’ `ownyourcode/.theme/theme-prompt.md` +3. Run **Phase 6: Regenerate CSS** +4. Run **Phase 7: Confirm + preview** + +### Phase 3c: Regenerate current + +No prompt change β€” use the existing `theme-prompt.md`. Useful for re-rolling when frontend-design produces a result the user doesn't love. + +1. Run **Phase 5: Backup-before-write** +2. (No prompt copy β€” leave `theme-prompt.md` unchanged) +3. Run **Phase 6: Regenerate CSS** +4. Run **Phase 7: Confirm + preview** + +### Phase 3d: View full prompt + +Read-only display. Read `ownyourcode/.theme/theme-prompt.md` and show the entire content: + +``` +πŸ“„ Current theme prompt (ownyourcode/.theme/theme-prompt.md): + +[full file content, fenced as a code block] + +To change this prompt, re-run /own:theme and pick "Change theme prompt". +``` + +**STOP execution.** No backup, no regeneration. + +--- + +### Phase 5: Backup-before-write + +Generate a timestamp: `BACKUP_TS=$(date -u +"%Y-%m-%dT%H-%M-%SZ")`. + +Create backup directory and copy current state: + +```bash +BACKUP_DIR="ownyourcode/.theme/.history/${BACKUP_TS}" +mkdir -p "$BACKUP_DIR" +cp ownyourcode/.theme/theme-prompt.md "$BACKUP_DIR/theme-prompt.md" 2>/dev/null +cp ownyourcode/.theme/theme.css "$BACKUP_DIR/theme.css" 2>/dev/null +``` + +Tell the user (briefly): `"πŸ“¦ Previous theme backed up to .theme/.history/${BACKUP_TS}/"` + +### Phase 6: Regenerate CSS + +**If `plugin_available = true`:** + +Invoke the `frontend-design` skill with the prompt: + +``` +Skill: frontend-design (from plugin claude-plugins-official:frontend-design) +Input: contents of ownyourcode/.theme/theme-prompt.md +Output target: ownyourcode/.theme/theme.css +Additional constraint to inject into the skill's prompt: + "Generate ONLY a CSS file. The CSS must style the following semantic + classes used by OwnYourCode HTML templates: [list selectors from + theme-fallback.css]. Do NOT generate HTML, JS, or any other files. + Honor prefers-color-scheme if the prompt mentions dark mode." +``` + +**If `plugin_available = false`:** + +Tell the user: + +> "⚠️ The `frontend-design` plugin isn't installed. Using the bundled fallback CSS, which approximates the prompt's aesthetic but isn't custom-generated. +> +> To get a fully custom theme based on your prompt, install the plugin: +> /plugin install frontend-design@claude-plugins-official +> +> Then re-run /own:theme." + +Then copy `ownyourcode/templates/html/theme-fallback.css` β†’ `ownyourcode/.theme/theme.css`. + +Update manifest: `theme.fallback_mode = true`. + +### Phase 7: Confirm + preview offer + +Display: + +``` +βœ… Theme updated. + + Prompt: ownyourcode/.theme/theme-prompt.md + CSS: ownyourcode/.theme/theme.css + Backup: ownyourcode/.theme/.history/${BACKUP_TS}/ + +All 6 HTML files now use the new theme (no regeneration needed β€” +they reference theme.css via ). + +To revert: /own:theme --revert +``` + +Then ask: + +``` +Question: "Want to preview the new theme in your browser?" + +Options: +1. Yes β€” open mission.html now +2. No β€” I'll check it later +``` + +If yes, open the file using the platform-appropriate command. Detect the OS and branch: + +```bash +# Detect platform and open mission.html in the default browser. +case "$(uname -s)" in + Darwin*) open ownyourcode/product/mission.html ;; + Linux*) xdg-open ownyourcode/product/mission.html ;; + CYGWIN*|MINGW*|MSYS*) start ownyourcode/product/mission.html ;; + *) echo "Open this file manually: ownyourcode/product/mission.html" ;; +esac +``` + +On Windows PowerShell sessions (where `uname` may be absent), use: + +```powershell +Start-Process "ownyourcode/product/mission.html" +``` + +If no preview tool is available on the host, surface the path so the user can open it themselves rather than silently no-op. + +Update manifest: `theme.last_updated = [ISO timestamp]`. + +**END.** + +--- + +## Revert Flow (`/own:theme --revert`) + +### Step 1: List available backups + +```bash +ls -1t ownyourcode/.theme/.history/ 2>/dev/null +``` + +If empty: +> "No theme backups found. Nothing to revert to." + +**STOP.** + +### Step 2: Present backups via AskUserQuestion + +Show up to 4 most recent backups (newer first). Format each label as the ISO timestamp + first 30 chars of that backup's prompt for context: + +``` +Question: "Which theme do you want to restore?" + +Options: +1. 2026-05-28T14-12-30Z β€” "A warm paper-like document. Serif…" +2. 2026-05-27T22-08-15Z β€” "Default OwnYourCode Theme β€” Apple…" +... +``` + +If more than 4 exist, add a "Show more" option that lists all in chat. + +### Step 3: Restore selected backup + +Copy backup files back to active location (and backup CURRENT state first, so user can undo a revert): + +```bash +CURRENT_TS=$(date -u +"%Y-%m-%dT%H-%M-%SZ") +mkdir -p "ownyourcode/.theme/.history/${CURRENT_TS}-pre-revert" +cp ownyourcode/.theme/theme-prompt.md "ownyourcode/.theme/.history/${CURRENT_TS}-pre-revert/" +cp ownyourcode/.theme/theme.css "ownyourcode/.theme/.history/${CURRENT_TS}-pre-revert/" + +cp "ownyourcode/.theme/.history/${SELECTED_TS}/theme-prompt.md" ownyourcode/.theme/theme-prompt.md +cp "ownyourcode/.theme/.history/${SELECTED_TS}/theme.css" ownyourcode/.theme/theme.css +``` + +### Step 4: Confirm + +``` +βœ… Theme reverted to ${SELECTED_TS}. + +Your previous theme was backed up to .history/${CURRENT_TS}-pre-revert/ +in case you want to undo this revert. +``` + +**END.** + +--- + +## Important Notes + +1. **Never edit theme.css by hand.** Edit `theme-prompt.md` and re-run `/own:theme`. Hand-edits will be overwritten next regenerate. +2. **The theme prompt is a CSS spec, not a Markdown formatting choice.** It tells `frontend-design` how to generate CSS rules β€” be specific. +3. **History grows.** `.theme/.history/` can accumulate. Future enhancement: `/own:theme --gc` to prune backups older than N days. Not in v2.4.0. +4. **Custom prompts that try to change semantics (e.g., "hide the checkboxes") MUST be rejected.** The theme is visual only β€” never alter the data-* contracts. Surface a warning if a prompt seems to violate this. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6691dc0..063a9fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ All notable changes to OwnYourCode will be documented in this file. ### Added +#### v2.4.0 β€” HTML SDD Migration (Foundation β€” PR 1 of 5) +- **HTML Template Bundle:** Six `.html.template` files in `core/templates/html/` defining the semantic structure of the v2.4.0 HTML-canonical SDD workflow (`mission`, `stack`, `roadmap`, `spec`, `design`, `tasks`). Each template encodes a `data-*` mutation contract so Claude's existing `Edit` tool β€” not an external HTML parser β€” performs all state mutations and progress counts (Option D design from #9). +- **Default Theme Assets:** `theme-prompt.md.template` shipping an Apple Documentation aesthetic as the default prompt consumed by the `frontend-design` plugin, plus a hand-authored `theme-fallback.css` covering every semantic class and `data-*` selector for users without the plugin. Light + dark mode parity via `prefers-color-scheme`. +- **`/own:theme` Command:** New slash command for managing the visual styling of HTML SDD files. Four user actions (change prompt / pick preset / regenerate / view) plus `/own:theme --revert` for restoring any timestamped backup. Every write is backup-first via `ownyourcode/.theme/.history/[ISO-timestamp]/`. +- **`/own:init` Phase 0.5:** New idempotent phase inserted between the MCP Check and Detection phases. Seeds `ownyourcode/.theme/` with the bundled theme prompt and `theme-fallback.css` as the project's initial `theme.css`, then surfaces a prominent opt-in upgrade hint pointing users to `/plugin install frontend-design@claude-plugins-official` followed by `/own:theme` for fully custom styling. Phase deliberately does not attempt programmatic plugin detection or auto-install β€” runtime testing during PR 1 showed those paths are unreliable inside a slash-command flow (stale plugin cache directories, no in-flow Skill invocation). The deterministic fallback-first design ships instead; plugin-generated styling is a user-driven upgrade, not an automatic mid-flow dependency. +- **Install Script Updates:** New STEP 7.5 in both `project-install.sh` and `project-install.ps1` copies the HTML template bundle from the OwnYourCode source repo to `ownyourcode/templates/html/` inside each user's project. + +> Note: PR 1 ships **infrastructure only**. `/own:init` Phase 6 and `/own:feature` still write Markdown until PR 2 and PR 3 activate HTML output. Existing projects see zero behavior change. + #### Repository Infrastructure - **Claude PR Review Gate:** Every PR targeting `main` is now automatically reviewed by Claude against the OwnYourCode standards (P/S/T/X/D rule set across Philosophy, Structure, Tooling, Security, and Documentation), the 4 Protocols, and the universal-audience product mission. The reviewer's system prompt lives in `.github/CLAUDE_REVIEWER.md` and is isolated from the workflow YAML for fast iteration. Reviewer enforces an explicit `VERDICT:` contract (`APPROVE` / `REQUEST_CHANGES` / `COMMENT`) so branch protection can gate merges on the verdict. - **`@claude` Tag Responder:** Any write-access user can now mention `@claude` in a PR/issue comment, an inline review comment, or a formal PR review to summon Claude for in-thread Q&A with full context (latest PR diff, full comment thread, PR/issue description). Complementary to the auto-review gate β€” different concern, different workflow file (`.github/workflows/claude-tag.yml`), no system prompt (uses the action's default conversational tag mode). Tool surface is read-and-comment only (no `Edit`/`Write`/shell-wildcards) and the trigger is gated by the action's built-in write-access check. diff --git a/README.md b/README.md index 5b7c691..8e900d2 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ Learnings compound across projects. Patterns that worked. Mistakes you won't rep | -------------- | ---------------------------------- | | `/own:status` | Check progress, tasks, and career stats | | `/own:profile` | View or change your profile | +| `/own:theme` | Manage HTML theme styling (v2.4.0+) | | `/own:test` | Guide through writing tests | | `/own:docs` | Guide through writing documentation | diff --git a/core/templates/html/design.html.template b/core/templates/html/design.html.template new file mode 100644 index 0000000..e7d2887 --- /dev/null +++ b/core/templates/html/design.html.template @@ -0,0 +1,126 @@ + + + + + + + {{FEATURE_TITLE}} β€” Technical Design + + + + +
+

Phase {{PHASE_N}} β€” {{PHASE_NAME}} β€” Technical Design

+

{{FEATURE_TITLE}}

+

Generated: {{ISO_DATE}}

+
+ +
+ +
+

Architecture Overview

+

{{ARCHITECTURE_OVERVIEW}}

+
+
{{ARCHITECTURE_DIAGRAM}}
+
{{DIAGRAM_CAPTION}}
+
+
+ +
+

Data Flow

+

{{DATA_FLOW_DESCRIPTION}}

+
    +
  1. {{FLOW_STEP_1}}
  2. +
  3. {{FLOW_STEP_2}}
  4. +
  5. {{FLOW_STEP_3}}
  6. +
+
+ +
+

Component Breakdown

+ + + + + + + + + + + + + + + + +
ComponentResponsibilityOwns
{{COMPONENT_1_NAME}}{{COMPONENT_1_RESPONSIBILITY}}{{COMPONENT_1_OWNS}}
{{COMPONENT_2_NAME}}{{COMPONENT_2_RESPONSIBILITY}}{{COMPONENT_2_OWNS}}
+
+ +
+

Trade-offs & Decisions

+ +
+

{{TRADE_OFF_1_TITLE}}

+

{{TRADE_OFF_1_CONTEXT}}

+

Chosen: {{TRADE_OFF_1_CHOSEN}}

+

Rejected: {{TRADE_OFF_1_REJECTED}}

+

Why: {{TRADE_OFF_1_REASONING}}

+
+ +
+

{{TRADE_OFF_2_TITLE}}

+

{{TRADE_OFF_2_CONTEXT}}

+

Chosen: {{TRADE_OFF_2_CHOSEN}}

+

Rejected: {{TRADE_OFF_2_REJECTED}}

+

Why: {{TRADE_OFF_2_REASONING}}

+
+
+ +
+

File Structure

+
{{FILE_TREE}}
+
+ +
+

Open Questions

+

Decisions deferred until implementation:

+ +
+ +
+ + + + + diff --git a/core/templates/html/mission.html.template b/core/templates/html/mission.html.template new file mode 100644 index 0000000..0761b56 --- /dev/null +++ b/core/templates/html/mission.html.template @@ -0,0 +1,78 @@ + + + + + + + {{PROJECT_NAME}} β€” Mission + + + + +
+

Project Mission

+

{{PROJECT_NAME}}

+

Generated: {{ISO_DATE}}

+
+ +
+ +
+

The Problem

+

{{PROBLEM_STATEMENT}}

+
+ +
+

Who Is This For?

+

{{AUDIENCE}}

+
+ +
+

Definition of Done

+

When these things work, the project is COMPLETE:

+ + +
+ + {{DOD_ITEM_1}} +
+ +
+ + {{DOD_ITEM_2}} +
+ +
+ + {{DOD_ITEM_3}} +
+
+ +
+

Why This Matters

+

{{WHY_THIS_MATTERS}}

+
+ +
+ + + + + diff --git a/core/templates/html/roadmap.html.template b/core/templates/html/roadmap.html.template new file mode 100644 index 0000000..96a2f6c --- /dev/null +++ b/core/templates/html/roadmap.html.template @@ -0,0 +1,96 @@ + + + + + + + {{PROJECT_NAME}} β€” Roadmap + + + + +
+

Project Roadmap

+

{{PROJECT_NAME}}

+

Generated: {{ISO_DATE}}

+
+ +
+ +

{{INTRO_PARAGRAPH}}

+ + + +
+

Phase 1: Foundation

+

Priority: HIGH

+

{{PHASE_1_DESCRIPTION}}

+ +
+ +
+

Phase 2: Core Features

+

Priority: MEDIUM

+

{{PHASE_2_DESCRIPTION}}

+ +
+ +
+

Phase 3: Polish & Deploy

+

Priority: LOW

+

Testing, documentation, deployment.

+ +
+ +
+ + + + + diff --git a/core/templates/html/spec.html.template b/core/templates/html/spec.html.template new file mode 100644 index 0000000..ee98c5b --- /dev/null +++ b/core/templates/html/spec.html.template @@ -0,0 +1,109 @@ + + + + + + + {{FEATURE_TITLE}} β€” Spec + + + + +
+

Phase {{PHASE_N}} β€” {{PHASE_NAME}} β€” Specification

+

{{FEATURE_TITLE}}

+

Generated: {{ISO_DATE}}

+
+ +
+ +
+

Overview

+

{{OVERVIEW}}

+
+ +
+

Why This Feature?

+

{{MOTIVATION}}

+
+ +
+

User Stories

+ +
+

As a {{ACTOR_1}}

+

I want {{WANT_1}}

+

So that {{SO_THAT_1}}

+
+ +
+

As a {{ACTOR_2}}

+

I want {{WANT_2}}

+

So that {{SO_THAT_2}}

+
+
+ +
+

Acceptance Criteria

+

This feature is "done" when:

+ +
+ +
+

Edge Cases

+

Scenarios the implementation MUST handle:

+ +
+ +
+

Out of Scope

+

Explicitly NOT in this feature (prevents scope creep):

+ +
+ +
+

Open Questions

+

Decisions to resolve before/during implementation:

+ +
+ +
+ + + + + diff --git a/core/templates/html/stack.html.template b/core/templates/html/stack.html.template new file mode 100644 index 0000000..86cddb2 --- /dev/null +++ b/core/templates/html/stack.html.template @@ -0,0 +1,137 @@ + + + + + + + {{PROJECT_NAME}} β€” Stack + + + + +
+

Technology Stack

+

{{PROJECT_NAME}}

+

Generated: {{ISO_DATE}}

+
+ +
+ +
+

Detected / Chosen Stack

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LayerTechnologyVersionSourcePurpose
Frontend{{FRONTEND_NAME}}{{FRONTEND_VERSION}}{{FRONTEND_SOURCE}}{{FRONTEND_PURPOSE}}
Backend{{BACKEND_NAME}}{{BACKEND_VERSION}}{{BACKEND_SOURCE}}{{BACKEND_PURPOSE}}
Database{{DATABASE_NAME}}{{DATABASE_VERSION}}{{DATABASE_SOURCE}}{{DATABASE_PURPOSE}}
+ +
+ Source attribution legend +
+
package.json
+
Version from your installed dependencies (source of truth).
+
MCP verified (YYYY-MM-DD)
+
Confirmed via Context7 / Octocode on this date.
+
Verify at [URL]
+
Could not verify; check official docs for current version.
+
+
+
+ +
+

Package Manager

+

Using: {{PACKAGE_MANAGER}}

+

{{PACKAGE_MANAGER_EDUCATION}}

+
+ +
+

Why These Choices?

+

{{RATIONALE}}

+
+ +
+

Version Notes

+

{{VERSION_NOTES}}

+
+ +
+

Reference Projects (via Octocode)

+ +
+ +
+

Key Files

+ + + + + + + + +
FilePurpose
{{ENTRY_POINT}}{{ENTRY_POINT_PURPOSE}}
{{CONFIG_FILE}}{{CONFIG_FILE_PURPOSE}}
+
+ +
+ + + + + diff --git a/core/templates/html/tasks.html.template b/core/templates/html/tasks.html.template new file mode 100644 index 0000000..9576c7e --- /dev/null +++ b/core/templates/html/tasks.html.template @@ -0,0 +1,103 @@ + + + + + + + {{FEATURE_TITLE}} β€” Tasks + + + + +
+

Phase {{PHASE_N}} β€” {{PHASE_NAME}}

+

{{FEATURE_TITLE}} β€” Tasks

+

Generated: {{ISO_DATE}}

+
+ +
+ + + +
+

Setup

+ + +
+ + Install dependencies +
+ +
+ + Configure environment variables +
+
+ +
+

Implementation

+ +
+ + Build core feature logic +
+ +
+ + Wire UI to logic +
+
+ +
+

Verification

+ +
+ + Write tests covering edge cases +
+ +
+ + Run /own:done with 6-Gates review +
+
+ +
+ + + + + diff --git a/core/templates/html/theme-fallback.css b/core/templates/html/theme-fallback.css new file mode 100644 index 0000000..eb25ff5 --- /dev/null +++ b/core/templates/html/theme-fallback.css @@ -0,0 +1,426 @@ +/* ════════════════════════════════════════════════════════════════════ + OwnYourCode β€” Default Fallback Theme + ════════════════════════════════════════════════════════════════════ + Used when the `frontend-design` plugin is NOT installed. + Mirrors the bundled Apple Documentation aesthetic so users without + the plugin still get an acceptable, premium-feeling experience. + + Covers every semantic class and data-* selector emitted by the 6 + bundled HTML templates. Light and dark modes via prefers-color-scheme. + ════════════════════════════════════════════════════════════════════ */ + +/* ─── CSS Custom Properties (tokens) ─── */ + +:root { + /* Light mode defaults */ + --bg: #FAFAFA; + --bg-elevated: #FFFFFF; + --bg-subtle: #F2F2F4; + --text: #1D1D1F; + --text-secondary: #515154; + --text-tertiary: #86868B; + --accent: #0066CC; + --accent-soft: rgba(0, 102, 204, 0.08); + --border: #E5E5E7; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06); + + --success: #34A853; + --warn: #D97706; + --danger: #DC2626; + + /* Typography */ + --font-sans: ui-sans-serif, -apple-system, "SF Pro Display", "Segoe UI", system-ui, sans-serif; + --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace; + + /* Layout */ + --content-max: 720px; + --radius: 8px; + --radius-sm: 4px; + + /* Motion */ + --transition: 0.2s ease; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg: #1A1A1F; + --bg-elevated: #232328; + --bg-subtle: #2A2A30; + --text: #F5F5F7; + --text-secondary: #B4B4B8; + --text-tertiary: #86868B; + --accent: #0A84FF; + --accent-soft: rgba(10, 132, 255, 0.12); + --border: #38383D; + --shadow: 0 1px 3px rgba(255, 255, 255, 0.04), 0 1px 2px rgba(255, 255, 255, 0.06); + } +} + +/* ─── Reset + base ─── */ + +*, *::before, *::after { box-sizing: border-box; } + +html { font-size: 16px; -webkit-font-smoothing: antialiased; } + +body { + font-family: var(--font-sans); + font-size: 1rem; + font-weight: 400; + line-height: 1.6; + color: var(--text); + background: var(--bg); + margin: 0; + padding: 4rem 2rem; + transition: background var(--transition), color var(--transition); +} + +main { + max-width: var(--content-max); + margin: 0 auto; +} + +/* ─── Typography ─── */ + +h1, h2, h3, h4 { + font-weight: 600; + letter-spacing: -0.015em; + line-height: 1.25; + margin: 0 0 1rem; +} + +h1 { font-size: 2.5rem; } +h2 { font-size: 1.75rem; margin-top: 3rem; } +h3 { font-size: 1.25rem; margin-top: 2rem; } + +p { margin: 0 0 1.25rem; } + +code { + font-family: var(--font-mono); + font-size: 0.875em; + background: var(--bg-subtle); + padding: 0.125rem 0.375rem; + border-radius: var(--radius-sm); + color: var(--text); +} + +pre { + font-family: var(--font-mono); + font-size: 0.875rem; + background: var(--bg-subtle); + padding: 1.25rem; + border-radius: var(--radius); + border: 1px solid var(--border); + overflow-x: auto; + line-height: 1.5; +} + +a { + color: var(--accent); + text-decoration: none; + border-bottom: 1px solid transparent; + transition: border-color var(--transition); +} +a:hover { border-bottom-color: var(--accent); } + +/* ─── Document chrome ─── */ + +.document-header { + max-width: var(--content-max); + margin: 0 auto 3rem; + padding-bottom: 2rem; + border-bottom: 1px solid var(--border); +} + +.document-eyebrow { + font-size: 0.875rem; + font-weight: 600; + letter-spacing: 0.02em; + text-transform: uppercase; + color: var(--accent); + margin: 0 0 0.5rem; +} + +.document-meta { + font-size: 0.875rem; + color: var(--text-tertiary); + margin: 0.5rem 0 0; +} + +.document-footer { + max-width: var(--content-max); + margin: 4rem auto 0; + padding-top: 2rem; + border-top: 1px solid var(--border); + font-size: 0.875rem; + color: var(--text-tertiary); +} + +.section-intro { + color: var(--text-secondary); + margin-bottom: 1.5rem; +} + +/* ─── Tasks (Option D contract) ─── */ + +.task, +.dod-item { + display: flex; + align-items: center; + gap: 0.875rem; + padding: 0.875rem 1rem; + background: var(--bg-elevated); + border: 1px solid var(--border); + border-radius: var(--radius); + margin-bottom: 0.625rem; + box-shadow: var(--shadow); + transition: background var(--transition), opacity var(--transition); +} + +.task input[type="checkbox"], +.dod-item input[type="checkbox"] { + appearance: none; + width: 24px; + height: 24px; + border: 2px solid var(--border); + border-radius: var(--radius-sm); + cursor: pointer; + position: relative; + flex-shrink: 0; + transition: border-color var(--transition), background var(--transition); +} + +.task input[type="checkbox"]:checked, +.dod-item input[type="checkbox"]:checked { + background: var(--accent); + border-color: var(--accent); +} + +.task input[type="checkbox"]:checked::after, +.dod-item input[type="checkbox"]:checked::after { + content: ""; + position: absolute; + left: 6px; top: 2px; + width: 6px; height: 12px; + border: solid #fff; + border-width: 0 2px 2px 0; + transform: rotate(45deg); +} + +.task[data-status="completed"], +.dod-item[data-status="completed"] { + opacity: 0.65; +} + +.task[data-status="completed"] .task-text, +.dod-item[data-status="completed"] .dod-text { + text-decoration: line-through; + color: var(--text-tertiary); +} + +.task-text, .dod-text { font-size: 1rem; } + +/* ─── Phase groups (tasks.html) ─── */ + +.phase-group { + margin-bottom: 2.5rem; +} + +.phase-group h2 { + font-size: 1.25rem; + color: var(--text-secondary); + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 1px solid var(--border); +} + +/* ─── Roadmap phases ─── */ + +.phase { + margin-bottom: 2.5rem; + padding: 1.5rem; + background: var(--bg-elevated); + border: 1px solid var(--border); + border-radius: var(--radius); +} + +.phase[data-status="complete"] { + opacity: 0.7; +} + +.phase[data-status="complete"] h2::before { + content: "βœ“ "; + color: var(--success); +} + +.phase-priority { + display: inline-block; + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.05em; + text-transform: uppercase; + padding: 0.25rem 0.625rem; + border-radius: 999px; + margin-bottom: 0.75rem; +} + +.phase-priority[data-priority="high"] { background: rgba(220, 38, 38, 0.12); color: var(--danger); } +.phase-priority[data-priority="medium"] { background: rgba(217, 119, 6, 0.12); color: var(--warn); } +.phase-priority[data-priority="low"] { background: rgba(52, 168, 83, 0.12); color: var(--success); } + +.phase-description { + color: var(--text-secondary); + margin-bottom: 0.75rem; +} + +.phase-items { + margin: 0; + padding-left: 1.25rem; +} +.phase-items li { + color: var(--text-secondary); + margin-bottom: 0.375rem; +} + +/* ─── Tables ─── */ + +table { + width: 100%; + border-collapse: collapse; + margin-bottom: 1.5rem; + font-size: 0.9375rem; +} + +thead th { + text-align: left; + font-weight: 600; + color: var(--text-secondary); + border-bottom: 1px solid var(--border); + padding: 0.75rem 1rem; +} + +tbody td { + padding: 0.75rem 1rem; + border-bottom: 1px solid var(--border); + vertical-align: top; +} + +tbody tr:nth-child(even) { background: var(--bg-subtle); } +tbody tr:last-child td { border-bottom: none; } + +/* ─── Spec & Design sections ─── */ + +.mission-section, +.stack-section, +.spec-section, +.design-section { + margin-bottom: 3rem; +} + +.user-story { + padding: 1.25rem; + background: var(--bg-elevated); + border-left: 3px solid var(--accent); + border-radius: var(--radius); + margin-bottom: 1rem; +} +.user-story p { margin-bottom: 0.5rem; } +.user-story p:last-child { margin-bottom: 0; } + +.trade-off { + padding: 1.5rem; + background: var(--bg-elevated); + border: 1px solid var(--border); + border-radius: var(--radius); + margin-bottom: 1.5rem; + box-shadow: var(--shadow); +} + +.trade-off h3 { margin-top: 0; } +.trade-off-chosen { color: var(--success); } +.trade-off-rejected { color: var(--text-tertiary); } +.trade-off-reasoning { + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid var(--border); + color: var(--text-secondary); +} + +.architecture-diagram pre, +pre[data-file-tree] { + background: var(--bg-subtle); +} + +.architecture-diagram figcaption { + font-size: 0.875rem; + color: var(--text-tertiary); + margin-top: 0.5rem; + text-align: center; +} + +/* ─── Lists with data-IDs ─── */ + +.acceptance-criteria, +.edge-cases, +.out-of-scope, +.open-questions, +.data-flow-steps { + margin: 0 0 1.5rem; + padding-left: 1.5rem; +} + +.acceptance-criteria li, +.edge-cases li, +.out-of-scope li, +.open-questions li, +.data-flow-steps li { + margin-bottom: 0.5rem; + color: var(--text-secondary); +} + +.out-of-scope li { color: var(--text-tertiary); text-decoration: line-through; opacity: 0.7; } + +/* ─── Misc utilities ─── */ + +.source-legend { + font-size: 0.875rem; + color: var(--text-secondary); + margin-top: 1rem; +} +.source-legend summary { + cursor: pointer; + font-weight: 600; + color: var(--text); +} +.source-legend dl { margin-top: 0.75rem; } +.source-legend dt { font-weight: 600; margin-top: 0.5rem; } +.source-legend dd { margin: 0 0 0.5rem 1rem; color: var(--text-secondary); } + +.reference-projects { padding-left: 1.5rem; } +.reference-projects li { margin-bottom: 0.5rem; } + +.version-freshness { + display: block; + padding: 0.875rem 1rem; + background: rgba(217, 119, 6, 0.08); + border: 1px solid rgba(217, 119, 6, 0.2); + border-radius: var(--radius); + color: var(--warn); + font-size: 0.875rem; + margin-bottom: 1rem; +} + +.spec-nav { + display: flex; + gap: 1.5rem; + margin-bottom: 1rem; +} + +/* ─── Responsive ─── */ + +@media (max-width: 640px) { + body { padding: 2rem 1rem; } + h1 { font-size: 2rem; } + h2 { font-size: 1.5rem; } + table { font-size: 0.875rem; } + thead th, tbody td { padding: 0.5rem; } +} diff --git a/core/templates/html/theme-prompt.md.template b/core/templates/html/theme-prompt.md.template new file mode 100644 index 0000000..396abdb --- /dev/null +++ b/core/templates/html/theme-prompt.md.template @@ -0,0 +1,58 @@ + + +# Default OwnYourCode Theme β€” "Apple Documentation" + +Generate a premium, calm, technical-document aesthetic inspired by Apple +Developer Documentation (developer.apple.com). + +## Visual System + +- **Typography:** SF Pro Display (system-ui, -apple-system, "Segoe UI" fallback) + - Headings: weight 600, generous letter-spacing + - Body: weight 400, 1.6 line-height for readability + - Code: SF Mono (ui-monospace fallback) + +- **Color Modes:** Auto-detect via prefers-color-scheme + - Light mode: background #FAFAFA, text #1D1D1F, accent #0066CC + - Dark mode: background #1A1A1F, text #F5F5F7, accent #0A84FF + - Smooth transitions between modes (0.3s ease) + +- **Layout:** + - Generous whitespace β€” 4rem section spacing, 2rem paragraph spacing + - Max content width 720px (centered) for readability + - Soft 8px corners on cards, no harsh borders + - Subtle shadows β€” 0 1px 3px rgba(0,0,0,0.04) light / 0 1px 3px rgba(255,255,255,0.04) dark + +- **Components:** + - Task checkboxes: large, satisfying (24px), animated check on transition to data-status="completed" + - Code blocks: subtle tinted background, soft border + - Tables: zebra striping, no harsh grid lines + - Headings: weight contrast, no underlines + - Phase priority badges: small pills colored by data-priority (high/medium/low) + +## Vibe + +Calm, premium, opinionated. Not flashy. The reader should feel like they're +reading a real product document, not a generated artifact. diff --git a/scripts/project-install.ps1 b/scripts/project-install.ps1 index 1138aad..119abd2 100644 --- a/scripts/project-install.ps1 +++ b/scripts/project-install.ps1 @@ -283,6 +283,29 @@ if (Test-Path $srcGuides) { Write-Info "No guides to copy" } +# ============================================================================ +# STEP 7.5: Copy HTML templates (v2.4.0+) +# ============================================================================ +# These templates power the HTML-canonical SDD workflow. They are read at +# runtime by /own:init (Phase 0.5), /own:feature, and /own:theme. +# Safe on older source repos: missing templates are silently skipped. + +Write-Info "Copying HTML templates..." + +$srcHtml = Join-Path $BASE_DIR "core/templates/html" +$destHtml = Join-Path $PROJECT_DIR "ownyourcode/templates/html" + +if (Test-Path $srcHtml) { + New-Item -ItemType Directory -Force -Path $destHtml | Out-Null + $htmlFiles = Get-ChildItem -Path $srcHtml -Include "*.template","*.css" -Recurse -ErrorAction SilentlyContinue + foreach ($file in $htmlFiles) { + Copy-Item $file.FullName -Destination $destHtml -Force + } + Write-OK "HTML templates copied" +} else { + Write-Info "No HTML templates to copy (older source repo)" +} + # ============================================================================ # STEP 8: Create product templates # ============================================================================ diff --git a/scripts/project-install.sh b/scripts/project-install.sh index 522b34b..d2cc220 100755 --- a/scripts/project-install.sh +++ b/scripts/project-install.sh @@ -251,6 +251,25 @@ info "Copying guides..." cp "$BASE_DIR/guides/"*.md "$PROJECT_DIR/ownyourcode/guides/" 2>/dev/null || true success "Guides copied" +# ============================================================================ +# STEP 7.5: Copy HTML templates (v2.4.0+) +# ============================================================================ +# These templates power the HTML-canonical SDD workflow. They are read at +# runtime by /own:init (Phase 0.5), /own:feature, and /own:theme. +# Safe on older source repos: missing templates are silently skipped. + +info "Copying HTML templates..." + +mkdir -p "$PROJECT_DIR/ownyourcode/templates/html" +# Recursive so future subdirectories (e.g., presets/) are copied automatically. +# Mirrors the -Recurse semantics of the PowerShell variant for cross-platform parity. +if [ -d "$BASE_DIR/core/templates/html" ]; then + cp -R "$BASE_DIR/core/templates/html/." "$PROJECT_DIR/ownyourcode/templates/html/" 2>/dev/null || true + success "HTML templates copied" +else + info "No HTML templates to copy (older source repo)" +fi + # ============================================================================ # STEP 8: Create product templates # ============================================================================