[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DAN24SEPWN8N03Y8DYE85B":3,"skill-same:01M6DAN24SEPWN8N03Y8DYE85B":176},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":13,"repositoryHtmlUrl":55,"repositoryHomepageUrl":6,"ownerHtmlUrl":56,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":57,"install":58,"resources":71},"01M6DAN24SEPWN8N03Y8DYE85B","dev-bootstrap-application-script",null,"This skill should be used when asked to create a dev.sh (or similar) bash script that launches an application's full stack in tmux. It guides research of the project's services, generates an idempotent tmux bootstrap script with named windows, pane-ID-based splits, health checks, env loading, and sanitized per-run stdout\u002Fstderr logs.","tzeusy-org\u002Fai-bootstrap","tzeusy-org","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F141543652?v=4","01M6DAM1AP09H27BYGFY9QCNPB","01M6DAM1F4R187EK11XDN9JZKH",0,"MIT","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"dev bootstrap application script","bootstrap","dev","application","Bash","id","env","full","project","active","full stack","stack","tmux","health","services","logs","run","create","windows","research","2026-11-10 10:12:30",false,"---\nname: dev-bootstrap-application-script\ndescription: This skill should be used when asked to create a dev.sh (or similar) bash script that launches an application's full stack in tmux. It guides research of the project's services, generates an idempotent tmux bootstrap script with named windows, pane-ID-based splits, health checks, env loading, and sanitized per-run stdout\u002Fstderr logs.\nmetadata:\n  owner: tze\n  authors:\n    - tze\n  status: active\n  last_reviewed: \"2026-06-12\"\n---\n\n# Dev Bootstrap Application Script\n\n## Overview\n\nGenerate an idempotent bash script that launches every service in a project's full stack inside named tmux window(s), with up to 4 panes per window. The script handles session detection, window teardown\u002Frecreation, dependency ordering, health checks, per-run log capture, and optional reverse-proxy path-prefix bootstrapping (for tailscale serve, cloudflared, etc.).\n\nA ready-made template is bundled at `assets\u002Fdev.sh.template`.\n\n## When to Use\n\n- A user asks to \"write a dev script\", \"bootstrap the app in tmux\", or \"create a dev.sh\"\n- A user wants to launch multiple services (API, frontend, workers, databases) in one command\n- A user has an existing dev script and wants it rewritten following best practices\n\n## Workflow\n\n### Phase 1 — Research the Project\n\nBefore writing any code, discover what services the project needs. Read the following files (when present) to build a service inventory:\n\n| File | What to look for |\n|---|---|\n| `docker-compose.yml` \u002F `compose.yaml` | Infrastructure services (postgres, redis, rabbitmq, etc.) |\n| `package.json` | `scripts.dev`, `scripts.start`, framework (Next.js, Vite, Remix, etc.) |\n| `Makefile` \u002F `Justfile` | Existing `dev` \u002F `run` \u002F `serve` targets |\n| `Procfile` \u002F `Procfile.dev` | Named processes and their commands |\n| `pyproject.toml` \u002F `Pipfile` | Python entry points, uvicorn\u002Fgunicorn commands |\n| `Cargo.toml` \u002F `go.mod` | Build-and-run patterns |\n| `.env` \u002F `.env.example` | Environment variables needed at boot |\n| `turbo.json` \u002F `pnpm-workspace.yaml` | Monorepo workspace structure |\n| `README.md` | \"Getting Started\" \u002F \"Development\" sections |\n| Frontend router \u002F API client files | Whether routes and API calls are base-path aware |\n| Vite\u002FNext\u002Fwebpack dev config | Base path and dev proxy rewrite behavior |\n\nProduce a **service inventory** — an ordered list of:\n\n```\n1. Service name — command — working directory — depends on (if any)\n```\n\nExample:\n\n```\n1. postgres    — docker compose up -d postgres  — .          — (none)\n2. redis       — docker compose up -d redis     — .          — (none)\n3. api         — uv run uvicorn app:main        — .          — postgres, redis\n4. frontend    — npm run dev                    — .\u002Ffrontend — api\n```\n\n### Phase 2 — Design the Layout\n\n#### Pane Limit\n\nMaximum **4 panes per tmux window**. Beyond 4, panes become unreadably small.\n\n#### Window Count Decision\n\n| Services | Windows | Rationale |\n|---|---|---|\n| 1-4 | 1 window | Everything fits |\n| 5-8 | 2 windows | Group by concern (infra vs app, backend vs frontend) |\n| 9+ | 3 windows | Rare — consider if some services should stay in docker |\n\n#### Layout Selection\n\nPick the tmux preset layout that best matches the pane count:\n\n| Panes | Recommended layout | Visual |\n|---|---|---|\n| 2 | `even-horizontal` | `[A \\| B]` |\n| 2 | `even-vertical` | `[A \u002F B]` (stacked) |\n| 3 | `main-vertical` | `[A \\| B\u002FC]` (main left, two right) |\n| 3 | `main-horizontal` | `[A \u002F B\\|C]` (main top, two bottom) |\n| 4 | `tiled` | `[A\\|B \u002F C\\|D]` (2x2 grid) |\n\n#### Grouping Heuristic\n\nWhen splitting across multiple windows, group by concern:\n\n- **Window 1 (\"infra\")**: databases, caches, message brokers, docker services\n- **Window 2 (\"app\")**: API server, background workers, task queues\n- **Window 3 (\"frontend\")**: dev server, storybook, docs site\n\n### Phase 3 — Write the Script\n\nStart from `assets\u002Fdev.sh.template` and fill in the placeholders. Follow these mandatory patterns:\n\n#### Script Structure\n\n```\n1. Shebang + header comment with layout diagram\n2. set -euo pipefail\n3. Parse script args (for optional checks like --skip-tailscale-check)\n4. PROJECT_DIR and WINDOW constants\n5. Optional Layer 0 preflight (tailscale\u002Fdependencies\u002Fetc.)\n6. tmux prerequisite check\n7. Session detection (inside tmux vs new session)\n8. Kill existing window (idempotency)\n9. Create window + split panes (capture pane IDs)\n10. Small post-split delay before send-keys\n11. Initialize logs directory (timestamped run dir + latest symlink)\n12. Register pane log piping before launching commands\n13. Load environment variables\n14. Layer 1 launch services (send-keys to each pane)\n15. Layer 2 readiness gates (health endpoints\u002Fports)\n16. Print operator URLs (local + remote when available)\n17. Apply layout + set focus\n18. Attach if started detached\n```\n\n#### Mandatory Rules\n\n- **Pane IDs, never indices.** Always capture pane IDs with `-P -F '#{pane_id}'` and reference them by variable. Never use `tmux select-pane -t 0`.\n- **Idempotent.** `tmux kill-window -t \"${SESSION}:${WINDOW}\" 2>\u002Fdev\u002Fnull || true` before recreating.\n- **Session-aware.** Detect `$TMUX` to decide whether to create a session or reuse the current one.\n- **Header comment.** Every script must start with an ASCII layout diagram showing what runs where.\n- **Per-run logs + latest link.** Create logs under `logs\u002FYYYYmmdd_HHMMSS\u002F` and refresh `logs\u002Flatest -> logs\u002F\u003Crun_id>`.\n- **Pipe with `-o`.** Use `tmux pipe-pane -o` so re-runs do not stack duplicate pipe commands.\n- **Layered startup.** Prefer explicit layers (preflight -> launch -> readiness).\n- **User-facing URLs.** Always print local frontend URL and API base URL; print remote URL if a reverse proxy is configured.\n- **No prefix-only proxying.** If a path prefix is introduced (for example `\u002Fapp`), all app layers must agree on it (frontend base path, API path, router path parsing, and dev proxy rewrites).\n\n#### Reverse Proxy Prefix Coherency (Mandatory when using path prefixes)\n\nIf your script configures a reverse-proxy path prefix (for example `tailscale serve --set-path \u002Fmyapp`), ensure all of the following are aligned:\n\n1. Frontend dev server base path (`--base`, framework equivalent, or env setting).\n2. Frontend router path parsing\u002Fnavigation (strip\u002Fadd base path).\n3. API client prefix generation (`BASE_URL`-aware, not hardcoded root-only paths).\n4. Health\u002Freadiness fetch paths (for example `\u002Fready` -> `\u002Fmyapp\u002Fready` when prefixed).\n5. Dev proxy routes and rewrites (strip prefix before forwarding upstream).\n6. PWA scope\u002Fstart_url\u002Fassets if PWA is enabled.\n\nAnti-pattern to avoid: adding reverse-proxy path mapping alone while leaving client\u002Frouter\u002FAPI paths hardcoded to root.\n\n#### Tailscale Serve Preflight (Optional but Recommended)\n\nWhen bootstrapping HTTPS access via tailscale:\n\n1. Validate CLI exists (`command -v tailscale`).\n2. Validate authenticated state (`tailscale status --json`, reject `NeedsLogin`\u002F`Stopped` states).\n3. Inspect existing config first (`tailscale serve status --json`).\n4. Only apply missing mapping(s), then re-read status to verify mapping exists.\n5. Support CLI compatibility fallback (new vs legacy `tailscale serve` syntax).\n6. Emit actionable recovery instructions (manual command, `tailscale up`, permission hint such as `sudo tailscale set --operator=$USER` when relevant).\n7. Provide a skip flag (`--skip-tailscale-check`) for local-only workflows.\n\n#### Stdout\u002FStderr Logging (Mandatory)\n\nDirect `tmux pipe-pane ... \"cat >> file\"` captures interactive shell control sequences and pollutes logs. Use sanitized piping plus unbuffered writes.\n\n```bash\nLOGS_ROOT=\"${PROJECT_DIR}\u002Flogs\"\nLOGS_RUN_ID=\"$(date +%Y%m%d_%H%M%S)\"\nLOGS_RUN_DIR=\"${LOGS_ROOT}\u002F${LOGS_RUN_ID}\"\nLOGS_LATEST_LINK=\"${LOGS_ROOT}\u002Flatest\"\n\nmkdir -p \\\n  \"${LOGS_RUN_DIR}\u002Fbackend\" \\\n  \"${LOGS_RUN_DIR}\u002Fworkers\" \\\n  \"${LOGS_RUN_DIR}\u002Ffrontend\"\nrm -rf \"${LOGS_LATEST_LINK}\"\nln -s \"${LOGS_RUN_DIR}\" \"${LOGS_LATEST_LINK}\"\necho \"Logs for this run: ${LOGS_RUN_DIR}\"\n```\n\n```bash\npipe_pane_to_log() {\n  local pane_id=\"$1\"\n  local log_file=\"$2\"\n\n  tmux pipe-pane -o -t \"$pane_id\" \\\n    \"perl -pe 'BEGIN { \\$| = 1 } s\u002F\\\\e\\\\[[0-?]*[ -\\\\\u002F]*[@-~]\u002F\u002Fg; s\u002F\\\\e\\\\][^\\\\a]*(?:\\\\a|\\\\e\\\\\\\\)\u002F\u002Fg; s\u002F\\\\r\u002F\u002Fg; s\u002F[\\\\x00-\\\\x08\\\\x0B\\\\x0C\\\\x0E-\\\\x1F\\\\x7F]\u002F\u002Fg' >> '${log_file}'\"\n}\n```\n\n```bash\npipe_pane_to_log \"$PANE_API\" \"${LOGS_RUN_DIR}\u002Fbackend\u002Fapi.log\"\npipe_pane_to_log \"$PANE_WORKER\" \"${LOGS_RUN_DIR}\u002Fworkers\u002Fworker.log\"\npipe_pane_to_log \"$PANE_WEB\" \"${LOGS_RUN_DIR}\u002Ffrontend\u002Fweb.log\"\n```\n\nRequirements:\n- Include `BEGIN { $| = 1 }` in the sanitizer so logs are written incrementally (not buffered until process exit\u002Fbuffer fill).\n- Strip CSI + OSC + control characters before writing logs so `logs\u002Flatest\u002F**\u002F*.log` remains plain-text and grep-friendly.\n\n#### Pane Creation Patterns\n\nTwo panes (horizontal split):\n```bash\nPANE_LEFT=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_RIGHT=$(tmux split-window -t \"$PANE_LEFT\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n```\n\nThree panes (main-vertical — large left, two stacked right):\n```bash\nPANE_MAIN=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_TOP_R=$(tmux split-window -t \"$PANE_MAIN\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_BOT_R=$(tmux split-window -t \"$PANE_TOP_R\" -v -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n```\n\nFour panes (2x2 tiled):\n```bash\nPANE_TL=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_TR=$(tmux split-window -t \"$PANE_TL\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_BL=$(tmux split-window -t \"$PANE_TL\" -v -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_BR=$(tmux split-window -t \"$PANE_TR\" -v -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n```\n\n#### Multiple Windows\n\nWhen services overflow a single window, create additional windows:\n\n```bash\nWINDOW_1=\"myapp-infra\"\nWINDOW_2=\"myapp-app\"\n\n# Tear down both\ntmux kill-window -t \"${SESSION}:${WINDOW_1}\" 2>\u002Fdev\u002Fnull || true\ntmux kill-window -t \"${SESSION}:${WINDOW_2}\" 2>\u002Fdev\u002Fnull || true\n\n# Window 1: infrastructure\nPANE_DB=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW_1\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_CACHE=$(tmux split-window -t \"$PANE_DB\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n\n# Window 2: application\nPANE_API=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW_2\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_WEB=$(tmux split-window -t \"$PANE_API\" -h -c \"${PROJECT_DIR}\u002Ffrontend\" -P -F '#{pane_id}')\n```\n\n#### Environment Loading\n\n```bash\n# Single .env file\nexport $(grep -v '^#' \"$PROJECT_DIR\u002F.env\" | xargs -d '\\n')\n\n# Multiple env files (e.g., secrets + local overrides)\nENV_CMD=\"export \\$(grep -v '^#' \u002Fsecrets\u002F.env | xargs -d '\\n') && export \\$(grep -v '^#' .env | xargs -d '\\n') && \"\ntmux send-keys -t \"$PANE_API\" \"${ENV_CMD}uv run uvicorn app:main\" Enter\n```\n\n#### Health Checks and Dependency Ordering\n\nWhen a service depends on another (e.g., API needs postgres), use a wait loop:\n\n```bash\n# Inline wait-for-port in the pane command\ntmux send-keys -t \"$PANE_API\" \\\n  \"until nc -z localhost 5432 2>\u002Fdev\u002Fnull; do echo 'Waiting for postgres...'; sleep 1; done && uv run uvicorn app:main --reload\" Enter\n```\n\nFor a reusable helper defined at the top of the script:\n\n```bash\nwait_for_port() {\n  local port=$1 name=${2:-\"port $1\"} retries=${3:-30}\n  echo \"Waiting for ${name}...\"\n  for i in $(seq 1 \"$retries\"); do\n    nc -z localhost \"$port\" 2>\u002Fdev\u002Fnull && echo \"${name} ready\" && return 0\n    sleep 1\n  done\n  echo \"Timed out waiting for ${name}\" >&2\n  return 1\n}\n```\n\nFor HTTP readiness gates run in the outer shell (recommended after launch):\n\n```bash\nwait_for_http() {\n  local url=\"$1\"\n  local label=\"$2\"\n  local max_wait=\"${3:-60}\"\n  local interval=2\n  local elapsed=0\n\n  echo \"Waiting for ${label} (${url})...\"\n  while [ \"$elapsed\" -lt \"$max_wait\" ]; do\n    if curl -sf \"$url\" >\u002Fdev\u002Fnull 2>&1; then\n      echo \"${label} ready (${elapsed}s)\"\n      return 0\n    fi\n    sleep \"$interval\"\n    elapsed=$((elapsed + interval))\n  done\n  echo \"Warning: ${label} not ready within ${max_wait}s\" >&2\n  return 1\n}\n```\n\nThen in the pane:\n\n```bash\ntmux send-keys -t \"$PANE_API\" \\\n  \"source dev.sh.helpers 2>\u002Fdev\u002Fnull; wait_for_port 5432 postgres && uv run uvicorn app:main\" Enter\n```\n\nOr define the function inline and send it:\n\n```bash\ntmux send-keys -t \"$PANE_API\" \\\n  'until nc -z localhost 5432; do sleep 1; done && npm start' Enter\n```\n\n#### Common Service Patterns\n\n| Stack | Typical command |\n|---|---|\n| Docker infra | `docker compose up -d postgres redis` (run once in first pane, then start app) |\n| Python (uv) | `uv sync --dev && uv run uvicorn app:main --reload` |\n| Python (pip) | `pip install -e '.[dev]' && python -m app` |\n| Node (npm) | `npm install && npm run dev` |\n| Node (pnpm) | `pnpm install && pnpm dev` |\n| Go | `go run .\u002Fcmd\u002Fserver` |\n| Rust | `cargo watch -x run` |\n| Ruby\u002FRails | `bundle install && bin\u002Frails server` |\n| Elixir\u002FPhoenix | `mix deps.get && mix phx.server` |\n| Next.js | `npm install && npm run dev -- --port 3000` |\n| Vite | `npm install && npm run dev -- --host 0.0.0.0` |\n\n### Phase 4 — Verify\n\nBefore delivering the script, verify:\n\n- [ ] `set -euo pipefail` is present\n- [ ] Header comment includes ASCII layout diagram\n- [ ] All pane references use captured `$PANE_*` variables, never indices\n- [ ] `tmux kill-window` teardown precedes window creation (idempotent)\n- [ ] Both `$TMUX` \u002F non-`$TMUX` paths are handled\n- [ ] Script supports layered startup (preflight, launch, readiness)\n- [ ] Services with dependencies have a wait\u002Fhealth-check\n- [ ] HTTP readiness checks exist for critical endpoints where applicable\n- [ ] Working directories (`-c` flag) are correct for each pane\n- [ ] Layout command matches pane count\n- [ ] Logs are written to `logs\u002F\u003CYYYYmmdd_HHMMSS>\u002F...` and `logs\u002Flatest` points to that run\n- [ ] `tmux pipe-pane -o` is used for each pane log sink\n- [ ] Logs are clean (no ANSI escape sequences), e.g. `rg -nP \"\\x1b\" logs\u002Flatest\u002F**\u002F*.log` returns nothing\n- [ ] Script is `chmod +x`-able (shebang present)\n- [ ] Max 4 panes per window; overflow uses additional named windows\n- [ ] If using a path prefix, frontend base\u002Frouter\u002FAPI\u002Fproxy\u002Fhealth paths are coherent end-to-end\n- [ ] If using tailscale serve, script checks status first and verifies mapping after apply\n- [ ] Script includes compatibility fallback for tailscale CLI argument variants when needed\n- [ ] Script prints local URLs and (if configured) the remote\u002Ftailnet URL\n- [ ] A short post-split delay exists before `tmux send-keys` to avoid dropped keystrokes on fast reruns\n\n## Support Files\n\n- [`assets\u002Fdev.sh.template`](assets\u002Fdev.sh.template) — Default skeleton script\n  with all placeholders. Copy and fill in.\n- [`assets\u002Fdev.three-window.sh.template`](assets\u002Fdev.three-window.sh.template) —\n  Variant for a three-window layout.\n- [`assets\u002Fdev.multi-window.sh.template`](assets\u002Fdev.multi-window.sh.template) —\n  Variant for larger stacks needing one window per service group.\n- [`references\u002Fpatterns.md`](references\u002Fpatterns.md) — Exact tmux layout and\n  proxy patterns; load when filling in non-trivial splits or remote access.\n- [`scripts\u002Fvalidate_dev_bootstrap.py`](scripts\u002Fvalidate_dev_bootstrap.py) —\n  Run against a generated dev.sh before delivering it.\n","# Dev Bootstrap Application Script\n\n## Overview\n\nGenerate an idempotent bash script that launches every service in a project's full stack inside named tmux window(s), with up to 4 panes per window. The script handles session detection, window teardown\u002Frecreation, dependency ordering, health checks, per-run log capture, and optional reverse-proxy path-prefix bootstrapping (for tailscale serve, cloudflared, etc.).\n\nA ready-made template is bundled at `assets\u002Fdev.sh.template`.\n\n## When to Use\n\n- A user asks to \"write a dev script\", \"bootstrap the app in tmux\", or \"create a dev.sh\"\n- A user wants to launch multiple services (API, frontend, workers, databases) in one command\n- A user has an existing dev script and wants it rewritten following best practices\n\n## Workflow\n\n### Phase 1 — Research the Project\n\nBefore writing any code, discover what services the project needs. Read the following files (when present) to build a service inventory:\n\n| File | What to look for |\n|---|---|\n| `docker-compose.yml` \u002F `compose.yaml` | Infrastructure services (postgres, redis, rabbitmq, etc.) |\n| `package.json` | `scripts.dev`, `scripts.start`, framework (Next.js, Vite, Remix, etc.) |\n| `Makefile` \u002F `Justfile` | Existing `dev` \u002F `run` \u002F `serve` targets |\n| `Procfile` \u002F `Procfile.dev` | Named processes and their commands |\n| `pyproject.toml` \u002F `Pipfile` | Python entry points, uvicorn\u002Fgunicorn commands |\n| `Cargo.toml` \u002F `go.mod` | Build-and-run patterns |\n| `.env` \u002F `.env.example` | Environment variables needed at boot |\n| `turbo.json` \u002F `pnpm-workspace.yaml` | Monorepo workspace structure |\n| `README.md` | \"Getting Started\" \u002F \"Development\" sections |\n| Frontend router \u002F API client files | Whether routes and API calls are base-path aware |\n| Vite\u002FNext\u002Fwebpack dev config | Base path and dev proxy rewrite behavior |\n\nProduce a **service inventory** — an ordered list of:\n\n```\n1. Service name — command — working directory — depends on (if any)\n```\n\nExample:\n\n```\n1. postgres    — docker compose up -d postgres  — .          — (none)\n2. redis       — docker compose up -d redis     — .          — (none)\n3. api         — uv run uvicorn app:main        — .          — postgres, redis\n4. frontend    — npm run dev                    — .\u002Ffrontend — api\n```\n\n### Phase 2 — Design the Layout\n\n#### Pane Limit\n\nMaximum **4 panes per tmux window**. Beyond 4, panes become unreadably small.\n\n#### Window Count Decision\n\n| Services | Windows | Rationale |\n|---|---|---|\n| 1-4 | 1 window | Everything fits |\n| 5-8 | 2 windows | Group by concern (infra vs app, backend vs frontend) |\n| 9+ | 3 windows | Rare — consider if some services should stay in docker |\n\n#### Layout Selection\n\nPick the tmux preset layout that best matches the pane count:\n\n| Panes | Recommended layout | Visual |\n|---|---|---|\n| 2 | `even-horizontal` | `[A \\| B]` |\n| 2 | `even-vertical` | `[A \u002F B]` (stacked) |\n| 3 | `main-vertical` | `[A \\| B\u002FC]` (main left, two right) |\n| 3 | `main-horizontal` | `[A \u002F B\\|C]` (main top, two bottom) |\n| 4 | `tiled` | `[A\\|B \u002F C\\|D]` (2x2 grid) |\n\n#### Grouping Heuristic\n\nWhen splitting across multiple windows, group by concern:\n\n- **Window 1 (\"infra\")**: databases, caches, message brokers, docker services\n- **Window 2 (\"app\")**: API server, background workers, task queues\n- **Window 3 (\"frontend\")**: dev server, storybook, docs site\n\n### Phase 3 — Write the Script\n\nStart from `assets\u002Fdev.sh.template` and fill in the placeholders. Follow these mandatory patterns:\n\n#### Script Structure\n\n```\n1. Shebang + header comment with layout diagram\n2. set -euo pipefail\n3. Parse script args (for optional checks like --skip-tailscale-check)\n4. PROJECT_DIR and WINDOW constants\n5. Optional Layer 0 preflight (tailscale\u002Fdependencies\u002Fetc.)\n6. tmux prerequisite check\n7. Session detection (inside tmux vs new session)\n8. Kill existing window (idempotency)\n9. Create window + split panes (capture pane IDs)\n10. Small post-split delay before send-keys\n11. Initialize logs directory (timestamped run dir + latest symlink)\n12. Register pane log piping before launching commands\n13. Load environment variables\n14. Layer 1 launch services (send-keys to each pane)\n15. Layer 2 readiness gates (health endpoints\u002Fports)\n16. Print operator URLs (local + remote when available)\n17. Apply layout + set focus\n18. Attach if started detached\n```\n\n#### Mandatory Rules\n\n- **Pane IDs, never indices.** Always capture pane IDs with `-P -F '#{pane_id}'` and reference them by variable. Never use `tmux select-pane -t 0`.\n- **Idempotent.** `tmux kill-window -t \"${SESSION}:${WINDOW}\" 2>\u002Fdev\u002Fnull || true` before recreating.\n- **Session-aware.** Detect `$TMUX` to decide whether to create a session or reuse the current one.\n- **Header comment.** Every script must start with an ASCII layout diagram showing what runs where.\n- **Per-run logs + latest link.** Create logs under `logs\u002FYYYYmmdd_HHMMSS\u002F` and refresh `logs\u002Flatest -> logs\u002F\u003Crun_id>`.\n- **Pipe with `-o`.** Use `tmux pipe-pane -o` so re-runs do not stack duplicate pipe commands.\n- **Layered startup.** Prefer explicit layers (preflight -> launch -> readiness).\n- **User-facing URLs.** Always print local frontend URL and API base URL; print remote URL if a reverse proxy is configured.\n- **No prefix-only proxying.** If a path prefix is introduced (for example `\u002Fapp`), all app layers must agree on it (frontend base path, API path, router path parsing, and dev proxy rewrites).\n\n#### Reverse Proxy Prefix Coherency (Mandatory when using path prefixes)\n\nIf your script configures a reverse-proxy path prefix (for example `tailscale serve --set-path \u002Fmyapp`), ensure all of the following are aligned:\n\n1. Frontend dev server base path (`--base`, framework equivalent, or env setting).\n2. Frontend router path parsing\u002Fnavigation (strip\u002Fadd base path).\n3. API client prefix generation (`BASE_URL`-aware, not hardcoded root-only paths).\n4. Health\u002Freadiness fetch paths (for example `\u002Fready` -> `\u002Fmyapp\u002Fready` when prefixed).\n5. Dev proxy routes and rewrites (strip prefix before forwarding upstream).\n6. PWA scope\u002Fstart_url\u002Fassets if PWA is enabled.\n\nAnti-pattern to avoid: adding reverse-proxy path mapping alone while leaving client\u002Frouter\u002FAPI paths hardcoded to root.\n\n#### Tailscale Serve Preflight (Optional but Recommended)\n\nWhen bootstrapping HTTPS access via tailscale:\n\n1. Validate CLI exists (`command -v tailscale`).\n2. Validate authenticated state (`tailscale status --json`, reject `NeedsLogin`\u002F`Stopped` states).\n3. Inspect existing config first (`tailscale serve status --json`).\n4. Only apply missing mapping(s), then re-read status to verify mapping exists.\n5. Support CLI compatibility fallback (new vs legacy `tailscale serve` syntax).\n6. Emit actionable recovery instructions (manual command, `tailscale up`, permission hint such as `sudo tailscale set --operator=$USER` when relevant).\n7. Provide a skip flag (`--skip-tailscale-check`) for local-only workflows.\n\n#### Stdout\u002FStderr Logging (Mandatory)\n\nDirect `tmux pipe-pane ... \"cat >> file\"` captures interactive shell control sequences and pollutes logs. Use sanitized piping plus unbuffered writes.\n\n```bash\nLOGS_ROOT=\"${PROJECT_DIR}\u002Flogs\"\nLOGS_RUN_ID=\"$(date +%Y%m%d_%H%M%S)\"\nLOGS_RUN_DIR=\"${LOGS_ROOT}\u002F${LOGS_RUN_ID}\"\nLOGS_LATEST_LINK=\"${LOGS_ROOT}\u002Flatest\"\n\nmkdir -p \\\n  \"${LOGS_RUN_DIR}\u002Fbackend\" \\\n  \"${LOGS_RUN_DIR}\u002Fworkers\" \\\n  \"${LOGS_RUN_DIR}\u002Ffrontend\"\nrm -rf \"${LOGS_LATEST_LINK}\"\nln -s \"${LOGS_RUN_DIR}\" \"${LOGS_LATEST_LINK}\"\necho \"Logs for this run: ${LOGS_RUN_DIR}\"\n```\n\n```bash\npipe_pane_to_log() {\n  local pane_id=\"$1\"\n  local log_file=\"$2\"\n\n  tmux pipe-pane -o -t \"$pane_id\" \\\n    \"perl -pe 'BEGIN { \\$| = 1 } s\u002F\\\\e\\\\[[0-?]*[ -\\\\\u002F]*[@-~]\u002F\u002Fg; s\u002F\\\\e\\\\][^\\\\a]*(?:\\\\a|\\\\e\\\\\\\\)\u002F\u002Fg; s\u002F\\\\r\u002F\u002Fg; s\u002F[\\\\x00-\\\\x08\\\\x0B\\\\x0C\\\\x0E-\\\\x1F\\\\x7F]\u002F\u002Fg' >> '${log_file}'\"\n}\n```\n\n```bash\npipe_pane_to_log \"$PANE_API\" \"${LOGS_RUN_DIR}\u002Fbackend\u002Fapi.log\"\npipe_pane_to_log \"$PANE_WORKER\" \"${LOGS_RUN_DIR}\u002Fworkers\u002Fworker.log\"\npipe_pane_to_log \"$PANE_WEB\" \"${LOGS_RUN_DIR}\u002Ffrontend\u002Fweb.log\"\n```\n\nRequirements:\n- Include `BEGIN { $| = 1 }` in the sanitizer so logs are written incrementally (not buffered until process exit\u002Fbuffer fill).\n- Strip CSI + OSC + control characters before writing logs so `logs\u002Flatest\u002F**\u002F*.log` remains plain-text and grep-friendly.\n\n#### Pane Creation Patterns\n\nTwo panes (horizontal split):\n```bash\nPANE_LEFT=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_RIGHT=$(tmux split-window -t \"$PANE_LEFT\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n```\n\nThree panes (main-vertical — large left, two stacked right):\n```bash\nPANE_MAIN=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_TOP_R=$(tmux split-window -t \"$PANE_MAIN\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_BOT_R=$(tmux split-window -t \"$PANE_TOP_R\" -v -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n```\n\nFour panes (2x2 tiled):\n```bash\nPANE_TL=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_TR=$(tmux split-window -t \"$PANE_TL\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_BL=$(tmux split-window -t \"$PANE_TL\" -v -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_BR=$(tmux split-window -t \"$PANE_TR\" -v -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n```\n\n#### Multiple Windows\n\nWhen services overflow a single window, create additional windows:\n\n```bash\nWINDOW_1=\"myapp-infra\"\nWINDOW_2=\"myapp-app\"\n\n# Tear down both\ntmux kill-window -t \"${SESSION}:${WINDOW_1}\" 2>\u002Fdev\u002Fnull || true\ntmux kill-window -t \"${SESSION}:${WINDOW_2}\" 2>\u002Fdev\u002Fnull || true\n\n# Window 1: infrastructure\nPANE_DB=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW_1\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_CACHE=$(tmux split-window -t \"$PANE_DB\" -h -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\n\n# Window 2: application\nPANE_API=$(tmux new-window -t \"$SESSION\" -n \"$WINDOW_2\" -c \"$PROJECT_DIR\" -P -F '#{pane_id}')\nPANE_WEB=$(tmux split-window -t \"$PANE_API\" -h -c \"${PROJECT_DIR}\u002Ffrontend\" -P -F '#{pane_id}')\n```\n\n#### Environment Loading\n\n```bash\n# Single .env file\nexport $(grep -v '^#' \"$PROJECT_DIR\u002F.env\" | xargs -d '\\n')\n\n# Multiple env files (e.g., secrets + local overrides)\nENV_CMD=\"export \\$(grep -v '^#' \u002Fsecrets\u002F.env | xargs -d '\\n') && export \\$(grep -v '^#' .env | xargs -d '\\n') && \"\ntmux send-keys -t \"$PANE_API\" \"${ENV_CMD}uv run uvicorn app:main\" Enter\n```\n\n#### Health Checks and Dependency Ordering\n\nWhen a service depends on another (e.g., API needs postgres), use a wait loop:\n\n```bash\n# Inline wait-for-port in the pane command\ntmux send-keys -t \"$PANE_API\" \\\n  \"until nc -z localhost 5432 2>\u002Fdev\u002Fnull; do echo 'Waiting for postgres...'; sleep 1; done && uv run uvicorn app:main --reload\" Enter\n```\n\nFor a reusable helper defined at the top of the script:\n\n```bash\nwait_for_port() {\n  local port=$1 name=${2:-\"port $1\"} retries=${3:-30}\n  echo \"Waiting for ${name}...\"\n  for i in $(seq 1 \"$retries\"); do\n    nc -z localhost \"$port\" 2>\u002Fdev\u002Fnull && echo \"${name} ready\" && return 0\n    sleep 1\n  done\n  echo \"Timed out waiting for ${name}\" >&2\n  return 1\n}\n```\n\nFor HTTP readiness gates run in the outer shell (recommended after launch):\n\n```bash\nwait_for_http() {\n  local url=\"$1\"\n  local label=\"$2\"\n  local max_wait=\"${3:-60}\"\n  local interval=2\n  local elapsed=0\n\n  echo \"Waiting for ${label} (${url})...\"\n  while [ \"$elapsed\" -lt \"$max_wait\" ]; do\n    if curl -sf \"$url\" >\u002Fdev\u002Fnull 2>&1; then\n      echo \"${label} ready (${elapsed}s)\"\n      return 0\n    fi\n    sleep \"$interval\"\n    elapsed=$((elapsed + interval))\n  done\n  echo \"Warning: ${label} not ready within ${max_wait}s\" >&2\n  return 1\n}\n```\n\nThen in the pane:\n\n```bash\ntmux send-keys -t \"$PANE_API\" \\\n  \"source dev.sh.helpers 2>\u002Fdev\u002Fnull; wait_for_port 5432 postgres && uv run uvicorn app:main\" Enter\n```\n\nOr define the function inline and send it:\n\n```bash\ntmux send-keys -t \"$PANE_API\" \\\n  'until nc -z localhost 5432; do sleep 1; done && npm start' Enter\n```\n\n#### Common Service Patterns\n\n| Stack | Typical command |\n|---|---|\n| Docker infra | `docker compose up -d postgres redis` (run once in first pane, then start app) |\n| Python (uv) | `uv sync --dev && uv run uvicorn app:main --reload` |\n| Python (pip) | `pip install -e '.[dev]' && python -m app` |\n| Node (npm) | `npm install && npm run dev` |\n| Node (pnpm) | `pnpm install && pnpm dev` |\n| Go | `go run .\u002Fcmd\u002Fserver` |\n| Rust | `cargo watch -x run` |\n| Ruby\u002FRails | `bundle install && bin\u002Frails server` |\n| Elixir\u002FPhoenix | `mix deps.get && mix phx.server` |\n| Next.js | `npm install && npm run dev -- --port 3000` |\n| Vite | `npm install && npm run dev -- --host 0.0.0.0` |\n\n### Phase 4 — Verify\n\nBefore delivering the script, verify:\n\n- [ ] `set -euo pipefail` is present\n- [ ] Header comment includes ASCII layout diagram\n- [ ] All pane references use captured `$PANE_*` variables, never indices\n- [ ] `tmux kill-window` teardown precedes window creation (idempotent)\n- [ ] Both `$TMUX` \u002F non-`$TMUX` paths are handled\n- [ ] Script supports layered startup (preflight, launch, readiness)\n- [ ] Services with dependencies have a wait\u002Fhealth-check\n- [ ] HTTP readiness checks exist for critical endpoints where applicable\n- [ ] Working directories (`-c` flag) are correct for each pane\n- [ ] Layout command matches pane count\n- [ ] Logs are written to `logs\u002F\u003CYYYYmmdd_HHMMSS>\u002F...` and `logs\u002Flatest` points to that run\n- [ ] `tmux pipe-pane -o` is used for each pane log sink\n- [ ] Logs are clean (no ANSI escape sequences), e.g. `rg -nP \"\\x1b\" logs\u002Flatest\u002F**\u002F*.log` returns nothing\n- [ ] Script is `chmod +x`-able (shebang present)\n- [ ] Max 4 panes per window; overflow uses additional named windows\n- [ ] If using a path prefix, frontend base\u002Frouter\u002FAPI\u002Fproxy\u002Fhealth paths are coherent end-to-end\n- [ ] If using tailscale serve, script checks status first and verifies mapping after apply\n- [ ] Script includes compatibility fallback for tailscale CLI argument variants when needed\n- [ ] Script prints local URLs and (if configured) the remote\u002Ftailnet URL\n- [ ] A short post-split delay exists before `tmux send-keys` to avoid dropped keystrokes on fast reruns\n\n## Support Files\n\n- [`assets\u002Fdev.sh.template`](assets\u002Fdev.sh.template) — Default skeleton script\n  with all placeholders. Copy and fill in.\n- [`assets\u002Fdev.three-window.sh.template`](assets\u002Fdev.three-window.sh.template) —\n  Variant for a three-window layout.\n- [`assets\u002Fdev.multi-window.sh.template`](assets\u002Fdev.multi-window.sh.template) —\n  Variant for larger stacks needing one window per service group.\n- [`references\u002Fpatterns.md`](references\u002Fpatterns.md) — Exact tmux layout and\n  proxy patterns; load when filling in non-trivial splits or remote access.\n- [`scripts\u002Fvalidate_dev_bootstrap.py`](scripts\u002Fvalidate_dev_bootstrap.py) —\n  Run against a generated dev.sh before delivering it.\n",{"name":5,"metadata":48,"description":7},{"owner":49,"status":32,"authors":50,"last_reviewed":51},"tze",[49],"2026-06-12","main","c907d6f0bf96bd61b936e8972e0f1c66ebb8148c","skills\u002Farchive\u002Fdev-bootstrap-application-script","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap","https:\u002F\u002Fgithub.com\u002Ftzeusy-org","2026-11-10 23:17:25",{"source":8,"skillName":5,"commands":59,"prompt":69,"zipAvailable":70},[60,63,66],{"tool":61,"command":62},"npx","npx skills add tzeusy-org\u002Fai-bootstrap --skill dev-bootstrap-application-script",{"tool":64,"command":65},"bunx","bunx skills add tzeusy-org\u002Fai-bootstrap --skill dev-bootstrap-application-script",{"tool":67,"command":68},"pnpm","pnpm dlx skills add tzeusy-org\u002Fai-bootstrap --skill dev-bootstrap-application-script","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002FSKILL.md",true,[72,78,82,86,92,98,102,106,110,114,120,124,128,132,136,140,144,148,152,156,160,164,168,172],{"path":73,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":76,"sourceHtmlUrl":77},"assets\u002Fdev.multi-window.sh.template","ASSET","资产文件",11393,"https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002Fassets\u002Fdev.multi-window.sh.template",{"path":79,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":80,"sourceHtmlUrl":81},"assets\u002Fdev.sh.template",12026,"https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002Fassets\u002Fdev.sh.template",{"path":83,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":84,"sourceHtmlUrl":85},"assets\u002Fdev.three-window.sh.template",12112,"https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002Fassets\u002Fdev.three-window.sh.template",{"path":87,"resourceType":88,"resourceTypeDesc":89,"sizeBytes":90,"sourceHtmlUrl":91},"customize.toml","OTHER","其他",1614,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fcustomize.toml",{"path":93,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":96,"sourceHtmlUrl":97},"data\u002Fgdd-purpose.md","REFERENCE","参考文档",8922,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fdata\u002Fgdd-purpose.md",{"path":99,"resourceType":74,"resourceTypeDesc":75,"sizeBytes":100,"sourceHtmlUrl":101},"data\u002Fgenre-complexity.csv",8025,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fdata\u002Fgenre-complexity.csv",{"path":103,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":104,"sourceHtmlUrl":105},"evals\u002Fevals.json",2413,"https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002Fevals\u002Fevals.json",{"path":107,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":108,"sourceHtmlUrl":109},"evals\u002Ftrigger-queries.json",842,"https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002Fevals\u002Ftrigger-queries.json",{"path":111,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":112,"sourceHtmlUrl":113},"references\u002Fpatterns.md",4267,"https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002Freferences\u002Fpatterns.md",{"path":115,"resourceType":116,"resourceTypeDesc":117,"sizeBytes":118,"sourceHtmlUrl":119},"scripts\u002Fvalidate_dev_bootstrap.py","SCRIPT","脚本",6994,"https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Farchive\u002Fdev-bootstrap-application-script\u002Fscripts\u002Fvalidate_dev_bootstrap.py",{"path":121,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":122,"sourceHtmlUrl":123},"steps-v\u002Fstep-v-01-discovery.md",7714,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-01-discovery.md",{"path":125,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":126,"sourceHtmlUrl":127},"steps-v\u002Fstep-v-02-format-detection.md",7015,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-02-format-detection.md",{"path":129,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":130,"sourceHtmlUrl":131},"steps-v\u002Fstep-v-02b-parity-check.md",7156,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-02b-parity-check.md",{"path":133,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":134,"sourceHtmlUrl":135},"steps-v\u002Fstep-v-03-density-validation.md",7348,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-03-density-validation.md",{"path":137,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":138,"sourceHtmlUrl":139},"steps-v\u002Fstep-v-04-brief-coverage-validation.md",8549,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-04-brief-coverage-validation.md",{"path":141,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":142,"sourceHtmlUrl":143},"steps-v\u002Fstep-v-05-measurability-validation.md",9028,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-05-measurability-validation.md",{"path":145,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":146,"sourceHtmlUrl":147},"steps-v\u002Fstep-v-06-traceability-validation.md",8529,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-06-traceability-validation.md",{"path":149,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":150,"sourceHtmlUrl":151},"steps-v\u002Fstep-v-07-implementation-leakage-validation.md",8960,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-07-implementation-leakage-validation.md",{"path":153,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":154,"sourceHtmlUrl":155},"steps-v\u002Fstep-v-08-genre-compliance-validation.md",9500,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-08-genre-compliance-validation.md",{"path":157,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":158,"sourceHtmlUrl":159},"steps-v\u002Fstep-v-09-game-type-validation.md",10861,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-09-game-type-validation.md",{"path":161,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":162,"sourceHtmlUrl":163},"steps-v\u002Fstep-v-10-smart-validation.md",7679,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-10-smart-validation.md",{"path":165,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":166,"sourceHtmlUrl":167},"steps-v\u002Fstep-v-11-holistic-quality-validation.md",9263,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-11-holistic-quality-validation.md",{"path":169,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":170,"sourceHtmlUrl":171},"steps-v\u002Fstep-v-12-completeness-validation.md",10445,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-12-completeness-validation.md",{"path":173,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":174,"sourceHtmlUrl":175},"steps-v\u002Fstep-v-13-report-complete.md",9006,"https:\u002F\u002Fgithub.com\u002Ftonygomes-wq\u002Fevo\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-validate-gdd\u002Fsteps-v\u002Fstep-v-13-report-complete.md",[177,201,226,241,260,271],{"skillNo":178,"name":179,"nameZh":6,"description":180,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":181,"categories":182,"keywords":183,"publishedAt":43},"01M6DAZD21TWH2ET70V9FF75CQ","user-run","Use when a step needs privileges this session lacks (docker, sudo, another user's checkout or secrets, host access) and the owner must run it as tze. Writes a reviewable \u002Fhome\u002Forca\u002F.tmp\u002F\u003Cslug>\u002Frun.sh that impersonates tze (USER_TO_IMPERSONATE overrides), tees timestamped logs plus latest.log and collects artifacts there; Claude presents it with a risk and time brief, then continues from the logs. Triggers: \"I'll run it for you\", \"permission denied on docker.sock\", \"needs sudo\", \"sudo: a password is required\", \"run as tze\", \"\u002Fuser-run\".","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Fpersonal\u002Fuser-run\u002FSKILL.md",[],[184,185,39,186,38,187,188,189,190,191,32,192,193,194,195,196,197,198,199,200],"user run","user","docker","use","host","as","triggers","permission","time","log","artifacts","session","password","access","secrets","risk","brief",{"skillNo":202,"name":203,"nameZh":6,"description":204,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":205,"categories":206,"keywords":215,"publishedAt":43},"01M6DAZAHTCBAD2WF0GAHWPST8","requesting-code-review","Use when completing tasks, implementing major features, or before merging to verify work meets requirements","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Fpersonal\u002Fth-workflow\u002Fsubskills\u002Frequesting-code-review\u002FSKILL.md",[207,210],{"categoryNo":208,"categoryName":209,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":211,"categoryName":212,"taxonomyType":213,"taxonomyTypeDesc":214},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[216,217,218,219,220,221,32,222,223,187,224,225],"requesting code review","code","review","code review","work","requirements","upstream","superpowers","verify","tasks",{"skillNo":227,"name":228,"nameZh":6,"description":229,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":230,"categories":231,"keywords":234,"publishedAt":43},"01M6DAZ7CJ82D81XZB2YHVVY48","receiving-code-review","Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Fpersonal\u002Fth-workflow\u002Fsubskills\u002Freceiving-code-review\u002FSKILL.md",[232,233],{"categoryNo":208,"categoryName":209,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":211,"categoryName":212,"taxonomyType":213,"taxonomyTypeDesc":214},[235,217,218,219,32,222,236,223,187,237,238,239,240],"receiving code review","implementation","code review feedback","technical","feedback","verification",{"skillNo":242,"name":243,"nameZh":6,"description":244,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":245,"categories":246,"keywords":247,"publishedAt":43},"01M6DAZ4ER76ADXJ9KRFP7V3Q9","finishing-a-development-branch","Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Fpersonal\u002Fth-workflow\u002Fsubskills\u002Ffinishing-a-development-branch\u002FSKILL.md",[],[248,249,250,251,187,252,220,253,254,255,223,256,257,258,32,222,259,236],"branch","development","finishing a development branch","integrate","decide","how","cleanup","pr","merge","tests","structured","options",{"skillNo":261,"name":262,"nameZh":6,"description":263,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":264,"categories":265,"keywords":266,"publishedAt":43},"01M6DAYZFWWW2YPKP89QNQR96H","executing-plans","Use when you have a written implementation plan to execute in a separate session with review checkpoints","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Fpersonal\u002Fth-workflow\u002Fsubskills\u002Fexecuting-plans\u002FSKILL.md",[],[267,268,269,218,270,32,222,236,223,187,195],"plans","executing plans","plan","execute",{"skillNo":272,"name":273,"nameZh":6,"description":274,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":275,"categories":276,"keywords":277,"publishedAt":43},"01M6DAYWM2YQHYCK7C35K1D29J","dispatching-parallel-agents","Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies","https:\u002F\u002Fgithub.com\u002Ftzeusy-org\u002Fai-bootstrap\u002Fblob\u002Fmain\u002Fskills\u002Fpersonal\u002Fth-workflow\u002Fsubskills\u002Fdispatching-parallel-agents\u002FSKILL.md",[],[278,279,280,187,223,222,281,32,282,225,283],"parallel agents","parallel","dispatching parallel agents","state","dependencies","shared"]