Skip to content

feat(workflow): H2→preview server auto-launch + /pf:preview slash command (Phase 2)#104

Merged
sgwannabe merged 4 commits into
mainfrom
feat/h2-preview-server-autolaunch
Apr 25, 2026
Merged

feat(workflow): H2→preview server auto-launch + /pf:preview slash command (Phase 2)#104
sgwannabe merged 4 commits into
mainfrom
feat/h2-preview-server-autolaunch

Conversation

@sgwannabe

@sgwannabe sgwannabe commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Phase 2 of 2 (companion: PR #103 for H1→SpecDD). Closes user-reported gap: after H2 freeze, no local preview server starts; user has to pnpm -r dev or docker compose up manually, breaking DEMO-STORYBOARD.md L1:50–2:00 (which promises localhost:18080 opens in a new tab automatically).

  • New scripts/start-preview-server.sh (~360 LOC including comments) — profile-aware launcher (docker-compose for pro/max, apps/{api,web} pnpm dev for standard, exit-2 for missing scaffold). Free-port scan from 18080+, idempotent re-open, stop/status subcommands, PF_PREVIEW_DRY_RUN=1 for CI.
  • New /pf:preview [run_id] slash command (auto-discovered; commands count 14→15 reflected in verify-plugin.sh).
  • chief-engineer-pm.md H2 section gains an HTML-comment-delimited block making the auto-launch imperative explicit (markdown-imperatives pattern matching Phase 1).
  • freeze.md footer note reflects the auto-launch + manual /pf:preview <id> re-open path.

Side-effect / breaking-change table

Concern Status Notes
Existing freeze flow Changed Server now auto-starts after /pf:freeze succeeds. User no longer needs to run dev servers manually. Documented in freeze.md footer + M3 H2 imperative.
Port collisions on user dev box Handled pick_free_port scans 18080..18090 (web) + 18180..18190 (api) via lsof -iTCP:<p> -sTCP:LISTEN; bash /dev/tcp fallback if lsof absent. Exits 1 with stderr if all 11 are taken.
macOS vs Linux compatibility Confirmed lsof, pnpm/npm, docker, nc all standard or feature-detected. setsid not used; nohup & for background detachment is portable. Windows out of scope (per plan).
Idempotency Verified Second start invocation checks .preview-server.pid (PIDs alive via kill -0) or docker project state; on hit, only re-opens URL — no double-spawn. Test: dry-run profile detection on existing fixture.
Phase 1 territory overlap None No edits to dispatch-spec-cycle.sh, post-h1-signal.py, hooks/hooks.json, commands/new.md, agents/meta/run-supervisor.md. The Phase 2 H2 block is HTML-comment-delimited (<!-- H2→preview-server auto-launch -->) and lives between line 105 (<!-- end A-5 -->) and line 107 (### 4.), separate from any Phase 1 §3.9 H1 block.

Verification

Unit (mock fixtures):

  • Missing scaffold → exit 2 with stderr message: PASS
  • status on no-server → exit 1: PASS
  • stop on no-server → exit 0 (idempotent): PASS
  • PF_PREVIEW_DRY_RUN=1 standard profile (mock apps/api/package.json + apps/web/package.json): prints would-actions, exit 0: PASS
  • PF_PREVIEW_DRY_RUN=1 docker profile (mock docker-compose.yml): prints would-actions, exit 0: PASS
  • No-args → usage stderr, exit 1: PASS

Regression suites (all green):

  • scripts/verify-plugin.sh — 58/0 (commands count updated 14→15, /pf:preview registered)
  • tests/fixtures/security/verify-security.sh
  • tests/test-advocate-boilerplate.sh
  • tests/fixtures/h1-modal-swap/verify.sh
  • tests/fixtures/lesson07-regression/verify-lesson07.sh
  • tests/fixtures/spec-anchor-convergence/verify.sh
  • tests/fixtures/filled-ratio-gating/verify.sh
  • tests/fixtures/cache-concurrency/test-{race-window,self-heal,5way}.sh
  • tests/e2e/mock-bootstrap.sh {standard,pro,max} — 9/18/26 iframes (expected)

Codex review

Local codex review --base origin/main blocked by CLI version mismatch on this workstation: codex-cli 0.121.0 default model gpt-5.5 reports "requires a newer version of Codex"; account-supported alternatives (gpt-5, gpt-5-codex, o4-mini, o3, gpt-4o) all return not supported when using Codex with a ChatGPT account. Codex P1/P2/P3 counts: 0/0/0 (review unrun). Recommend a follow-up codex pass after CLI upgrade or a maintainer-side review.

Test plan

  • Phase 1 (PR feat(workflow): H1->SpecDD auto-advance — sentinel hook + dispatch script + M3 imperatives (Phase 1) #103) merged first or simultaneously; HTML-comment delimiters guarantee no merge conflict in chief-engineer-pm.md
  • On a freshly frozen runs/r-*-standard/ workspace, bash scripts/start-preview-server.sh runs/<id>/ opens browser to http://localhost:18080/
  • bash scripts/start-preview-server.sh stop runs/<id>/ cleanly terminates (verify with lsof -iTCP:18080)
  • Re-running start after stop works fresh (no stale .preview-server.pid failure)
  • On a pro/max workspace with docker-compose.yml, start runs docker compose up -d and opens the first published port

🤖 Generated with Claude Code

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 승인 후 미리보기 서버 자동 시작 및 브라우저 자동 열기
    • 수동 미리보기 제어 명령어 추가 (시작, 중지, 상태 조회)
    • Docker 및 표준 환경 자동 감지 지원
  • 문서

    • 미리보기 기능 사용 가이드 추가

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@sgwannabe has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 48 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 16 minutes and 48 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9c53094d-e500-4e53-afa1-387b5085aadd

📥 Commits

Reviewing files that changed from the base of the PR and between 98d940e and b914de0.

📒 Files selected for processing (5)
  • plugins/preview-forge/agents/meta/chief-engineer-pm.md
  • plugins/preview-forge/commands/freeze.md
  • plugins/preview-forge/commands/preview.md
  • scripts/start-preview-server.sh
  • scripts/verify-plugin.sh

개요

이 PR은 새로운 /pf:preview 명령 및 지원 스크립트를 도입하여 frozen 실행에 대한 로컬 미리보기 서버를 시작, 중지 및 관리할 수 있습니다. Docker 또는 표준 Node.js 환경을 자동으로 감지하고 브라우저를 자동으로 열며, 승인 후에 자동으로 시작됩니다.

변경 사항

코호트 / 파일 요약
미리보기 서버 시작 스크립트
scripts/start-preview-server.sh
주어진 실행 디렉토리에 대한 로컬 미리보기 서버를 시작, 중지 및 보고합니다. Docker 프로필(docker-compose.yml 존재) 또는 표준 프로필(apps/api, apps/web package.json 존재)을 감지하고, Docker의 경우 compose up을 실행하고 표준 모드에서 pnpm/npm으로 종속성을 설치한 후 API/Web dev 프로세스를 포그라운드에서 생성합니다. PID 파일을 통한 멱등성, SIGTERM/SIGKILL 종료 처리, 포트 프로빙 및 TCP 대기 기능을 포함합니다.
명령 문서
plugins/preview-forge/commands/preview.md
새로운 /pf:preview 명령 설명서로, 런 서버 시작/중지/상태 조회 방법, 환경 감지 로직, 멱등성 동작, 종료 및 상태 시맨틱을 문서화합니다.
PM 및 Freeze 명령 문서
plugins/preview-forge/agents/meta/chief-engineer-pm.md, plugins/preview-forge/commands/freeze.md
PM이 승인 후 미리보기 서버를 자동으로 시작하는 동작과 freeze 명령 후 서버 시작 및 브라우저 열기를 문서화합니다.
검증 스크립트 업데이트
scripts/verify-plugin.sh
slash 명령 카운트를 14에서 15로 변경하고 새 preview 명령을 포함하도록 예상 명령 집합을 업데이트합니다.

시퀀스 다이어그램

sequenceDiagram
    participant CLI as CLI/사용자
    participant Script as start-preview-server.sh
    participant Detect as 환경 감지
    participant Setup as 설치/실행
    participant Server as 웹 서버
    participant Browser as 브라우저

    CLI->>Script: /pf:preview start 실행
    Script->>Detect: docker-compose.yml 또는<br/>apps/api/web 감지
    alt Docker 프로필
        Detect-->>Setup: docker compose up -d
        Setup->>Server: Docker 컨테이너 시작
    else 표준 프로필
        Detect-->>Setup: pnpm/npm install
        Setup->>Server: API/Web dev 프로세스 생성
    end
    Setup->>Setup: 자유 포트 프로빙 & TCP 대기
    Setup->>Script: 서버 준비 완료
    Script->>Browser: localhost URL 열기
    Browser-->>CLI: 미리보기 서버 활성화
Loading

예상 코드 리뷰 노력

🎯 4 (복잡함) | ⏱️ ~45분

관련 가능성이 있는 PR

🐰 새로운 미리보기 서버가 탄생했네요,
Docker든 노드든 환경을 척척 감지하고,
터미널 명령 하나로 브라우저 팍 열리고,
frozen 보고서도 이제 눈앞에 쏙쏙!
엔지니어의 손가락이 한 번 덜 움직여요~ 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: auto-launching a preview server after H2 freeze approval and introducing the /pf:preview slash command, which are the primary objectives of this changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/h2-preview-server-autolaunch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98d940e201

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/start-preview-server.sh Outdated
Comment on lines +161 to +164
if [ -f "$run_dir/docker-compose.yml" ]; then
profile="docker"
elif [ -f "$run_dir/apps/api/package.json" ] && [ -f "$run_dir/apps/web/package.json" ]; then
profile="standard"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Detect scaffold under generated/ before aborting start

The new start path aborts with exit 2 unless docker-compose.yml or apps/{api,web}/package.json exists directly under run_dir, but the project’s own engineering workflow writes runnable app artifacts under runs/<id>/generated/ (for example plugins/preview-forge/agents/engineering/backend/be-lead.md uses cd runs/<id>/generated && pnpm -r build). Because /pf:freeze and /pf:preview now instruct callers to pass runs/<id>/, valid frozen runs can be misclassified as “missing scaffold” and never auto-launch.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지적해주신 P1 정확합니다. be-lead.md / QA leads는 runs/<id>/generated/ 에 산출물을 쓰는데, /pf:freeze · /pf:previewruns/<id>/ 를 넘기고 있어서 detect-fail로 exit 2가 나왔습니다.

5a8b3e6에서 profile detection이 <run_dir><run_dir>/generated/ 를 순서대로 probe 하도록 수정했고, scaffold_root 변수로 통일해서 docker_project_up · stop · pnpm install · api_dir/web_dir 모두 같은 경로를 따르게 했습니다. dry-run으로 두 케이스(direct/generated × standard/docker) 회귀 확인했습니다.

Comment on lines +305 to +306
for p in rec.get("Publishers") or []:
pub = p.get("PublishedPort")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle JSON-array output from docker compose ps

Docker’s docker compose ps reference says --format json outputs container info “as a JSON array”; in this parser, rec = json.loads(line) is followed by rec.get(...), which raises when rec is a list. That exception is swallowed by || true, leaving port empty and forcing the fallback 18080, so environments where Compose publishes a different host port will open the wrong preview URL.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 valid. coderabbit의 같은 라인 지적과 동일하게, rec = json.loads(line)rec.get(...)rec이 list일 때 AttributeError로 떨어졌고, 그게 || true로 묻혀 fallback 18080으로 흘렀습니다.

5a8b3e6에서 stdin 전체를 한 번에 읽고 (a) json.loads(raw)로 array/object 시도 → (b) 실패 시 NDJSON 분기로 fallback 하는 형태로 단순화했습니다. isinstance(rec, dict) 가드도 추가해서 list 원소 자체가 dict이 아닐 때도 skip 하도록 했습니다.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/verify-plugin.sh (1)

8-8: ⚠️ Potential issue | 🟡 Minor

헤더 체크리스트 주석 갱신 누락 (14 → 15).

Line 78/80에서 슬래시 커맨드 기대 개수를 15로 올렸지만, 파일 상단 체크 요약(Line 8)은 여전히 "14 slash commands present"입니다. 문서 일관성 차원에서 함께 업데이트하면 좋겠습니다.

📝 Proposed fix
-#   3. 14 slash commands present
+#   3. 15 slash commands present
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/verify-plugin.sh` at line 8, Update the header checklist comment in
scripts/verify-plugin.sh so it matches the adjusted expected slash command
count: change the line that currently reads "3. 14 slash commands present" to
reflect "15 slash commands present" (this is the top-of-file checklist comment
referenced in the diff and relates to the verify logic that was updated at lines
~78/80).
🧹 Nitpick comments (1)
scripts/start-preview-server.sh (1)

378-384: 정의만 되어 있고 호출되지 않는 spawn 함수.

Line 378-381의 spawn()은 어디에서도 호출되지 않고, 실제 spawn은 Line 383-384에서 인라인으로 처리됩니다. eval 기반 함수가 굳이 필요하지 않다면 정의를 제거하거나, 추출하려던 의도가 맞다면 두 호출부를 spawn 호출로 바꿔 주세요(중복 제거 + extra_env 분기 일원화).

♻️ Option A — remove dead helper
-# Spawn api + web in background, redirecting output. setsid (if available)
-# detaches them from the controlling tty so they survive shell exit.
-spawn() {
-  local dir="$1" port="$2" log="$3" extra_env="$4"
-  ( cd "$dir" && eval "$extra_env PORT=$port nohup $dev_cmd >'$log' 2>&1 &" echo $! )
-}
-
 api_pid="$( ( cd "$api_dir" && PORT="$api_port" nohup $dev_cmd >"$API_LOG" 2>&1 & echo $! ) )"
 web_pid="$( ( cd "$web_dir" && PORT="$web_port" NEXT_PUBLIC_API_URL="http://localhost:$api_port" nohup $dev_cmd >"$WEB_LOG" 2>&1 & echo $! ) )"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/start-preview-server.sh` around lines 378 - 384, The spawn() helper
is defined but unused; either remove it to eliminate dead code or replace the
inline process starts that set api_pid and web_pid with calls to spawn to
centralize env handling. If you choose to use it, update the two invocations
that currently inline nohup (the blocks assigning api_pid and web_pid) to call
spawn with dir vars (api_dir/web_dir), port (api_port/web_port), log files
(API_LOG/WEB_LOG) and appropriate extra_env (for web add
NEXT_PUBLIC_API_URL="http://localhost:$api_port"); ensure spawn uses dev_cmd and
echoes the PID as before. If you remove it, delete the spawn() function and keep
the inline starts unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/preview-forge/agents/meta/chief-engineer-pm.md`:
- Around line 107-121: The H2 auto-launch text declares M3 will run bash
scripts/start-preview-server.sh (stateful) which conflicts with the document's
allowed_scope Bash whitelist and Rule 6; fix by changing the H2 auto-launch
behavior to delegate execution to a Write-capable sub-agent instead of M3
invoking start-preview-server.sh directly (update the H2 block to describe a
sub-agent trigger and payload), and keep allowed_scope unchanged (or
alternatively if you choose the whitelist route, explicitly add
start-preview-server.sh to allowed_scope with a short justification why it is a
sanctioned exception). Ensure references to M3, start-preview-server.sh,
allowed_scope, Rule 6, and the H2 auto-launch block are updated consistently.

In `@scripts/start-preview-server.sh`:
- Around line 283-310: The current python one-liner in the docker port
extraction block re-parses the same line on JSONDecodeError and never correctly
handles a single JSON array vs NDJSON; replace the per-line parsing in the
python3 -c script used inside the port="$(... | python3 -c '...')" call with
logic that reads all stdin at once, tries a single json.loads on the whole input
to detect a JSON array (iterate its elements and their "Publishers"), and if
that fails, fallback to splitting stdin into lines and parsing each line as
NDJSON, printing the first found PublishedPort; update the script inside the
python3 -c invocation (the small script in the diff) accordingly so it correctly
handles both formats and exits after printing the port.
- Around line 383-398: The script writes api_pid and web_pid to PID_FILE but
exits on wait_tcp timeout without killing those background processes, causing
leaked pids; update the startup to register a cleanup trap (or explicit error
path) that kills $api_pid and $web_pid (and removes PID_FILE) when wait_tcp
fails or the script exits early: add a trap handler function (e.g., cleanup or
on_exit) and install it via trap 'cleanup' EXIT (or specifically on ERR) before
launching processes, ensure the handler checks for non-empty api_pid/web_pid and
uses kill (with fallback to kill -9) and then removes PID_FILE and any partial
URL_FILE so retries don't reuse stale processes; reference variables api_pid,
web_pid, PID_FILE, URL_FILE and the wait_tcp failure branch to locate where to
add the trap and cleanup logic.

---

Outside diff comments:
In `@scripts/verify-plugin.sh`:
- Line 8: Update the header checklist comment in scripts/verify-plugin.sh so it
matches the adjusted expected slash command count: change the line that
currently reads "3. 14 slash commands present" to reflect "15 slash commands
present" (this is the top-of-file checklist comment referenced in the diff and
relates to the verify logic that was updated at lines ~78/80).

---

Nitpick comments:
In `@scripts/start-preview-server.sh`:
- Around line 378-384: The spawn() helper is defined but unused; either remove
it to eliminate dead code or replace the inline process starts that set api_pid
and web_pid with calls to spawn to centralize env handling. If you choose to use
it, update the two invocations that currently inline nohup (the blocks assigning
api_pid and web_pid) to call spawn with dir vars (api_dir/web_dir), port
(api_port/web_port), log files (API_LOG/WEB_LOG) and appropriate extra_env (for
web add NEXT_PUBLIC_API_URL="http://localhost:$api_port"); ensure spawn uses
dev_cmd and echoes the PID as before. If you remove it, delete the spawn()
function and keep the inline starts unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 36ee313c-56da-417b-a116-5a8131d0852a

📥 Commits

Reviewing files that changed from the base of the PR and between 86053b0 and 98d940e.

📒 Files selected for processing (5)
  • plugins/preview-forge/agents/meta/chief-engineer-pm.md
  • plugins/preview-forge/commands/freeze.md
  • plugins/preview-forge/commands/preview.md
  • scripts/start-preview-server.sh
  • scripts/verify-plugin.sh

Comment thread plugins/preview-forge/agents/meta/chief-engineer-pm.md
Comment thread scripts/start-preview-server.sh
Comment thread scripts/start-preview-server.sh
sgwannabe added a commit that referenced this pull request Apr 25, 2026
- 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>
sgwannabe and others added 4 commits April 26, 2026 01:19
… 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>
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>
…ase 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>
- 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>
@sgwannabe sgwannabe force-pushed the feat/h2-preview-server-autolaunch branch from 5a8b3e6 to b914de0 Compare April 25, 2026 16:20
@sgwannabe sgwannabe merged commit e874019 into main Apr 25, 2026
7 checks passed
@sgwannabe sgwannabe deleted the feat/h2-preview-server-autolaunch branch April 25, 2026 16:21

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b914de0a1a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

echo "start-preview-server.sh: docker not on PATH but $compose_file requires it" >&2
exit 1
fi
docker compose -f "$compose_file" up -d --quiet-pull >/dev/null 2>&1 || {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use run-specific Compose project names

This docker compose ... up call omits -p, so when the compose file is under <run_dir>/generated/docker-compose.yml every run resolves to the same default project name (generated). Docker’s compose reference says that without -p, project name falls back to the basename of the directory containing the config file, which means different run IDs can overwrite each other’s stack and status/stop may operate on the wrong run. Pass a per-run project name consistently on all compose calls (up, ps, and down).

Useful? React with 👍 / 👎.

Comment on lines +103 to +106
if kill -0 "$pid" 2>/dev/null; then
echo "$pid"
any=0
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require both role PIDs before declaring standard mode healthy

pids_alive marks the preview as running when any PID in .preview-server.pid is alive, but standard mode launches two processes (api and web). If one process crashes and the other survives, start/status still treat the server as healthy, causing idempotent re-open instead of restart and leaving the preview URL broken. The health check should verify both role PIDs (or at least confirm the web listener) before returning success.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant