Skip to content

Commit e874019

Browse files
sgwannabeclaude
andauthored
feat(workflow): H2→preview server auto-launch + /pf:preview slash command (Phase 2) (#104)
* feat(scripts): start-preview-server.sh — profile-aware preview server launcher (Phase 2) Bridges H2 freeze → live local app gap (DEMO-STORYBOARD.md L1:50–2:00). Auto-detects profile (docker-compose.yml vs apps/{api,web}/package.json), picks free port from 18080+, spawns dev servers in background, opens browser. Idempotent (re-runs only re-open URL), supports stop + status subcommands. PF_PREVIEW_DRY_RUN=1 keeps unit tests light. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(commands): /pf:preview slash command (Phase 2) User-facing manual entry point for re-opening or stopping the local preview server post-H2 (e.g. after a reboot or explicit /pf:preview stop). Wraps scripts/start-preview-server.sh; defaults to most-recent run when run_id omitted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(agents,commands): explicit H2→preview auto-launch imperative (Phase 2) Adds an HTML-comment-delimited block to chief-engineer-pm.md instructing M3 to invoke scripts/start-preview-server.sh immediately after H2 approval — matching the markdown-imperatives pattern Phase 1 uses for H1→SpecDD. freeze.md gains a footer note describing the same auto-launch and the manual /pf:preview re-open / stop commands. The HTML delimiter keeps the H2 block textually distinct from any §3.9 H1 dispatch block Phase 1 may add, so the two PRs merge cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(preview-server): apply PR #104 review feedback (codex + coderabbit) - Detect scaffold under <run_dir>/generated/ in addition to <run_dir>/ so freshly-frozen runs (be-lead writes apps to runs/<id>/generated/) auto-launch instead of mis-aborting with exit 2 (codex P1). - Replace per-line `docker compose ps --format json` parser with read-all-stdin logic that correctly handles both NDJSON and single JSON-array formats (codex P2 + coderabbit minor). - Add cleanup_spawned trap so wait_tcp 60s timeout no longer leaks api/web pids; PID_FILE is removed and SIGTERM sent to both children before exit (coderabbit major). - Remove unused spawn() helper to eliminate dead code (coderabbit nitpick). - chief-engineer-pm.md: explicitly whitelist start-preview-server.sh in allowed_scope as a v1.7.0+ Phase 2 sanctioned exception, resolving the Rule 6 conflict between the H2 auto-launch block and the read-only Bash policy (coderabbit major). - verify-plugin.sh: sync header checklist comment 14 -> 15 to match the command-count assertion at line 80 (coderabbit minor, outside-diff). Refs PR #104 review comments Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 17f354a commit e874019

5 files changed

Lines changed: 502 additions & 7 deletions

File tree

plugins/preview-forge/agents/meta/chief-engineer-pm.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,23 @@ Task({
128128
이 dispatch는 markdown 지시가 아니라 **명령형 imperative** — LLM trust 줄이기 위해 의도적으로 명시적 Task block.
129129
<!-- end H1→SpecDD auto-advance -->
130130

131+
<!-- H2→preview-server auto-launch (PR Phase 2, addresses user-reported gap) -->
132+
#### H2 승인 후 즉시 preview 서버 자동 기동 (자동, 사용자 입력 없음)
133+
134+
`/pf:export` (또는 사용자가 H2에서 deploy 승인) 후, M3는 **즉시** preview 서버를 기동한다. README의 "human clicks twice" 약속에 따라 H2 외에는 자동 진행.
135+
136+
검증 스크립트 (Phase 1과 동일한 plugin-root 절대 경로 형태 — 사용자 workspace에서 `scripts/`가 없어도 동작):
137+
```bash
138+
bash "${CLAUDE_PLUGIN_ROOT}/../../scripts/start-preview-server.sh" runs/<id>/
139+
# exit 0 → 서버 기동 + 브라우저 자동 오픈
140+
# exit 2 → scaffold 누락 (TestDD freeze 미완료); 사용자에게 보고
141+
```
142+
143+
수동 재실행 / 정지: `/pf:preview <id>` / `/pf:preview stop <id>`.
144+
145+
Idempotent: 이미 살아있는 서버에 대해서는 URL만 다시 열기, 재기동 안 함.
146+
<!-- end H2→preview-server auto-launch -->
147+
131148
### 4. Memory 파일 관리 (쓰기 권한 독점)
132149

133150
**Rule 3**에 따라 당신만 `memory/{CLAUDE,PROGRESS,LESSONS}.md`에 쓸 수 있습니다. 다른 agent는 Blackboard에 `memory.request.{file}` 키로 요청 → 당신이 검토 후 batch 반영.
@@ -179,9 +196,10 @@ Auto-retro-trigger 훅이 Blackboard에 `retro.requested` 행을 기록하면:
179196
- `runs/<id>/design-approved.json` (Gate H1 수집 결과)
180197
- `/memories/m3-decisions/*.md` (자신의 reflection)
181198
- Task: 모든 department lead 호출 가능
182-
- Bash: **H1/H2 gate 지원용 read-only scripts만** 허용 (v1.6.0+). 구체적으로:
183-
- `scripts/generate-gallery.sh <run-dir>` (H1 gallery HTML 생성)
184-
- `scripts/open-browser.sh <path-or-url>` (H1 gallery auto-open, 비블로킹)
199+
- Bash: **H1/H2 gate 지원용 scripts만** 허용 (v1.6.0+). 구체적으로:
200+
- `scripts/generate-gallery.sh <run-dir>` (H1 gallery HTML 생성, read-only)
201+
- `scripts/open-browser.sh <path-or-url>` (H1 gallery auto-open, 비블로킹, read-only)
202+
- `scripts/start-preview-server.sh <run-dir>``start|stop|status` 형태 (v1.7.0+ Phase 2 sanctioned exception: stateful이지만 idempotent + run_dir-local 작용으로 한정 — H2 finalize 직후 single-shot으로만 호출. PID/URL/log 파일은 모두 `<run_dir>/.preview-*`에만 기록되며, factory-policy/Rule 6 enforcement에서 명시적으로 화이트리스트 처리됨.)
185203
- 그 외 destructive·stateful Bash는 차단 (Rule 6). 상태 변화는 Write 또는 sub-agent 위임.
186204

187205
## forbidden

plugins/preview-forge/commands/freeze.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ description: Force evaluate Judges + Auditors and attempt freeze
2020

2121
현재 run의 Stage 7 (Judges + Auditors)를 강제 실행. 점수 미달이면 dissent와 함께 보고만 하고 freeze 안 함.
2222

23+
## After freeze
24+
25+
Once `score/report.json` is locked and `.frozen-hash` written, M3 automatically launches the local preview server (`bash scripts/start-preview-server.sh runs/<id>/`) and opens your browser to the running app. To re-open or stop the server later: `/pf:preview <id>` / `/pf:preview stop <id>`.
26+
2327
## 관련
2428

2529
- 본 명령은 plugin `preview-forge`의 일부입니다.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
description: Launch the local preview server for a frozen run (post-H2 or manual re-open)
3+
---
4+
5+
# /pf:preview — Launch the local preview server for a frozen run
6+
7+
**Layer-0 정책**: Pro/Max 기본 포함. 별도 API 키 불필요.
8+
9+
## Usage
10+
11+
```
12+
/pf:preview [run_id]
13+
/pf:preview stop [run_id]
14+
/pf:preview status [run_id]
15+
```
16+
17+
## 인자
18+
19+
- `run_id` (optional): 특정 run. 생략 시 가장 최근 run (`ls -t runs/r-* | head -1`).
20+
21+
## 동작
22+
23+
`bash scripts/start-preview-server.sh runs/<id>/` 호출. `runs/<id>/` 의 내용으로 profile 자동 감지:
24+
25+
1. `docker-compose.yml` 존재 (pro/max) → `docker compose up -d` + 첫 published port → 브라우저 자동 오픈.
26+
2. `apps/api/package.json` + `apps/web/package.json` 존재 (standard) → 의존성 설치 → 18080부터 free port 자동 탐색 → `pnpm dev` 백그라운드 spawn → web TCP accept 대기 (≤60s) → 브라우저 자동 오픈.
27+
3. 둘 다 없음 → exit 2 (TestDD freeze 미완료).
28+
29+
본 명령은 H2 승인 직후 M3가 자동으로 한 번 호출하므로 수동 실행은 보통 **재오픈** 또는 **재기동** 용도다 (서버를 stop 했거나 머신을 재부팅한 경우).
30+
31+
## Idempotency
32+
33+
이미 살아있는 PID 가 `<run_dir>/.preview-server.pid` 에 있으면 재기동 없이 URL 만 다시 연다. 두 번 spawn 되지 않는다.
34+
35+
## 종료
36+
37+
- `/pf:preview stop <run_id>` — SIGTERM → 5s 대기 → SIGKILL fallback. docker 프로필은 `docker compose down`.
38+
- `/pf:preview status <run_id>` — 살아있으면 stdout 에 URL + exit 0, 아니면 exit 1.
39+
40+
## 관련
41+
42+
- 본 명령은 plugin `preview-forge`의 일부입니다.
43+
- 스크립트: `scripts/start-preview-server.sh` (CI 테스트용 `PF_PREVIEW_DRY_RUN=1` 지원).
44+
- Gap B 배경: DEMO-STORYBOARD.md L1:50–2:00 의 자동 localhost:18080 약속.
45+
- 상세 스펙: [preview-forge-proposal.html](../../../preview-forge-proposal.html)

0 commit comments

Comments
 (0)