implement-features-cx

star 1

Analyze open feature request issues, implement viable ones on dedicated branches, and respond to authors

vzwjustin By vzwjustin schedule Updated 5/13/2026

name: implement-features-cx description: Analyze open feature request issues, implement viable ones on dedicated branches, and respond to authors

/implement-features — Feature Request Harvest, Research & Implementation Workflow

Overview

A 5-phase workflow that systematically harvests feature requests from GitHub issues, creates structured idea files, researches solutions across the internet and Git repositories, presents a consolidated report for user approval, then generates detailed implementation plans and executes them.

Codex Execution Notes

  • Treat // turbo / // turbo-all as instructions to use multi_tool_use.parallel for independent reads, checks, and GitHub calls.
  • Approval gates are hard stops. Present the report/plan in the final response and do not move to implementation phases until the user explicitly approves.
  • Keep harvest/research bounded enough to produce the approval report quickly; do not start implementation while still in report phases.

Output directory structure:

_ideia/
├── viable/                  # Features approved for implementation
│   ├── need_details/        # ❓ Good idea but waiting for author clarification (issues stay OPEN)
│   │   └── 1015-warp-terminal-mitm.md
│   ├── 1046-native-playground.md           # ✅ Ready — researched and planned
│   └── 1046-native-playground.requirements.md
├── defer/                   # ⏭️ Good ideas deferred for future cycles (issues CLOSED)
│   └── 1041-smart-auto-combos.md
└── notfit/                  # ❌ Out of scope / already exists (issues CLOSED)
    └── 945-telegram-integration.md

_tasks/features-vX.Y.Z/   # Implementation plans (per-release)
└── 1046-native-playground.plan.md

LIFECYCLE RULE: viable/ files are DELETED once the feature is implemented — they are not moved. Only unimplemented features live in viable/ (or viable/need_details/). Files in defer/ and notfit/ remain as permanent reference.

BRANCH RULE: All implementation work MUST happen on the current release/vX.Y.Z branch. Never create separate feat/ branches. If no release branch exists yet, create one first using /generate-release Phase 1 steps 1–5.


Phase 1 — Harvest: Collect & Catalog Feature Ideas

1.1 Identify the Repository

// turbo

  • Run: git -C <project_root> remote get-url origin to extract owner/repo.

1.2 Ensure Release Branch Exists

// turbo

Before doing any work, ensure you are on the current release branch:

# Check current branch
git branch --show-current

# If on main, determine next version and create the release branch
VERSION=$(node -p "require('./package.json').version")
NEXT=$(node -p "const [a,b,c]=('$VERSION').split('.').map(Number); c>=9?a+'.'+(b+1)+'.0':a+'.'+b+'.'+(c+1)")
git checkout -b release/v$NEXT
npm version patch --no-git-tag-version
npm install

If already on a release/vX.Y.Z branch, continue working there.

1.3 Fetch ALL Open Feature Requests

// turbo-all

⚠️ CRITICAL: The JSON output of gh issue list can be truncated by the tool, silently hiding issues. You MUST use the two-step approach below.

Step 1 — Get Issue numbers only (small output, never truncated):

# Fetch issues with feature/enhancement labels
gh issue list --repo <owner>/<repo> --state open -l "enhancement" --limit 500 --json number --jq '.[].number'

# Also check for [Feature] in title (common pattern when no labels are set)
gh issue list --repo <owner>/<repo> --state open --limit 500 --json number,title --jq '.[] | select(.title | test("\\[Feature\\]|\\[feature\\]|feature request"; "i")) | .number'
  • Merge both lists, deduplicate. Count and confirm the total.

Step 2 — Fetch full metadata for each Issue (one call per issue):

