Skip to content
Draft
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
17 changes: 17 additions & 0 deletions .cursor/environment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "gh-blog (Astro)",
"install": "bash .cursor/install.sh",
"terminals": [
{
"name": "astro-dev",
"command": "export PATH=\"$HOME/.bun/bin:$PATH\" && bun run dev --host",
"description": "Astro dev server on http://localhost:4321"
}
],
"ports": [
{
"name": "astro-dev",
"port": 4321
}
]
}
11 changes: 11 additions & 0 deletions .cursor/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -euo pipefail

# Install the pinned bun (matches packageManager in package.json) if missing.
BUN_VERSION="1.4.2"
if ! command -v bun >/dev/null 2>&1; then
curl -fsSL https://bun.sh/install | bash -s "bun-v${BUN_VERSION}"
fi
export PATH="$HOME/.bun/bin:$PATH"

bun install --frozen-lockfile
9 changes: 5 additions & 4 deletions .tasks/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@
| ----- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| 0 | Foundation: 브랜치·툴체인·지식기반 | `main` 전환, Node 22 + **bun** 고정 (yarn classic 잔재 제거), Astro Docs MCP + Astro 스킬 1개 + StyleX ESLint 룰 확정, StyleX 스파이크(o) | `main`이 default, `bun run dev`+StyleX 샘플 빌드 그린, 스킬 목록 `SPEC`에 핀 | [SPEC](phase-0-foundation/SPEC.md) · [PLAN](phase-0-foundation/PLAN.md) |
| 1 | Scaffold + Design System + Home/Tags 껍데기 + 배포 | Astro v7 스캐폴드(static), StyleX 토큰/프리미티브, Home·Tags 라우트, GH Pages Actions 배포 | `main` 푸시→Pages 자동배포, Lighthouse perf≥90·a11y≥95, 스타일런타임 주입 0 | [SPEC](phase-1-scaffold-design-system/SPEC.md) · [PLAN](phase-1-scaffold-design-system/PLAN.md) |
| 1.5 | Visual design 적용 | 컨셉 PNG + `docs/conventions/design.md` 토큰·타이포·레이아웃. Prism.js Vitesse Light 계열 코드 블록. Home/목업 기사·위키 | 코드 블록이 다크가 아님, a11y≥95, 런타임 스타일 주입 0 | [SPEC](phase-1.5-visual-design/SPEC.md) · [PLAN](phase-1.5-visual-design/PLAN.md) |
| 2 | Content Routes + MDX 마이그레이션 | `articles`(가변 테마) + `til`(통일) + `tags/[tag]`, Content Collections(Zod), 기존 6개 + `llm-wiki-template/wiki` 선별 이식 | 기존글 100% 렌더(깨진 링크 0), 스키마 위반 0, articles≥2 colorway 데모 | [SPEC](phase-2-content-routes/SPEC.md) · [PLAN](phase-2-content-routes/PLAN.md) |
| 3 | Wiki Quiz (flash cards) | 랜덤 객관식/주관식, 덱·세션·채점·localStorage 진척, island로 SSG 무해화 | 퀴즈 20문항 시드, 키보드 조작·채점 단위테스트 그린 | [SPEC](phase-3-wiki-quiz/SPEC.md) · [PLAN](phase-3-wiki-quiz/PLAN.md) |
| 4 | Hardening + 운영 | Pagefind 검색, SEO/RSS/OG/sitemap, 404, CI 가드(lint·link·schema·공개안전), 구 `gh-pages` 정리 | 검색 Top-3 적중 수동체크, CI 그린, 구배포 경로 제거 | [SPEC](phase-4-hardening-ops/SPEC.md) · [PLAN](phase-4-hardening-ops/PLAN.md) |

의존성: 0 → 1 → 2 → 3 → 4 순차. 3·4는 2 승인 후 병렬 검토 가능.
의존성: 0 → 1 → 1.5 → 2 → 3 → 4 순차. 3·4는 2 승인 후 병렬 검토 가능.

