-
Notifications
You must be signed in to change notification settings - Fork 1
Pipeline Design 6
shipwright doctor (scripts/sw-doctor.sh) is the setup validation command — it runs 13 sections checking prerequisites (tmux, jq, claude, node, git), configuration, permissions, and GitHub integration. The dashboard (dashboard/server.ts, a Bun WebSocket server on port 8767) is a core feature but has zero doctor coverage. Users hit confusing failures when Bun is missing, dashboard files aren't present (e.g., shallow clone), or port 8767 is already occupied by another process.
Constraints from the codebase:
- Bash 3.2 compatible — no associative arrays, no
readarray, no${var,,} -
set -euo pipefailwith ERR trap in all scripts - Doctor uses
check_pass/check_warn/check_failhelpers with PASS/WARN/FAIL counters -
$_DOCTOR_SCRIPT_DIRresolves the repo root via$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - The dashboard port is 8767 (confirmed in
dashboard/server.tsandscripts/sw-dashboard.sh), not 3000 as the issue title assumed -
SHIPWRIGHT_DASHBOARD_PORTenv var overrides the default port - Bun is an optional dependency (dashboard-only), so missing Bun should warn, not fail — matching how
ghis treated in Section 12
Add Section 14: Dashboard to sw-doctor.sh between the GitHub Integration section (Section 13, ending ~line 886) and the Summary block (~line 888). Three subsections with warn-level severity:
-
command -v bunto detect presence - On success:
check_pass "bun $(bun --version)" - On failure:
check_warn "bun not found — required for dashboard (curl -fsSL https://bun.sh/install | bash)" - Warn-level because Bun is only needed for the dashboard feature, not core pipeline functionality
- Resolve repo root as
$_DOCTOR_SCRIPT_DIR/.. - Check
dashboard/server.tsexists (-ftest) - Check
dashboard/public/exists (-dtest) - On missing:
check_warnwith path shown — handles shallow clones or partial installs - On present: single
check_pass "dashboard files present"
- Read port from
${SHIPWRIGHT_DASHBOARD_PORT:-8767} - If
lsofis not available (! command -v lsof):check_pass "port $port check skipped (lsof not available)"— graceful degradation on minimal systems - If
lsof -ti :"$port"exits non-zero (no listener):check_pass "port $port available" - If port is in use: get PID from
lsof, get process name viaps -p "$pid" -o comm=- If process name contains "bun":
check_pass "port $port in use by dashboard (pid $pid)"— our dashboard is already running, that's fine - Otherwise:
check_warn "port $port in use by $proc_name (pid $pid) — dashboard may fail to start"
- If process name contains "bun":
- Follows the established test harness pattern from
sw-tmux-test.shexactly: same color constants, PASS/FAIL/TOTAL counters, FAILURES array, ERR trap,run_testwrapper -
setup_env()creates sandboxed temp directory with mockscripts/,bin/,home/,dashboard/structure -
run_doctor()helper executessw-doctor.shwith sandboxedHOMEandPATHpointing to mock binaries - Mock binaries are simple shell scripts in
$TEMP_DIR/binthat echo expected output and exit with controlled codes - 7 tests covering all branches of the three new checks
- Append
&& bash scripts/sw-doctor-test.shtopackage.jsonscripts.testchain as test #23
-
Make Bun a hard requirement (
check_fail) — Pros: simpler logic, forces dashboard readiness. Cons: breaks doctor for users who don't use the dashboard; inconsistent with howgh(also optional) usescheck_warn. Rejected because doctor should validate the full setup without forcing optional features. -
Use
ssornetstatinstead oflsoffor port checking — Pros:ssis more modern on Linux. Cons: macOS doesn't shipss;netstatoutput format varies across platforms;lsofis present on macOS by default and common on Linux. Rejected becauselsofprovides the best cross-platform coverage for the primary macOS target, with graceful skip when unavailable. -
Check port by attempting a TCP connect (
/dev/tcpornc) — Pros: no dependency onlsof. Cons:/dev/tcprequires bash (not POSIX),ncflags differ across platforms, and neither tells us which process holds the port (losing the dashboard-vs-other distinction). Rejected because process identification is a key UX differentiator. -
Embed dashboard checks into the existing Section 12 (Optional Tools) — Pros: fewer section headers, simpler diff. Cons: dashboard validation is a logical grouping of 3 related checks (runtime + files + port) that deserves its own section for clarity, matching how GitHub got its own Section 13. Rejected to maintain section-per-concern consistency.
-
Files to create:
scripts/sw-doctor-test.sh(new test suite, ~250 lines) -
Files to modify:
scripts/sw-doctor.sh(add ~50 lines for Section 14 before Summary),package.json(append test #23 to chain) -
Dependencies: None new. Uses
lsof(already present on macOS, gracefully skipped elsewhere) -
Risk areas:
-
lsofoutput parsing — PID extraction must handle multi-line output (multiple listeners); take only the first PID viahead -1 -
ps -p PID -o comm=— thecomm=(no header) format is POSIX but verify it works on macOS Bash 3.2 - Section numbering — inserting Section 14 before Summary must not break the existing section counter or summary totals (they use PASS/WARN/FAIL variables that accumulate, so insertion point is safe)
-
pipefailinteraction withlsof—lsofexits 1 when no matching port; must guard with|| trueto avoid pipeline abort
-
-
shipwright doctoroutput includes14. Dashboardsection with three subsections - With Bun installed: shows PASS with version string
- Without Bun: shows WARN with install instructions (not FAIL)
- With
dashboard/server.tsanddashboard/public/present: shows PASS - With either missing: shows WARN naming the missing path
- With port 8767 free: shows PASS
- With port 8767 held by a bun process: shows PASS identifying it as dashboard
- With port 8767 held by another process: shows WARN with process name and PID
- Without
lsofavailable: shows PASS with "skipped" note (not WARN or FAIL) -
SHIPWRIGHT_DASHBOARD_PORToverride is respected in port check - All 7 tests in
sw-doctor-test.shpass -
sw-doctor-test.shregistered as test #23 inpackage.json - Existing test suites pass without modification
- No Bash 3.2 incompatibilities (no associative arrays, no
readarray, no${var,,}) - All new code uses
set -euo pipefailwith ERR trap