gh issue view <NUMBER> --repo <owner>/<repo> --json number,title,labels,body,comments,createdAt,author,assignees
  • Read the entire body — including description, use cases, screenshots, mockups, and any embedded images.
  • Read ALL comments — community discussion, agreements, restrictions, owner responses, and linked PRs.
  • Images: If the body or comments contain image URLs (![...](...) or https://...png/jpg/gif), note them — they may contain UI mockups, wireframes, or architecture diagrams that are essential to understanding the request.
  • You may batch these into parallel calls (up to 4 at a time).
  • Sort by oldest first (FIFO).

1.4 Create Idea Files (initially in _ideia/ root)

For each feature request, create a structured idea file in <project_root>/_ideia/:

Filename convention: <NUMBER>-<kebab-case-short-title>.md Example: 1046-native-playground.md, 1041-smart-auto-combos.md

1.4a — If the idea file does NOT exist yet, create it:

# Feature: <Title from Issue>

> GitHub Issue: #<NUMBER> — opened by @<author> on <date>
> Status: 📋 Cataloged | Priority: TBD

## 📝 Original Request

<Paste the FULL issue body here, preserving all formatting, images, and code blocks>

## 💬 Community Discussion

<Summarize ALL comments chronologically, noting who said what and any decisions or objections raised>

### Participants

- @<author> — Original requester
- @<commenter1> — <brief role/opinion>
- ...

### Key Points

- <bullet list of the most important discussion points>
- <agreements reached>
- <objections raised>

## 🎯 Refined Feature Description

<YOUR interpretation and enrichment of the feature request. Expand on what was asked, fill in logical gaps, provide concrete examples of how it would work. This section should be MORE detailed and clearer than the original request.>

### What it solves

- <problem 1>
- <problem 2>

### How it should work (high level)

1. <step 1>
2. <step 2>
3. ...

### Affected areas

- <list of codebase areas, modules, files likely affected>

## 📎 Attachments & References

- <any image URLs, mockup links, or external references from the issue>

## 🔗 Related Ideas

- <links to related \_ideia/ files if any overlap found>

1.4b — If the idea file ALREADY exists, update it:

  • Append new comments from the issue to the Community Discussion section.
  • Update the Refined Feature Description if new information changes the understanding.
  • Add any new Related Ideas cross-references found.
  • Do NOT overwrite existing content — append and enrich it.

1.5 Cross-Reference & Deduplication

After processing all issues:

  • Scan all _ideia/*.md files for overlapping features.
  • If two features are substantially the same, add 🔗 Related Ideas cross-references to both.
  • If one is a strict subset of another, note it in the smaller file: > ℹ️ This feature is a subset of #<OTHER_NUMBER>. Consider implementing together.

Phase 2 — Research: Find Solutions & Build Requirements

For each cataloged idea that is viable (aligns with the project's goals):

2.1 Viability Pre-Check

Before investing in research, quickly assess:

  • Does this feature align with the project's goals and architecture?
  • Is it technically feasible with the current codebase?
  • Does it duplicate existing functionality?
  • Would it introduce breaking changes or security risks?
  • Is there enough detail to understand what's needed?

Verdict options:

Verdict When Action
VIABLE Good idea, enough context Proceed to Research
NEEDS DETAIL Good idea, insufficient spec Skip research, ask author
⏭️ DEFER Good idea, too complex for this cycle Catalog only, skip research
NOT FIT Doesn't fit the project Explain why
🔁 ALREADY EXISTS Feature already implemented Point to existing feature

2.2 Internet Research (for VIABLE features)

For each viable feature, perform systematic research:

Step 1 — Web search for similar implementations:

WebSearch("how to implement <feature description> in <tech stack>")
WebSearch("<feature keyword> implementation nextjs typescript 2025 2026")
WebSearch("<feature keyword> open source library npm")

Step 2 — Find reference Git repositories:

WebSearch("site:github.com <feature keyword> <tech stack> stars:>100")
WebSearch("github <feature keyword> implementation recently updated 2026")
  • Find up to 10 relevant repositories, sorted by most recently updated.
  • For each repository:
    • Note the repo URL, star count, last commit date
    • Read its README and relevant source files via WebFetch
    • Extract the architectural approach, patterns used, and key code snippets

Step 3 — Read API docs and standards:

If the feature involves an external API, protocol, or standard:

  • Find and read the official documentation
  • Note version requirements, authentication patterns, rate limits

2.3 Create Requirements File

For each researched feature, create a requirements file alongside its idea file:

Filename: <NUMBER>-<kebab-case-short-title>.requirements.md

# Requirements: <Feature Title>

> Feature Idea: [#<NUMBER>](./<NUMBER>-<kebab-case-short-title>.md)
> Research Date: <YYYY-MM-DD>
> Verdict: ✅ VIABLE

## 🔍 Research Summary

<Brief summary of what was found during research>

## 📚 Reference Implementations

| #   | Repository       | Stars | Last Updated | Approach | Relevance    |
| --- | ---------------- | ----- | ------------ | -------- | ------------ |
| 1   | [repo/name](url) | ⭐ N  | YYYY-MM-DD   | <brief>  | High/Med/Low |
| 2   | ...              |       |              |          |              |

### Key Patterns Found

- <pattern 1 with code snippet or link>
- <pattern 2>

## 📐 Proposed Solution Architecture

### Approach

<Describe the chosen approach based on research findings>

### New Files

| File                  | Purpose       |
| --------------------- | ------------- |
| `path/to/new/file.ts` | <description> |

### Modified Files

| File                       | Changes        |
| -------------------------- | -------------- |
| `path/to/existing/file.ts` | <what changes> |

### Database Changes

- <migrations needed, if any>

### API Changes

- <new/modified endpoints, if any>

### UI Changes

- <new/modified pages/components, if any>

## ⚙️ Implementation Effort

- **Estimated complexity**: Low / Medium / High / Very High
- **Estimated files changed**: ~N
- **Dependencies needed**: <new npm packages, if any>
- **Breaking changes**: Yes/No — <details>
- **i18n impact**: <number of new translation keys>
- **Test coverage needed**: <brief description>

## ⚠️ Open Questions

- <question 1>
- <question 2>

## 🔗 External References

- <documentation URLs>
- <API references>

Phase 2.5 — Organize & Respond: Sort Files and Post GitHub Comments

2.5.1 Create Directory Structure

// turbo

mkdir -p <project_root>/_ideia/viable
mkdir -p <project_root>/_ideia/viable/need_details
mkdir -p <project_root>/_ideia/defer
mkdir -p <project_root>/_ideia/notfit

2.5.2 Move Idea Files to Category Subdirectories

After classification, move EVERY idea file to its correct subdirectory:

# ✅ VIABLE — move idea + requirements files
mv _ideia/<NUMBER>-*.md _ideia/viable/
mv _ideia/<NUMBER>-*.requirements.md _ideia/viable/

# ❓ NEEDS DETAIL — viable but waiting for author response
mv _ideia/<NUMBER>-*.md _ideia/viable/need_details/

# ⏭️ DEFER — move idea files only
mv _ideia/<NUMBER>-*.md _ideia/defer/

# ❌ NOT FIT & 🔁 ALREADY EXISTS — move idea files only
mv _ideia/<NUMBER>-*.md _ideia/notfit/

No files should remain in _ideia/ root after this step (except subdirectories).

2.5.3 Post GitHub Comments by Category

Each category has a specific comment template and action:


For 🔁 ALREADY EXISTS — Comment + CLOSE issue

// turbo

The feature already exists in the system. Explain WHERE it is and HOW to use it.

Hi @<author>! Thanks for the suggestion! 🙏

Great news — this functionality **already exists** in OmniRoute:

**📍 Where to find it:** <exact dashboard path or settings location>

**🔧 How to use it:**

1. <step 1>
2. <step 2>
3. <step 3>

If you have any trouble finding or using it, feel free to ask in a Discussion. We're always happy to help!

Closing this as the feature is already available. 🎉
gh issue close <NUMBER> --repo <owner>/<repo> --comment "<comment above>"

For ⏭️ DEFER — Comment + CLOSE issue

// turbo

Thank the user, explain the idea was cataloged, and that we'll study it before implementing.

Hi @<author>! Thanks for this thoughtful feature request! 🙏

We really appreciate the detailed proposal. We've **cataloged your idea** and it's now part of our improvement backlog.

Due to the **significant architectural impact** of this feature, we'll need to conduct thorough use-case studies and architectural analysis before we start development. This ensures we build it right and don't introduce regressions.

**What happens next:**

- Your idea is saved in our internal feature backlog
- We'll conduct architecture studies when this area is prioritized
- We'll notify you here when development begins

Thank you for contributing to OmniRoute's roadmap! Your input helps shape the product. 🚀
gh issue close <NUMBER> --repo <owner>/<repo> --comment "<comment above>"

For ❌ NOT FIT — Comment + CLOSE issue

// turbo

Politely explain why the feature doesn't fit the project scope.

Hi @<author>! Thanks for the suggestion! 🙏

After careful analysis, we've determined that this feature **falls outside OmniRoute's core scope** as a proxy/router.

**Reason:** <explain why — e.g., "Telegram integration belongs in the application/orchestrator layer that consumes OmniRoute's API, not inside the router itself.">

**Alternative:** <suggest an alternative approach if possible>

We appreciate you thinking of ways to improve OmniRoute! If you'd like to discuss this further, feel free to open a Discussion. 🙏
gh issue close <NUMBER> --repo <owner>/<repo> --comment "<comment above>"

For ❓ NEEDS DETAIL — Comment (keep OPEN)

// turbo

Ask for the specific missing details needed.

Hi @<author>! Thanks for the feature request — it's an interesting idea and we'd love to explore it further. 🙏

To move forward, we need a few more details:

1. <specific question 1>
2. <specific question 2>
3. <specific question 3>

If you know of any **open-source projects or repositories** that implement something similar, please share links — it would help us design the best solution.

Looking forward to your response! 🚀

For ✅ VIABLE — Comment (keep OPEN)

// turbo

Thank the user, confirm we've cataloged their idea, and explain it may be implemented in future versions.

Hi @<author>! Thanks for the great feature suggestion! 🙏

We've analyzed your request and it aligns well with OmniRoute's roadmap. We've **cataloged this feature** and it's in our implementation backlog.

**Status:** 📋 Cataloged for future implementation

This feature may be included in upcoming releases. We'll **respond to this issue and tag you** as soon as implementation begins so you can test it.

Thank you for helping improve OmniRoute! 🚀

⚠️ Do NOT close viable issues — they remain OPEN for tracking.


Phase 3 — Report: Present Findings to User

3.1 🛑 MANDATORY STOP — Present Consolidated Report

After completing Phase 1, Phase 2, and Phase 2.5, STOP and present the following report in the chat. Do NOT proceed to implementation.

Present a structured report containing:

3.1a — Feature Summary Table

# Issue Title Verdict Location Action
1 #N Title ✅ VIABLE _ideia/viable/ Issue OPEN, comment posted
2 #N Title ⏭️ DEFER _ideia/defer/ Issue CLOSED with explanation
3 #N Title ❌ NOT FIT _ideia/notfit/ Issue CLOSED with explanation
4 #N Title 🔁 EXISTS _ideia/notfit/ Issue CLOSED with guidance
5 #N Title ❓ NEEDS DETAIL _ideia/viable/need_details/ Issue OPEN, questions posted

3.1b — Viable Features Detail

For each VIABLE feature, provide a brief paragraph:

  • What was found during research
  • The proposed approach
  • Key risks or unknowns
  • Which reference repositories were most useful

3.1c — Issues Requiring Author Feedback

For features marked ❓ NEEDS DETAIL, list:

  • What specific information is missing
  • What examples or repository references would help

3.1d — Ask for User Confirmation

End the report with:

Ready to proceed with implementation?

  • Reply "sim" or "yes" to generate full implementation plans for all VIABLE features.
  • Reply with specific issue numbers to select only certain features.
  • Reply "não" or "no" to stop here.

Phase 4 — Plan: Generate Implementation Plans (after user says "yes")

⚠️ Do NOT enter this phase without explicit user approval from Phase 3.

4.1 Create Task Directory

mkdir -p <project_root>/_tasks/features-vX.Y.Z/

4.2 Generate One Implementation Plan Per Feature

For each VIABLE feature approved by the user, create:

Filename: _tasks/features-vX.Y.Z/<NUMBER>-<kebab-case-title>.plan.md

# Implementation Plan: <Feature Title>

> Issue: #<NUMBER>
> Idea: [\_ideia/viable/<NUMBER>-title.md](../../_ideia/viable/<NUMBER>-title.md)
> Requirements: [\_ideia/viable/<NUMBER>-title.requirements.md](../../_ideia/viable/<NUMBER>-title.requirements.md)
> Branch: `release/vX.Y.Z`

## Overview

<Brief description of what will be built>

## Pre-Implementation Checklist

- [ ] Read all related source files listed below
- [ ] Confirm no conflicts with in-flight PRs
- [ ] Verify database migration numbering

## Implementation Steps

### Step 1: <Title>

**Files:**

- `path/to/file.ts` — <what to change>

**Details:**
<Detailed description of the change, including code patterns to follow, function signatures, etc.>

### Step 2: <Title>

...

### Step N: Tests

**New test files:**

- `tests/unit/<test-file>.test.mjs` — <what to test>

**Test cases:**

- [ ] <test case 1>
- [ ] <test case 2>

### Step N+1: i18n

**Translation keys to add:**

- `<namespace>.<key>` — "<English value>"

### Step N+2: Documentation

- [ ] Update CHANGELOG.md
- [ ] Update relevant docs/ files

## Verification Plan

1. Run `npm run build` — must pass
2. Run `npm test` — all tests must pass
3. Run `npm run lint` — no new errors
4. <Manual verification steps>

## Commit Plan

feat: (#)


4.3 Present Plans for Final Approval

Present a summary of all generated plans:

Implementation plans generated:

# Feature Plan File Steps Effort
1 </td> <td><code>_tasks/features-vX.Y.Z/N-title.plan.md</code></td> <td>N steps</td> <td>Medium</td> </tr> </tbody></table> <p>Reply <strong>"sim"</strong> or <strong>"yes"</strong> to begin implementation of all features. Reply with specific issue numbers to implement only certain ones.</p> </blockquote> <hr> <h2>Phase 5 — Execute: Implement the Plans (after user says "yes")</h2> <blockquote> <p><strong>⚠️ Do NOT enter this phase without explicit user approval from Phase 4.</strong></p> </blockquote> <h3>5.1 Implement Each Feature</h3> <p>For each approved plan, execute it step by step:</p> <ol> <li><strong>Follow the plan</strong> — implement exactly as specified in the <code>.plan.md</code> file</li> <li><strong>Build</strong> — Run <code>npm run build</code> after each feature to verify compilation</li> <li><strong>Test</strong> — Run <code>npm test</code> to ensure no regressions</li> <li><strong>Commit</strong> — Commit with: <code>feat: <description> (#<NUMBER>)</code></li> <li><strong>Update the plan</strong> — Mark completed steps with <code>[x]</code> in the plan file</li> <li><strong>Continue</strong> — Move to the next feature (do NOT switch branches)</li> </ol> <h3>5.2 Respond to Authors (Update Viable Issues)</h3> <p>For each implemented feature, <strong>close the issue with a final comment</strong>:</p> <pre><code class="language-markdown">✅ **Implemented in `release/vX.Y.Z`!** Hi @<author>! Great news — your feature request has been implemented! 🎉 **What was done:** - <bullet list of what was built> **How to try it:** ```bash git fetch origin && git checkout release/vX.Y.Z npm install && npm run dev ``` </code></pre> <p>This will be included in the upcoming <strong>vX.Y.Z</strong> release. Feel free to reopen if you spot any issues! 🚀</p> <pre><code> ```bash gh issue close <NUMBER> --repo <owner>/<repo> --comment "<comment above>" </code></pre> <p>Then <strong>DELETE the idea file</strong> — it has served its purpose:</p> <pre><code class="language-bash"># ✅ Implemented files are DELETED (not moved) rm _ideia/viable/<NUMBER>-<title>.md rm _ideia/viable/<NUMBER>-<title>.requirements.md # if exists </code></pre> <blockquote> <p><strong>Why delete?</strong> <code>viable/</code> only holds features that still NEED to be done. Once implemented, the commit history and CHANGELOG are the source of truth. Keeping the file would be confusing.</p> </blockquote> <h3>5.3 Finalize & Push</h3> <p>After implementing all approved features:</p> <ol> <li><strong>Update CHANGELOG.md</strong> on the release branch with all new feature entries</li> <li>Push the release branch: <code>git push origin release/vX.Y.Z</code></li> <li>Run <code>/generate-release</code> workflow Phase 1 steps 7–10 (tests → commit → push → open PR to main → wait for user)</li> </ol> <h3>5.4 Final Summary Report</h3> <p>Present a final summary report to the user:</p> <table> <thead> <tr> <th>Issue</th> <th>Title</th> <th>Verdict</th> <th>Action</th> <th>Commit</th> </tr> </thead> <tbody><tr> <td>#N</td> <td>Title</td> <td>✅ Implemented</td> <td>Issue closed, idea file deleted</td> <td><code>abc1234</code></td> </tr> <tr> <td>#N</td> <td>Title</td> <td>⏭️ Deferred</td> <td>Issue closed + saved in <code>_ideia/defer/</code></td> <td>—</td> </tr> <tr> <td>#N</td> <td>Title</td> <td>❌ Not Fit</td> <td>Issue closed + saved in <code>_ideia/notfit/</code></td> <td>—</td> </tr> <tr> <td>#N</td> <td>Title</td> <td>🔁 Exists</td> <td>Issue closed + saved in <code>_ideia/notfit/</code></td> <td>—</td> </tr> <tr> <td>#N</td> <td>Title</td> <td>❓ Needs Detail</td> <td>Issue OPEN, moved to <code>_ideia/viable/need_details/</code></td> <td>—</td> </tr> </tbody></table> <p>Include:</p> <ul> <li>Total features harvested</li> <li>Total ideas cataloged (<code>viable/need_details/</code> + <code>defer/</code> + <code>notfit/</code>)</li> <li>Total features implemented (idea files deleted, issues closed)</li> <li>Total features deferred</li> <li>Total issues closed</li> <li>Total issues left open (needs detail only — viable are closed after implementation)</li> <li>Test results (pass/fail count)</li> </ul> </article> </div> <!-- Right: Metadata & Command Sidebar --> <div class="w-full lg:w-80 shrink-0 flex flex-col gap-6" data-astro-cid-7zzsworf> <!-- Install Card --> <div class="p-6 rounded-xl bg-surface-container border border-border/80 flex flex-col gap-4 shadow-sm" data-astro-cid-7zzsworf> <span class="text-xs font-bold uppercase tracking-widest text-on-surface-variant/60 font-mono" data-astro-cid-7zzsworf>Install via CLI</span> <div class="flex flex-col gap-2" data-astro-cid-7zzsworf> <div id="detail-install-cmd" class="font-mono text-[11px] p-3 rounded-lg bg-black/40 border border-border select-all break-all text-primary font-bold leading-relaxed" data-astro-cid-7zzsworf> npx skills add https://github.com/vzwjustin/OmniCode --skill implement-features-cx </div> <button id="detail-copy-btn" class="w-full py-2.5 rounded-lg bg-primary hover:bg-primary-hover text-on-primary font-sans font-bold text-sm shadow transition-all active:scale-95 flex items-center justify-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px]" data-astro-cid-7zzsworf>content_copy</span> <span data-astro-cid-7zzsworf>Copy Command</span> </button> </div> </div> <!-- Details & Stats Card --> <div class="p-6 rounded-xl bg-surface-container border border-border/80 flex flex-col gap-4 shadow-sm text-on-surface" data-astro-cid-7zzsworf> <span class="text-xs font-bold uppercase tracking-widest text-on-surface-variant/60 font-sans" data-astro-cid-7zzsworf>Repository Details</span> <div class="flex flex-col gap-3.5" data-astro-cid-7zzsworf> <div class="flex justify-between items-center text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>star</span> Stars </span> <span class="font-mono font-bold text-on-surface" data-astro-cid-7zzsworf>1</span> </div> <div class="flex justify-between items-center text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>call_split</span> Forks </span> <span class="font-mono font-bold text-on-surface" data-astro-cid-7zzsworf>0</span> </div> <div class="flex justify-between items-center text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>navigation</span> Branch </span> <span class="font-mono bg-surface border border-border px-2 py-0.5 rounded text-[11px] text-on-surface-variant" data-astro-cid-7zzsworf>main</span> </div> <div class="flex justify-between items-start text-sm" data-astro-cid-7zzsworf> <span class="text-on-surface-variant/70 flex items-center gap-1.5 mt-0.5" data-astro-cid-7zzsworf> <span class="material-symbols-outlined text-[16px] text-on-surface-variant/60" data-astro-cid-7zzsworf>article</span> Path </span> <span class="font-mono bg-surface border border-border px-2 py-0.5 rounded text-[11px] text-on-surface-variant truncate max-w-[150px]" title="SKILL.md" data-astro-cid-7zzsworf>SKILL.md</span> </div> </div> </div> <!-- Occupations Tag Card --> <!-- Related Creators Card --> <div class="p-6 rounded-xl bg-surface-container border border-border/80 flex flex-col gap-3 shadow-sm" data-astro-cid-7zzsworf> <span class="text-xs font-bold uppercase tracking-widest text-on-surface-variant/60 font-sans" data-astro-cid-7zzsworf>More from Creator</span> <div class="flex items-center gap-2" data-astro-cid-7zzsworf> <img class="w-8 h-8 rounded-full border border-border" src="https://avatars.githubusercontent.com/u/19340462?u=6bce96348bb9d1675a7292238e7b429413b85714&v=4" alt="vzwjustin" onerror="this.src='https://avatars.githubusercontent.com/u/9919?v=4'" data-astro-cid-7zzsworf> <div class="flex flex-col min-w-0" data-astro-cid-7zzsworf> <span class="font-bold text-sm truncate text-on-surface" data-astro-cid-7zzsworf>vzwjustin</span> <a href="/?creator=vzwjustin" class="text-xs text-primary hover:underline font-semibold transition-all" data-astro-cid-7zzsworf>Explore all skills →</a> </div> </div> </div> </div> </div> </div> </div> <script> const copyBtn = document.getElementById("detail-copy-btn"); const installCmd = document.getElementById("detail-install-cmd"); if (copyBtn && installCmd) { copyBtn.addEventListener("click", () => { const cmd = installCmd.textContent.trim(); navigator.clipboard.writeText(cmd).then(() => { const originalText = copyBtn.innerHTML; copyBtn.innerHTML = ` <span class="material-symbols-outlined text-[16px]">check</span> <span>Copied!</span> `; copyBtn.style.background = "#10b981"; copyBtn.style.borderColor = "#10b981"; setTimeout(() => { copyBtn.innerHTML = originalText; copyBtn.style.background = ""; copyBtn.style.borderColor = ""; }, 1500); }); }); } </script> </div> <!-- Footer --> <footer class="border-t border-border bg-surface-container-low text-on-surface-variant py-8 px-gutter mt-16 rounded-xl"> <div class="max-w-container-max mx-auto flex flex-col md:flex-row justify-between items-center gap-6"> <div class="flex items-center gap-2"> <div class="w-6 h-6 rounded bg-primary bg-opacity-20 flex items-center justify-center"> <span class="material-symbols-outlined text-primary text-sm">code_blocks</span> </div> <span class="font-bold text-on-surface text-sm">SkillMD</span> </div> <div class="flex flex-wrap justify-center gap-6 text-sm"> <a href="/about" class="hover:text-primary transition-colors">About Us</a> <a href="/contact" class="hover:text-primary transition-colors">Contact Us</a> <a href="/privacy" class="hover:text-primary transition-colors">Privacy Policy</a> <a href="/terms" class="hover:text-primary transition-colors">Terms of Service</a> <a href="/support" class="hover:text-primary transition-colors">Support</a> </div> <div class="text-xs text-on-surface-variant/80"> © 2026 SkillMD. All rights reserved. </div> </div> </footer> </main> <!-- Script for Theme Toggle, Mobile Menu, and Sidebar Filter Redirection --> <script> // Theme setup const savedTheme = localStorage.getItem("theme") || "dark"; function applyTheme(theme) { document.documentElement.classList.remove("dark", "green", "dracula", "nord"); if (theme === "dark") { document.documentElement.classList.add("dark"); } else if (theme === "green") { document.documentElement.classList.add("dark", "green"); } else if (theme === "dracula") { document.documentElement.classList.add("dark", "dracula"); } else if (theme === "nord") { document.documentElement.classList.add("dark", "nord"); } document.documentElement.setAttribute("data-theme", theme); const themeMoon = document.getElementById("theme-moon"); const themeSun = document.getElementById("theme-sun"); const themeLeaf = document.getElementById("theme-leaf"); const themeDracula = document.getElementById("theme-dracula"); const themeNord = document.getElementById("theme-nord"); if (themeMoon && themeSun && themeLeaf && themeDracula && themeNord) { themeMoon.style.display = theme === "dark" ? "inline" : "none"; themeSun.style.display = theme === "light" ? "inline" : "none"; themeLeaf.style.display = theme === "green" ? "inline" : "none"; themeDracula.style.display = theme === "dracula" ? "inline" : "none"; themeNord.style.display = theme === "nord" ? "inline" : "none"; } } applyTheme(savedTheme); const themeToggleBtn = document.getElementById("theme-toggle-btn"); if (themeToggleBtn) { themeToggleBtn.addEventListener("click", () => { const currentTheme = document.documentElement.getAttribute("data-theme") || "dark"; let newTheme = "dark"; if (currentTheme === "dark") { newTheme = "light"; } else if (currentTheme === "light") { newTheme = "green"; } else if (currentTheme === "green") { newTheme = "dracula"; } else if (currentTheme === "dracula") { newTheme = "nord"; } else { newTheme = "dark"; } applyTheme(newTheme); localStorage.setItem("theme", newTheme); }); } // Mobile menu toggle and sidebar logic const mobileMenuToggle = document.getElementById("mobile-menu-toggle"); const sidebarMenu = document.getElementById("sidebar-menu"); const sidebarOverlay = document.getElementById("sidebar-overlay"); function isMobile() { return window.innerWidth < 768; // 768px is the 'md' breakpoint in Tailwind } function openSidebar() { if (sidebarMenu) { sidebarMenu.classList.remove("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.remove("hidden"); } } function closeSidebar() { if (sidebarMenu && isMobile()) { sidebarMenu.classList.add("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.add("hidden"); } } if (mobileMenuToggle && sidebarMenu) { mobileMenuToggle.addEventListener("click", (e) => { e.stopPropagation(); if (isMobile()) { const isClosed = sidebarMenu.classList.contains("-translate-x-full"); if (isClosed) { openSidebar(); } else { closeSidebar(); } } }); document.addEventListener("click", (e) => { if (isMobile()) { if (!sidebarMenu.contains(e.target) && !mobileMenuToggle.contains(e.target)) { closeSidebar(); } } }); if (sidebarOverlay) { sidebarOverlay.addEventListener("click", () => { if (isMobile()) { closeSidebar(); } }); } // Collapse sidebar when clicking a filter button, creator button, or nav item inside it sidebarMenu.addEventListener("click", (e) => { if (isMobile()) { const clickTarget = e.target.closest("button, a"); if (clickTarget) { closeSidebar(); } } }); // Sync sidebar state on window resize window.addEventListener("resize", () => { if (!isMobile()) { // Desktop: sidebar should be visible, no overlay if (sidebarMenu) { sidebarMenu.classList.remove("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.add("hidden"); } } else { // Mobile: start collapsed if (sidebarMenu) { sidebarMenu.classList.add("-translate-x-full"); } if (sidebarOverlay) { sidebarOverlay.classList.add("hidden"); } } }); } // If not on homepage, redirect on sidebar filter click const isHomepage = window.location.pathname === "/"; document.querySelectorAll("#occupation-filters .filter-btn").forEach(btn => { btn.addEventListener("click", (e) => { const occ = e.currentTarget.getAttribute("data-occupation"); if (!isHomepage) { window.location.href = occ ? `/?occupation=${encodeURIComponent(occ)}` : "/"; } }); }); document.querySelectorAll("#creator-filters .creator-btn").forEach(btn => { btn.addEventListener("click", (e) => { const creator = e.currentTarget.getAttribute("data-creator"); if (!isHomepage) { window.location.href = `/?creator=${encodeURIComponent(creator)}`; } }); }); </script> </body> </html>