## 정보구조 (1차 범위)

- `/` 홈페이지 · `/articles` + `/articles/[...slug]` · `/til` + `/til/[...slug]` (=wiki, 동일 템플릿) · `/tags` + `/tags/[tag]`
- 고도화: `/wiki/quiz` — flash cards, 랜덤 객관식/주관식 (Phase 3, islands)
- `articles`: 페이지별 자유 구성 — frontmatter(`theme`, `layout`, `colorway`, `components`)로 컬러셋·레이아웃 분기, MDX 안에서 자유 조립
- `til`/`wiki`: 단일 `WikiLayout` + 단일 스키마로 통일감
- 스타일: minimalism + light theme + "적당한 고급스러움" (타이포·여백·헤어라인·절제된 액센트)
- 스타일: [`docs/conventions/design.md`](../docs/conventions/design.md) — 따뜻한 베이지 캔버스, 민트 액센트, Prism Vitesse Light 계열. 컨셉: `.tasks/visual-concept-by-gpt-09-10.png`.
- UI: 재활용 가능한 design-system 컴포넌트, **StyleX** 기반 (`tokens → primitives → patterns`)

## 코드 스타일 (전 Phase 공통)
Expand All @@ -34,7 +35,7 @@

- Phase 0에서 `master`→`main` (이력 유지 rename, GitHub default 전환, Pages 소스 재지정, `deploy.yml`의 `branches:[master]` 제거가 Phase 1에서).
- Phase별 스택 (base 체인, 아래→위 순서로 머지):
`main` ← `feat/ci-gates` ← `feat/phase-0-foundation` ← `feat/phase-1-scaffold` ← `feat/phase-2-content` ←
`main` ← `feat/ci-gates` ← `feat/phase-0-foundation` ← `feat/phase-1-scaffold` ← `feat/phase-1.5-visual` ← `feat/phase-2-content` ←
`feat/phase-3-quiz` ← `feat/phase-4-hardening`
- 생성: 페이즈 완료 즉시 `gh pr create --draft --base <parent-branch>` (draft). planner/verifier 리뷰 통과 후 `gh pr ready`. CI는 PR마다 자동 실행 (CI 선행 머지 후).
- 머지는 아래부터 순서대로 (GitHub "Merge" + base 자동전환 확인). `gh` 2.100.0 설치 확인됨.
Expand All @@ -46,7 +47,7 @@
- Cursor (Cline 한도 소진 시 기본): [harness/cursor.md](playbook/harness/cursor.md) — 부모 Grok 4.6 (orchestrator+leader), planner·verifier 서브에이전트, Composer 2.5 implementer는 worktree. 정의: `.cursor/agents/`.
- Cline + Herdr: [harness/cline-herdr.md](playbook/harness/cline-herdr.md) — pane 3개, muse-spark / glm-5.3-flash (2026-09-10 실측).
- Claude Code / Codex: 스텁. 첫 실사용 때 `_template.md`로 승격.
흐름: leader 추적 → planner가 PLAN 정제 → developer 구현 + **draft** PR → verifier 리뷰 (Cursor: GPT 5.6 Sol medium) → ready 전환 → **사람 머지**.
흐름: leader 추적 → planner가 PLAN 정제 → developer 구현 + **draft** PR → verifier 리뷰 (Cursor: Sol → 막히면 Opus 5 → 비용 크면 Grok·Kimi K3) → ready 전환 → **사람 머지**.
**미사용:** Paseo, opencode-go 모델.

## 승인 플로우
Expand Down
10 changes: 10 additions & 0 deletions .tasks/phase-1.5-visual-design/LOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Phase 1.5 LOG

- Harness: cursor
- Started: 2026-09-10
- Status: SPEC+PLAN 작성. 구현은 승인 후.

## Notes

