-
Notifications
You must be signed in to change notification settings - Fork 1
Pipeline Plan 16
Seth Ford edited this page Feb 13, 2026
·
4 revisions
The .claude/ directory files keep requiring permission. Let me try the plan mode approach instead since the pipeline expects the plan in the state file.
The plan is complete. Here's the implementation plan for adding Linux systemd support for process supervision:
| File | Action | Purpose |
|---|---|---|
scripts/sw-launchd.sh |
Modify | Add OS detection, systemd unit generation, cross-platform install/uninstall/status |
scripts/sw-launchd-test.sh |
Create | New test suite (13 tests) covering both platforms |
package.json |
Modify | Register new test suite |
.github/workflows/test.yml |
Modify | Add launchd test step |
The script already sources lib/compat.sh which provides is_macos() and is_linux(). The approach:
-
Replace
check_macos()with platform dispatch — each command branches onis_macos/is_linux -
Extract macOS logic into
install_launchd(),uninstall_launchd(),status_launchd() -
Add parallel systemd functions —
install_systemd(),uninstall_systemd(),status_systemd()
-
User-level units (
~/.config/systemd/user/) — no root required, matching launchd's user-agent pattern -
KillSignal=SIGTERM— daemon already traps SIGTERM (trap 'touch "$SHUTDOWN_FLAG"' SIGINT SIGTERMat line 4330) -
TimeoutStopSec=35— daemon's graceful shutdown waits 30s; give 35s before SIGKILL -
StandardOutput=journal— routes logs to journald (log rotation for free viajournalctl --user -u shipwright-daemon) -
Restart=on-failure— auto-restart on crash, not clean exit -
loginctl enable-linger— services survive logout on headless servers
| Service | Unit Name | ExecStart | Stop Timeout |
|---|---|---|---|
| Daemon | shipwright-daemon.service |
sw daemon start |
35s |
| Dashboard | shipwright-dashboard.service |
bun run dashboard/server.ts |
10s |
| Connect | shipwright-connect.service |
sw connect start |
10s |
- Task 1: Refactor
sw-launchd.sh— extract macOS plist logic intoinstall_launchd(),uninstall_launchd(),status_launchd() - Task 2: Add platform dispatch —
cmd_install/cmd_uninstall/cmd_statusbranch onis_macos/is_linux - Task 3: Implement
install_systemd()— generate 3.serviceunit files with journald, SIGTERM, restart policy - Task 4: Implement
uninstall_systemd()— disable/stop services, remove unit files, daemon-reload - Task 5: Implement
status_systemd()— querysystemctl --user is-active, show journal entries - Task 6: Update help text and header for cross-platform support
- Task 7: Create
sw-launchd-test.sh— 13 tests with mocked systemctl/launchctl/loginctl - Task 8: Register test in
package.jsonandtest.yml - Task 9: Run full test suite and verify all 23 suites pass
-
13 unit tests with mocked binaries, controlling platform via
_COMPAT_UNAMEoverride - Tests verify: file generation, content validation (SIGTERM, journal, timeouts), conditional connect install, unsupported platform error, linger enablement
- Runs on both
macos-latestandubuntu-latestin existing CI matrix
-
shipwright launchd installdetects OS and generates appropriate service files - Three systemd units generated: daemon, dashboard, connect
-
shipwright launchd statusworks on both macOS and Linux - Graceful shutdown via SIGTERM with 35s timeout for daemon
- Log rotation via journald (Linux) / file-based (macOS)
- New test suite passes on Linux CI
- All 23 test suites pass, no Bash 3.2 violations