Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
"email": "rukais2294@gmail.com"
},
"metadata": {
"description": "AI-native Vibe Coding — From idea to Deploy, Zero friction. Unified plugin with 12 agents, 5 commands, 4 skills, team-based parallel build, 20 design styles, screen-spec generator.",
"description": "AI-native Vibe Coding — From idea to Deploy, Zero friction. Unified plugin with 13 agents, 5 commands, 5 skills, team-based parallel build, 20 design styles, screen-spec generator.",
"version": "2.1.0"
},
"plugins": [
{
"name": "wigtn-coding",
"description": "Unified AI-native Vibe Coding plugin: PRD generation, digging analysis, screen-spec (IA / User Flow / Wireframe HTML / Dev Handoff), team-based parallel implementation, quality-gated auto-commit, 20 design styles, frontend (React/Next.js), backend (NestJS/Prisma), mobile (React Native/Expo), AI integration (STT/LLM), DevOps (Docker/CI-CD). 12 agents, 5 commands, 4 skills.",
"description": "Unified AI-native Vibe Coding plugin: PRD generation, digging analysis, screen-spec (IA / User Flow / Wireframe HTML / Dev Handoff), team-based parallel implementation, quality-gated auto-commit, 20 design styles, frontend (React/Next.js), backend (NestJS/Prisma), mobile (React Native/Expo), AI integration (STT/LLM), DevOps (Docker/CI-CD). 13 agents, 5 commands, 5 skills.",
"source": "./plugins/wigtn-coding",
"version": "2.1.0",
"author": {
Expand Down
44 changes: 44 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: 🐞 Bug report
description: 플러그인이 기대대로 동작하지 않을 때 / Report a bug in the plugin
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
버그를 알려주셔서 감사합니다. 재현 단계가 구체적일수록 빨리 고칠 수 있습니다.
- type: input
id: component
attributes:
label: 영향 받는 부분 / Affected part
description: 어떤 command / agent / skill 인가요?
placeholder: "/screen-spec, code-reviewer, handdrawn-diagram, …"
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: 무슨 일이 있었나요? / What happened?
description: 기대한 동작 vs 실제 동작
placeholder: |
기대: …
실제: …
validations:
required: true
- type: textarea
id: repro
attributes:
label: 재현 단계 / Steps to reproduce
placeholder: |
1. `/prd …`
2. `/screen-spec …`
3. …
validations:
required: true
- type: textarea
id: env
attributes:
label: 환경 / Environment
description: Claude Code 버전, OS, 플러그인 버전
placeholder: "Claude Code x.y, macOS 15, wigtn-coding 2.1.0"
validations:
required: false
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Discussions are not enabled on this repo; general questions go through blank issues.
blank_issues_enabled: true
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: 💡 Feature request
description: 새 agent / command / skill 또는 개선 제안 / Propose a new capability
labels: ["enhancement"]
body:
- type: textarea
id: problem
attributes:
label: 어떤 문제를 풀고 싶나요? / What problem does this solve?
description: 해결하려는 워크플로우/불편을 먼저 적어주세요 (해결책보다 문제 먼저).
validations:
required: true
- type: dropdown
id: kind
attributes:
label: 종류 / Kind
options:
- New skill
- New command
- New agent
- Improve existing
- Other
validations:
required: true
- type: textarea
id: proposal
attributes:
label: 제안 / Proposed solution
description: 어떻게 동작하면 좋을지. 트리거 예시(`/...`)가 있으면 도움이 됩니다.
validations:
required: false
- type: textarea
id: alternatives
attributes:
label: 대안 / Alternatives considered
validations:
required: false
28 changes: 28 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!-- 한 PR에 하나의 관심사. 제목은 Conventional Commits 형식 (feat/fix/docs/refactor/chore). -->

## Summary

<!-- 무엇을, 왜 바꿨는지 1~3줄 -->

## Changes

-

## Type

- [ ] `feat` — new agent / command / skill / capability
- [ ] `fix` — bug fix
- [ ] `docs` — documentation only
- [ ] `refactor` / `chore`

## Checklist

- [ ] 새 agent/command/skill을 `plugin.json`에 등록했다 (해당 시)
- [ ] 카운트를 모두 동기화했다 — `plugin.json`, `marketplace.json`, `README.{md,ko,cn}` 배지/표, `CLAUDE.md` (해당 시)
- [ ] `python3 .github/scripts/validate_plugin.py` 통과
- [ ] 버전 변경 시 `marketplace.json` ↔ `plugin.json` ↔ README/CLAUDE.md 일치
- [ ] 사용자 노출 콘텐츠는 한국어, 코드/커밋은 영어

## Related issue

<!-- Closes #NN -->
144 changes: 144 additions & 0 deletions .github/scripts/validate_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/usr/bin/env python3
"""Validate WIGTN plugin manifests against the filesystem and each other.

Guards the count/version drift class of bugs: stated counts in descriptions,
plugin.json arrays, and the actual files on disk must all agree, and the
version must be consistent across manifests. Exits non-zero on any mismatch.

Run locally: python3 .github/scripts/validate_plugin.py
"""

from __future__ import annotations

import json
import re
import sys
from pathlib import Path
from typing import List, Tuple

ROOT = Path(__file__).resolve().parents[2]
MARKETPLACE = ROOT / ".claude-plugin" / "marketplace.json"

errors: List[str] = []


def load_json(path: Path) -> dict:
"""Load JSON, recording a fatal error if it is missing or malformed."""
try:
return json.loads(path.read_text(encoding="utf-8"))
except FileNotFoundError:
errors.append(f"{path.relative_to(ROOT)}: file not found")
except json.JSONDecodeError as exc:
errors.append(f"{path.relative_to(ROOT)}: invalid JSON — {exc}")
return {}


def count_dir(path: Path, pattern: str) -> int:
"""Count entries matching a glob; 0 if the directory is absent."""
return len(list(path.glob(pattern))) if path.is_dir() else 0


def stated_counts(text: str) -> dict:
"""Extract 'N agents | commands | skills' counts from a description string."""
found = {}
for kind in ("agents", "commands", "skills"):
match = re.search(rf"(\d+)\s+{kind}", text)
if match:
found[kind] = int(match.group(1))
return found


def check_plugin(source: Path, mkt_version: str) -> None:
"""Validate one plugin's manifest, arrays, file counts, and version."""
rel = source.relative_to(ROOT)
manifest = source / ".claude-plugin" / "plugin.json"
data = load_json(manifest)
if not data:
return

actual: dict = {
"agents": count_dir(source / "agents", "*.md"),
"commands": count_dir(source / "commands", "*.md"),
"skills": len([p for p in (source / "skills").glob("*") if p.is_dir()])
if (source / "skills").is_dir()
else 0,
}

# plugin.json arrays must match the files on disk.
for kind in ("agents", "commands", "skills"):
listed = len(data.get(kind, []))
if listed != actual[kind]:
errors.append(
f"{rel}: plugin.json lists {listed} {kind} "
f"but {actual[kind]} exist on disk"
)

# Stated counts in plugin.json description must match reality.
for kind, n in stated_counts(data.get("description", "")).items():
if n != actual[kind]:
errors.append(
f"{rel}: description says {n} {kind} but {actual[kind]} exist"
)

# Version must agree with the marketplace entry (when present).
plugin_version = data.get("version")
if plugin_version and mkt_version and plugin_version != mkt_version:
errors.append(
f"{rel}: plugin.json version {plugin_version} != "
f"marketplace version {mkt_version}"
)

return actual


def main() -> int:
mkt = load_json(MARKETPLACE)
if not mkt:
print_report()
return 1

mkt_meta_version = mkt.get("metadata", {}).get("version", "")

for entry in mkt.get("plugins", []):
source = (ROOT / entry["source"]).resolve()
entry_version = entry.get("version", "")
if entry_version and mkt_meta_version and entry_version != mkt_meta_version:
errors.append(
f"marketplace.json: plugin '{entry.get('name')}' version "
f"{entry_version} != metadata version {mkt_meta_version}"
)
actual = check_plugin(source, entry_version or mkt_meta_version)

# Stated counts in the marketplace description must match reality too.
if actual:
for kind, n in stated_counts(entry.get("description", "")).items():
if n != actual[kind]:
errors.append(
f"marketplace.json: plugin '{entry.get('name')}' "
f"description says {n} {kind} but {actual[kind]} exist"
)
for kind, n in stated_counts(
mkt.get("metadata", {}).get("description", "")
).items():
if n != actual[kind]:
errors.append(
f"marketplace.json: metadata description says {n} {kind} "
f"but {actual[kind]} exist"
)

print_report()
return 1 if errors else 0


def print_report() -> None:
if errors:
print("Plugin validation FAILED:\n")
for err in errors:
print(f" ✗ {err}")
print(f"\n{len(errors)} problem(s). See .github/scripts/validate_plugin.py")
else:
print("Plugin validation passed — manifests, counts, and version agree.")


if __name__ == "__main__":
sys.exit(main())
25 changes: 25 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: validate

on:
pull_request:
paths:
- ".claude-plugin/**"
- "plugins/**"
- "README*.md"
- "CLAUDE.md"
- ".github/scripts/validate_plugin.py"
push:
branches: [main]

permissions:
contents: read

jobs:
manifests:
name: Validate plugin manifests & counts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Validate JSON, arrays, counts, and version consistency
run: python3 .github/scripts/validate_plugin.py
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

A unified Claude Code plugin enabling AI-powered Vibe Coding: idea to production with minimal friction.

**Version**: 2.0.0
**Version**: 2.1.0
**License**: Apache-2.0
**Repository**: https://github.com/wigtn/wigtn-plugins-with-claude-code

Expand All @@ -14,9 +14,9 @@ A unified Claude Code plugin enabling AI-powered Vibe Coding: idea to production
wigtn-plugins-with-claude-code/
├── .claude-plugin/ # Marketplace metadata
├── plugins/
│ └── wigtn-coding/ # Unified plugin: 12 agents, 5 commands, 5 skills, 20 design styles
│ └── wigtn-coding/ # Unified plugin: 13 agents, 5 commands, 5 skills, 20 design styles
│ ├── .claude-plugin/ # Plugin metadata
│ ├── agents/ # 12 agent definitions
│ ├── agents/ # 13 agent definitions
│ ├── commands/ # 5 commands (/prd, /screen-spec, /implement, /auto-commit, /review-pr)
│ ├── skills/ # 5 skills (code-review-levels, design-system-reference, handdrawn-diagram, screen-spec, team-memory-protocol)
│ └── hooks/ # Hooks configuration
Expand Down
63 changes: 63 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Contributing to WIGTN Coding

Thanks for your interest! This repo is a Claude Code **plugin marketplace** — one
unified plugin (`wigtn-coding`) made of agents, commands, and skills. The notes
below keep contributions consistent and mergeable.

한국어 사용자를 위한 콘텐츠는 한국어로 작성하되, 코드·커밋·이 문서는 영어를 유지합니다.

## Repo layout

```
.claude-plugin/marketplace.json # marketplace entry (name, version, plugin list)
plugins/wigtn-coding/
├── .claude-plugin/plugin.json # plugin manifest (agents/commands/skills arrays)
├── agents/ *.md # one file per agent
├── commands/ *.md # one file per slash command
├── skills/ <name>/SKILL.md # one folder per skill
└── hooks/hooks.json
```

## Adding an agent / command / skill

1. Create the file/folder under the matching directory.
2. **Register it** in `plugins/wigtn-coding/.claude-plugin/plugin.json` (add to the
`agents` / `commands` / `skills` array). A skill that is not in the array is not
exposed by the plugin.
3. **Update the counts everywhere** — this is enforced by CI (see below):
- `plugins/wigtn-coding/.claude-plugin/plugin.json` description (`N agents, …`)
- `.claude-plugin/marketplace.json` (both descriptions)
- `README.md`, `README.ko.md`, `README.cn.md` (the `N-Skills` / `N-Agents`
badges **and** the skill/agent tables)
- `CLAUDE.md` architecture block
4. User-facing content (skills, commands) is written in Korean; keep technical
terms in English.

## Conventions

- **Commits**: Conventional Commits — `feat(skill):`, `fix:`, `docs:`, `chore:`, …
- **Branches**: `feat/<name>`, `fix/<desc>`, `refactor/<desc>`.
- **Skill frontmatter**: `name`, `description` (with trigger keywords), optional
`allowed-tools`. See existing skills for the pattern.
- **Mermaid in generated docs**: quote every label (`["..."]`), use only valid
shapes, no `mindmap` (use `flowchart LR`).

## Versioning & releases

Single source of truth: the `version` in `marketplace.json` and `plugin.json` must
match, and `README` / `CLAUDE.md` must state the same number. Bump with
[SemVer](https://semver.org/): `fix` → patch, `feat` → minor.

## Before you open a PR

Run the same check CI runs:

```bash
python3 .github/scripts/validate_plugin.py
```

It verifies that JSON is valid and that the stated counts, the `plugin.json`
arrays, and the files on disk all agree — and that the version is consistent. PRs
that drift will fail this check.

Fill in the PR template, link any related issue, and keep one concern per PR.
Loading
Loading