- 컨셉 PNG와 `docs/conventions/design.md`를 대조해 코드 블록만 라이트 Prism으로 뒤집음.
- 스택: `feat/phase-1-scaffold` ← `feat/phase-1.5-visual`.
29 changes: 29 additions & 0 deletions .tasks/phase-1.5-visual-design/PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Phase 1.5 PLAN — Visual design 적용

> 상태: SPEC 대응 초안. 브랜치 `feat/phase-1.5-visual`, **base = `feat/phase-1-scaffold`**.

정본: [`docs/conventions/design.md`](../../docs/conventions/design.md).
목업: [`.tasks/visual-concept-by-gpt-09-10.png`](../visual-concept-by-gpt-09-10.png).

## 순서

1. **토큰** — `src/styles/tokens.stylex.ts`를 design.md §3·6·7로 교체 (canvas, surface, ink, accent `#16A36A`, space 4px, radius). Phase 1 `#3F6B5A` / `#FAFAF8` 제거. 컴포넌트가 시맨틱 토큰만 쓰게 맞춤.
- 수용: `bun run check` 그린, Storybook에서 paper가 `#F7F5EE`에 가깝다.
2. **폰트** — Pretendard 또는 Noto Sans KR, Geist Mono. 디스플레이는 라이선스 확인 후 1개만(히어로·기사 제목). `Base.astro`에서 로드. 본문·nav에 손글씨 금지.
3. **Prism** — `bun add @astrojs/prism prismjs`. `astro.config.mjs` `markdown: { syntaxHighlight: 'prism' }`. `src/styles/prism-vitesse-light.css` (design.md §11 토큰). `Base.astro`에서 import. `src/components/content/CodeBlock` (lang, copy). 다크 테마 CSS 없음.
- 수용: 빌드 HTML에 `class="language-*"`, `pre` 배경이 `#F1EFE6` 근처. `grep -l okaidia` 없음.
4. **Home** — 컨셉 01: 작은 라벨, 손글씨 문장, 짧은 소개, CTA, 반대편 장식(WebGL island 또는 CSS 폴백). 최신글은 리스트(날짜·제목·요약·태그). `prefers-reduced-motion`이면 정적 민트 형태만.
5. **목업 기사·위키** — `src/pages/articles/mock.astro`, `src/pages/til/mock.astro` (Phase 2 라우트와 맞출 이름). 기사: 메타 + 손글씨 제목 + 본문 폭 `--reading-max` + 우측 TOC(데스크탑) + Prism 예시 + Tip callout. 위키: 좌측 가벼운 사이드바 + 본문. Collections 없음.
6. **스토리** — 토큰·CodeBlock·Header·PostCard 갱신. `bun run build-storybook`.
7. **게이트** — `check` / oxfmt / oxlint / vitest / build / Lighthouse Home+mock article / 런타임 JS 스타일 주입 0.
8. **draft PR** — `--base feat/phase-1-scaffold --assignee @me --label phase-1.5 --label astro --label conventions`. 머지는 사람. Phase 1(#56)이 먼저 머지돼야 디프가 맞다.

## 검증

- Prism: mock 페이지 소스에 `token keyword` 등이 있고, 스크린샷에서 코드 블록이 베이지다 (차콜 아님).
- `bunx oxfmt --check .` · `bunx oxlint .` 그린.

## 승인 요청

- [ ] 다크 코드 블록을 버리고 Prism Vitesse Light 계열로 가는 것 동의?
- [ ] 실 콘텐츠 없이 mock article/wiki로 레이아웃을 먼저 고정하는 것 동의? (Phase 2에서 교체)
49 changes: 49 additions & 0 deletions .tasks/phase-1.5-visual-design/SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Phase 1.5 — Visual design 적용

> 상태: SPEC+PLAN 작성됨 / 승인 대기. 브랜치 `feat/phase-1.5-visual`, base `feat/phase-1-scaffold`.

## 1. 배경

Phase 1은 스캐폴드·토큰 자리·Home/Tags 껍데기까지다. 토큰은 아직 paper `#FAFAF8` / sage accent `#3F6B5A`다.

2026-09-10 컨셉 [`.tasks/visual-concept-by-gpt-09-10.png`](../visual-concept-by-gpt-09-10.png)과 계약 [`docs/conventions/design.md`](../../docs/conventions/design.md)이 생긴다. 콘텐츠 이식(Phase 2) 전에 **보이는 페이지를 이 계약에 맞춘다.**

검토 결론 (구현은 계약 파일):

- 따뜻한 베이지 캔버스 + 민트 액센트 + 손글씨 디스플레이(희소) + Geist Mono — 컨셉과 문서가 같다.
- 컨셉 목업 헥스(`#FBF6EF`, `#10B981`, 카드 `#FFF`)는 Tailwind에 가깝다. 구현은 design.md (`#F7F5EE`, `#16A36A`, surface `#FCFBF7`).
- 컨셉·초안 design.md의 **다크 코드 블록은 버린다.** Prism.js + Vitesse Light 계열, 배경은 캔버스에 한 단계만 낮춘 `#F1EFE6`, 키워드는 액센트.

## 2. 목표

1. StyleX 시맨틱 토큰을 `docs/conventions/design.md` §3·§6·§7에 맞춘다. Phase 1 자리 토큰을 덮어쓴다.
2. 타이포: Pretendard/Noto Sans KR 본문, Geist Mono 코드·메타, 디스플레이 손글씨(히어로·기사 제목만).
3. Home을 컨셉 01에 가깝게: 손글씨 히어로, CTA, 최신글은 빽빽한 그리드가 아니라 에디토리얼 리스트. WebGL은 island + 정적 폴백 + `prefers-reduced-motion`.
4. 목업 기사(`/articles/mock`)와 위키(`/til/mock` 또는 `/wiki/mock`): 우측 TOC / 좌측 사이드바, Callout, **Prism 코드 블록**. 실 Collections는 Phase 2.
5. 코드: `markdown.syntaxHighlight: 'prism'`, `@astrojs/prism`, `src/styles/prism-vitesse-light.css`를 `Base.astro`에서 로드. 다크 Prism 테마 금지.
6. 해당 UI `*.stories.ts` 갱신.

## 3. 비목표

- MDX 6편 이식, Collections, `colorway` 다중 테마 (Phase 2).
- Quiz, Pagefind, 다크모드.
- 컨셉의 “Was this helpful?” / Three.js를 전 페이지에 깔기.

## 4. 산출물

- 갱신된 `src/styles/tokens.stylex.ts`, `prism-vitesse-light.css`, `CodeBlock` (+ copy).
- Home / mock article / mock wiki가 컨셉 레이아웃을 따른다.
- Storybook 스토리 갱신.

## 5. 종료 게이트

- [ ] `bun run check` · `bunx oxfmt --check .` · `bunx oxlint .` · `bunx vitest run` 그린.
- [ ] `bun run build` 그린. 런타임 스타일 주입 0. Prism 클래스가 HTML에 있고, 코드 `pre` 배경이 다크(`#171A18` 등)가 아님.
- [ ] Home·mock article Lighthouse a11y ≥ 95. `prefers-reduced-motion`에서 WebGL 미로드.
- [ ] `bun run build-storybook` 그린.
- [ ] 본문 대비: canvas 위 ink가 WCAG AA.

## 6. 리스크

- 웹폰트 + WebGL이 Lighthouse perf를 깎음 → 서브셋, lazy island, 모바일에서 WebGL 생략.
- Gmarket Sans 라이선스: 컨셉에만 등장. 구현은 라이선스 확인된 디스플레이 페이스(또는 시스템 손글씨 폴백).
2 changes: 1 addition & 1 deletion .tasks/playbook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

Message verbs (`DONE`, `BLOCKED`, `PLAN-CHANGE`, `PLAN-READY`, `PR-DRAFT`, `PR-READY`, `REVIEW`) are identical across harnesses. Append every report to `.tasks/phase-N-*/LOG.md`.

PR lifecycle: developer opens `--draft` immediately at phase complete (`PR-DRAFT`) → verifier review (Cursor: GPT 5.6 Sol medium) → on `REVIEW APPROVE`, `gh pr ready` (`PR-READY`) → **human merges**.
PR lifecycle: developer opens `--draft` immediately at phase complete (`PR-DRAFT`) → verifier review (Cursor: Sol → Opus 5 if blocked → Grok·Kimi if expensive) → on `REVIEW APPROVE`, `gh pr ready` (`PR-READY`) → **human merges**.

A harness **may fold** orchestrator + leader into one parent session (Cursor default). That is a mapping, not a license to drop LOG or gates.

Expand Down
31 changes: 21 additions & 10 deletions .tasks/playbook/harness/cursor.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,38 @@ Never two write-capable agents on the same checkout.
| orchestrator / leader | Grok 4.6 in the parent picker | long tool loops, instruction following |
| planner | `inherit` | same judgment as parent |
| developer | `composer-2.5` (`composer-2.5-fast` if the Fast variant is the picker name) | edits + terminal |
| verifier | `gpt-5.6-sol-medium` | draft review (SPEC + gates). OpenAI models in Cursor: proposed shutoff **2026-11-12** ([OpenAI](https://openai.com/index/our-decision-on-cursor-following-its-acquisition-by-spacex/)). After that, fallback `inherit` (Grok) and LOG it. |
| verifier | `gpt-5.6-sol-medium` | Default review. Blocked → Opus 5. Expensive → Grok then Kimi K3. OpenAI shutoff 2026-11-12. |

On **legacy request-based plans without Max Mode**, Cursor may ignore `model:` and run subagents as Composer. If that happens, run planner/verifier in the parent Grok chat instead of Task, and LOG the fallback.

If Grok quota is exhausted: keep this harness, switch the **parent** picker to whatever reasoning model is available, and LOG it. Do not silently start Cline panes from a Cursor session.

## OpenAI / GPT window and usage

- Official proposed shutoff of OpenAI models in Cursor: **2026-11-12**. Do not start a Sol review on or after that date; switch verifier to Grok (`inherit`) first.
- After **every** Sol review, append to `.tasks/phase-N-*/LOG.md`:
- `model: gpt-5.6-sol-medium`
- start/end timestamps
- Cursor usage if the UI shows it (request cost on the review turn, or Settings → Usage delta). There is no billing API in this harness — if the number is not visible, write `usage: not visible` and still record the model + time.
- verdict (`REVIEW APPROVE|CHANGES`)
- If one review looks expensive relative to a Grok/Composer pass, **stop** and ask the human before the next Sol review. Candidate fallbacks: Grok (`inherit`), then Composer.
- Default review model: `gpt-5.6-sol-medium`. Proposed OpenAI Cursor shutoff **2026-11-12** ([OpenAI](https://openai.com/index/our-decision-on-cursor-following-its-acquisition-by-spacex/)).
- After **every** review spawn, append to `.tasks/phase-N-*/LOG.md`: model slug, start/end, `usage` (UI cost or `not visible`), verdict.
- Fallback (do not ask the human first — this is the pin):

```mermaid
flowchart TD
S["verifier spawn"] --> Sol["gpt-5.6-sol-medium"]
Sol -->|"blocked: resource_exhausted / 404 / after 2026-11-12"| Opus["claude-opus-5-thinking-high"]
Sol -->|"completed but expensive"| Cheap{"cheaper reviewer"}
Opus -->|"expensive or blocked"| Cheap
Cheap --> Grok["inherit Grok / cursor-grok-4.6-high"]
Cheap --> Kimi["kimi-k3-max"]
```

- **Blocked** = spawn error, quota, or shutoff. Next try is Opus 5.
- **Expensive** = the human or a huge usage delta vs a Grok pass. Next try is Grok, then Kimi K3. LOG the substitution.
- `.cursor/agents/verifier.md` `model:` stays Sol. Parent Task overrides `model` on fallback.

## Spawn sequence (per phase)

1. Parent (Grok) reads SPEC + PLAN + this file. Creates or updates `.tasks/phase-N-*/LOG.md` (leader duties).
2. `Use the planner subagent` (or `/planner`) with the Part A brief. Wait for `PLAN-READY`. Human may still be asked to approve PLAN deltas. Planner is **not** `readonly` (it writes PLAN.md); treat product-code edits as a bug.
3. After PLAN-READY: `Run the implementer subagent on Composer in its own worktree` with the developer brief (`../developer.md`). Isolation phrase is mandatory. Implementer must open `--draft` and stop at `PR-DRAFT`.
4. On `PR-DRAFT`: `/verifier` on **GPT 5.6 Sol medium** (covers planner Part B). Do not spawn a second reviewer. Record usage in LOG. Do not mark the PR ready yet.
4. On `PR-DRAFT`: `/verifier` on **GPT 5.6 Sol medium**. If spawn is blocked, retry Opus 5 (`claude-opus-5-thinking-high`). If a review is expensive, next ones use Grok then Kimi K3. Record usage in LOG. Do not mark the PR ready yet.
5. On `REVIEW APPROVE`: implementer (or parent) runs `gh pr ready`, then `PR-READY`.
6. Parent records ready + asks the **human to merge**. Do not `gh pr merge` unless the human explicitly asked for that phase (Phase 0 was that exception).

Expand All @@ -77,7 +87,8 @@ Parent prompt (copy):
Harness: cursor. Fold leader into this chat.
Use the planner subagent first (PLAN.md only). After PLAN-READY and human ack,
run the implementer subagent on Composer in its own worktree.
Implementer opens a draft PR (PR-DRAFT). Then run verifier on GPT 5.6 Sol medium.
Implementer opens a draft PR (PR-DRAFT). Then run verifier on GPT 5.6 Sol medium
(Opus 5 if Sol is blocked; Grok then Kimi K3 if a review is expensive).
After REVIEW APPROVE, gh pr ready. Do not merge. Do not implement product code in this chat.
```

Expand Down
Binary file added .tasks/visual-concept-by-gpt-09-10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
- Multi-agent: role contracts in `.tasks/playbook/`; spawn/models in `.tasks/playbook/harness/` (one harness per phase). Cursor default: [harness/cursor.md](.tasks/playbook/harness/cursor.md).
- Commits: [`docs/conventions/commits.md`](docs/conventions/commits.md) — logical units, conventional, Korean. Body 1–2 lines, max 3.
- PRs: [`docs/conventions/prs.md`](docs/conventions/prs.md) — why / effect / design diagrams / scope. Assignee `@me`. Labels from that doc. Comments in Korean.
- Cursor review: GPT 5.6 Sol medium until OpenAI Cursor shutoff (**2026-11-12**). Then Grok. Human merges from Phase 1.
- Cursor review: GPT 5.6 Sol medium. If Sol is blocked → Opus 5. If a review is expensive → Grok then Kimi K3. OpenAI Cursor shutoff **2026-11-12**. Human merges from Phase 1.
- Test titles in Korean (`describe` = symbol name).

## 6. Links
Expand Down
6 changes: 6 additions & 0 deletions design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Design System

Canonical: [`docs/conventions/design.md`](docs/conventions/design.md).

Visual mock: [`.tasks/visual-concept-by-gpt-09-10.png`](.tasks/visual-concept-by-gpt-09-10.png).
This root file is a pointer only — edit the conventions doc.
Loading