shipwright-cli 1.7.1 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/code-reviewer.md +90 -0
- package/.claude/agents/devops-engineer.md +142 -0
- package/.claude/agents/pipeline-agent.md +80 -0
- package/.claude/agents/shell-script-specialist.md +150 -0
- package/.claude/agents/test-specialist.md +196 -0
- package/.claude/hooks/post-tool-use.sh +45 -0
- package/.claude/hooks/pre-tool-use.sh +25 -0
- package/.claude/hooks/session-started.sh +37 -0
- package/README.md +212 -814
- package/claude-code/CLAUDE.md.shipwright +54 -0
- package/claude-code/hooks/notify-idle.sh +2 -2
- package/claude-code/hooks/session-start.sh +24 -0
- package/claude-code/hooks/task-completed.sh +6 -2
- package/claude-code/settings.json.template +12 -0
- package/dashboard/public/app.js +4422 -0
- package/dashboard/public/index.html +816 -0
- package/dashboard/public/styles.css +4755 -0
- package/dashboard/server.ts +4315 -0
- package/docs/KNOWN-ISSUES.md +18 -10
- package/docs/TIPS.md +38 -26
- package/docs/patterns/README.md +33 -23
- package/package.json +9 -5
- package/scripts/adapters/iterm2-adapter.sh +1 -1
- package/scripts/adapters/tmux-adapter.sh +52 -23
- package/scripts/adapters/wezterm-adapter.sh +26 -14
- package/scripts/lib/compat.sh +200 -0
- package/scripts/lib/helpers.sh +72 -0
- package/scripts/postinstall.mjs +72 -13
- package/scripts/{cct → sw} +118 -22
- package/scripts/sw-adversarial.sh +274 -0
- package/scripts/sw-architecture-enforcer.sh +330 -0
- package/scripts/sw-checkpoint.sh +468 -0
- package/scripts/sw-cleanup.sh +359 -0
- package/scripts/sw-connect.sh +619 -0
- package/scripts/{cct-cost.sh → sw-cost.sh} +368 -34
- package/scripts/sw-daemon.sh +5574 -0
- package/scripts/sw-dashboard.sh +477 -0
- package/scripts/sw-developer-simulation.sh +252 -0
- package/scripts/sw-docs.sh +635 -0
- package/scripts/sw-doctor.sh +907 -0
- package/scripts/{cct-fix.sh → sw-fix.sh} +10 -6
- package/scripts/{cct-fleet.sh → sw-fleet.sh} +498 -22
- package/scripts/sw-github-checks.sh +521 -0
- package/scripts/sw-github-deploy.sh +533 -0
- package/scripts/sw-github-graphql.sh +972 -0
- package/scripts/sw-heartbeat.sh +293 -0
- package/scripts/{cct-init.sh → sw-init.sh} +144 -11
- package/scripts/sw-intelligence.sh +1196 -0
- package/scripts/sw-jira.sh +643 -0
- package/scripts/sw-launchd.sh +364 -0
- package/scripts/sw-linear.sh +648 -0
- package/scripts/{cct-logs.sh → sw-logs.sh} +72 -2
- package/scripts/sw-loop.sh +2217 -0
- package/scripts/{cct-memory.sh → sw-memory.sh} +514 -36
- package/scripts/sw-patrol-meta.sh +417 -0
- package/scripts/sw-pipeline-composer.sh +455 -0
- package/scripts/sw-pipeline-vitals.sh +1096 -0
- package/scripts/sw-pipeline.sh +7593 -0
- package/scripts/sw-predictive.sh +820 -0
- package/scripts/{cct-prep.sh → sw-prep.sh} +339 -49
- package/scripts/{cct-ps.sh → sw-ps.sh} +9 -6
- package/scripts/{cct-reaper.sh → sw-reaper.sh} +10 -6
- package/scripts/sw-remote.sh +687 -0
- package/scripts/sw-self-optimize.sh +1048 -0
- package/scripts/sw-session.sh +541 -0
- package/scripts/sw-setup.sh +234 -0
- package/scripts/sw-status.sh +796 -0
- package/scripts/{cct-templates.sh → sw-templates.sh} +9 -4
- package/scripts/sw-tmux.sh +591 -0
- package/scripts/sw-tracker-jira.sh +277 -0
- package/scripts/sw-tracker-linear.sh +292 -0
- package/scripts/sw-tracker.sh +409 -0
- package/scripts/{cct-upgrade.sh → sw-upgrade.sh} +103 -46
- package/scripts/{cct-worktree.sh → sw-worktree.sh} +3 -0
- package/templates/pipelines/autonomous.json +35 -6
- package/templates/pipelines/cost-aware.json +21 -0
- package/templates/pipelines/deployed.json +40 -6
- package/templates/pipelines/enterprise.json +16 -2
- package/templates/pipelines/fast.json +19 -0
- package/templates/pipelines/full.json +28 -2
- package/templates/pipelines/hotfix.json +19 -0
- package/templates/pipelines/standard.json +31 -0
- package/tmux/{claude-teams-overlay.conf → shipwright-overlay.conf} +27 -9
- package/tmux/templates/accessibility.json +34 -0
- package/tmux/templates/api-design.json +35 -0
- package/tmux/templates/architecture.json +1 -0
- package/tmux/templates/bug-fix.json +9 -0
- package/tmux/templates/code-review.json +1 -0
- package/tmux/templates/compliance.json +36 -0
- package/tmux/templates/data-pipeline.json +36 -0
- package/tmux/templates/debt-paydown.json +34 -0
- package/tmux/templates/devops.json +1 -0
- package/tmux/templates/documentation.json +1 -0
- package/tmux/templates/exploration.json +1 -0
- package/tmux/templates/feature-dev.json +1 -0
- package/tmux/templates/full-stack.json +8 -0
- package/tmux/templates/i18n.json +34 -0
- package/tmux/templates/incident-response.json +36 -0
- package/tmux/templates/migration.json +1 -0
- package/tmux/templates/observability.json +35 -0
- package/tmux/templates/onboarding.json +33 -0
- package/tmux/templates/performance.json +35 -0
- package/tmux/templates/refactor.json +1 -0
- package/tmux/templates/release.json +35 -0
- package/tmux/templates/security-audit.json +8 -0
- package/tmux/templates/spike.json +34 -0
- package/tmux/templates/testing.json +1 -0
- package/tmux/tmux.conf +98 -9
- package/scripts/cct-cleanup.sh +0 -172
- package/scripts/cct-daemon.sh +0 -3189
- package/scripts/cct-doctor.sh +0 -414
- package/scripts/cct-loop.sh +0 -1332
- package/scripts/cct-pipeline.sh +0 -3844
- package/scripts/cct-session.sh +0 -284
- package/scripts/cct-status.sh +0 -169
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
# ║ shipwright launchd — Process supervision on macOS ║
|
|
4
|
+
# ║ Auto-start daemon + dashboard on boot via launchd ║
|
|
5
|
+
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
|
+
|
|
9
|
+
VERSION="1.10.0"
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
|
+
|
|
13
|
+
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
|
14
|
+
CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
|
|
15
|
+
PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
|
|
16
|
+
BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
|
|
17
|
+
GREEN='\033[38;2;74;222;128m' # success
|
|
18
|
+
YELLOW='\033[38;2;250;204;21m' # warning
|
|
19
|
+
RED='\033[38;2;248;113;113m' # error
|
|
20
|
+
DIM='\033[2m'
|
|
21
|
+
BOLD='\033[1m'
|
|
22
|
+
RESET='\033[0m'
|
|
23
|
+
|
|
24
|
+
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
25
|
+
# shellcheck source=lib/compat.sh
|
|
26
|
+
[[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
|
|
27
|
+
|
|
28
|
+
# ─── Output Helpers ─────────────────────────────────────────────────────────
|
|
29
|
+
info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
|
|
30
|
+
success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
|
|
31
|
+
warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
|
|
32
|
+
error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
|
|
33
|
+
|
|
34
|
+
# ─── Constants ──────────────────────────────────────────────────────────────
|
|
35
|
+
PLIST_DIR="$HOME/Library/LaunchAgents"
|
|
36
|
+
DAEMON_PLIST="$PLIST_DIR/com.shipwright.daemon.plist"
|
|
37
|
+
DASHBOARD_PLIST="$PLIST_DIR/com.shipwright.dashboard.plist"
|
|
38
|
+
CONNECT_PLIST="$PLIST_DIR/com.shipwright.connect.plist"
|
|
39
|
+
LOG_DIR="$HOME/.shipwright/logs"
|
|
40
|
+
TEAM_CONFIG="$HOME/.shipwright/team-config.json"
|
|
41
|
+
|
|
42
|
+
# ─── Check macOS ─────────────────────────────────────────────────────────────
|
|
43
|
+
check_macos() {
|
|
44
|
+
if [[ "$OSTYPE" != "darwin"* ]]; then
|
|
45
|
+
error "launchd is only available on macOS"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# ─── Help ───────────────────────────────────────────────────────────────────
|
|
51
|
+
show_help() {
|
|
52
|
+
echo ""
|
|
53
|
+
echo -e "${CYAN}${BOLD} Shipwright launchd${RESET} ${DIM}v${VERSION}${RESET}"
|
|
54
|
+
echo -e "${DIM} ════════════════════════════════════════════${RESET}"
|
|
55
|
+
echo ""
|
|
56
|
+
echo -e " ${BOLD}USAGE${RESET}"
|
|
57
|
+
echo -e " shipwright launchd <command>"
|
|
58
|
+
echo ""
|
|
59
|
+
echo -e " ${BOLD}COMMANDS${RESET}"
|
|
60
|
+
echo -e " ${CYAN}install${RESET} Install launchd agents for daemon and dashboard (auto-start on boot)"
|
|
61
|
+
echo -e " ${CYAN}uninstall${RESET} Remove launchd agents and stop services"
|
|
62
|
+
echo -e " ${CYAN}status${RESET} Check status of launchd services"
|
|
63
|
+
echo -e " ${CYAN}help${RESET} Show this help message"
|
|
64
|
+
echo ""
|
|
65
|
+
echo -e " ${BOLD}EXAMPLES${RESET}"
|
|
66
|
+
echo -e " ${DIM}shipwright launchd install${RESET} # Set up auto-start on boot"
|
|
67
|
+
echo -e " ${DIM}shipwright launchd status${RESET} # Check if services are running"
|
|
68
|
+
echo -e " ${DIM}shipwright launchd uninstall${RESET} # Remove auto-start"
|
|
69
|
+
echo ""
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# ─── Install Command ─────────────────────────────────────────────────────────
|
|
73
|
+
cmd_install() {
|
|
74
|
+
check_macos
|
|
75
|
+
|
|
76
|
+
info "Installing launchd agents..."
|
|
77
|
+
|
|
78
|
+
# Create directories
|
|
79
|
+
mkdir -p "$PLIST_DIR" "$LOG_DIR"
|
|
80
|
+
|
|
81
|
+
# Find the full path to the sw CLI
|
|
82
|
+
local sw_bin
|
|
83
|
+
if [[ -x "$SCRIPT_DIR/sw" ]]; then
|
|
84
|
+
sw_bin="$SCRIPT_DIR/sw"
|
|
85
|
+
else
|
|
86
|
+
# Try to find it via PATH
|
|
87
|
+
sw_bin=$(command -v sw 2>/dev/null || echo "")
|
|
88
|
+
if [[ -z "$sw_bin" ]]; then
|
|
89
|
+
error "Could not find 'sw' binary — make sure Shipwright is installed"
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Resolve symlinks in case sw is symlinked
|
|
95
|
+
sw_bin=$(cd "$(dirname "$sw_bin")" && pwd)/$(basename "$sw_bin")
|
|
96
|
+
|
|
97
|
+
# ─── Create Daemon Plist ───────────────────────────────────────────────────
|
|
98
|
+
cat > "$DAEMON_PLIST" <<EOF
|
|
99
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
100
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
101
|
+
<plist version="1.0">
|
|
102
|
+
<dict>
|
|
103
|
+
<key>Label</key>
|
|
104
|
+
<string>com.shipwright.daemon</string>
|
|
105
|
+
<key>ProgramArguments</key>
|
|
106
|
+
<array>
|
|
107
|
+
<string>${sw_bin}</string>
|
|
108
|
+
<string>daemon</string>
|
|
109
|
+
<string>start</string>
|
|
110
|
+
</array>
|
|
111
|
+
<key>WorkingDirectory</key>
|
|
112
|
+
<string>${REPO_DIR}</string>
|
|
113
|
+
<key>KeepAlive</key>
|
|
114
|
+
<true/>
|
|
115
|
+
<key>RunAtLoad</key>
|
|
116
|
+
<true/>
|
|
117
|
+
<key>StandardOutPath</key>
|
|
118
|
+
<string>${LOG_DIR}/daemon.stdout.log</string>
|
|
119
|
+
<key>StandardErrorPath</key>
|
|
120
|
+
<string>${LOG_DIR}/daemon.stderr.log</string>
|
|
121
|
+
<key>EnvironmentVariables</key>
|
|
122
|
+
<dict>
|
|
123
|
+
<key>PATH</key>
|
|
124
|
+
<string>/opt/homebrew/bin:\$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
125
|
+
<key>HOME</key>
|
|
126
|
+
<string>\$HOME</string>
|
|
127
|
+
</dict>
|
|
128
|
+
</dict>
|
|
129
|
+
</plist>
|
|
130
|
+
EOF
|
|
131
|
+
|
|
132
|
+
chmod 644 "$DAEMON_PLIST"
|
|
133
|
+
success "Created daemon plist: ${DAEMON_PLIST}"
|
|
134
|
+
|
|
135
|
+
# ─── Create Dashboard Plist ────────────────────────────────────────────────
|
|
136
|
+
# Get full path to bun and server.ts
|
|
137
|
+
local bun_bin
|
|
138
|
+
bun_bin=$(command -v bun 2>/dev/null || echo "bun")
|
|
139
|
+
|
|
140
|
+
local server_file="$REPO_DIR/dashboard/server.ts"
|
|
141
|
+
if [[ ! -f "$server_file" ]]; then
|
|
142
|
+
warn "server.ts not found at $server_file — dashboard plist will reference a missing file"
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
cat > "$DASHBOARD_PLIST" <<EOF
|
|
146
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
147
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
148
|
+
<plist version="1.0">
|
|
149
|
+
<dict>
|
|
150
|
+
<key>Label</key>
|
|
151
|
+
<string>com.shipwright.dashboard</string>
|
|
152
|
+
<key>ProgramArguments</key>
|
|
153
|
+
<array>
|
|
154
|
+
<string>${bun_bin}</string>
|
|
155
|
+
<string>run</string>
|
|
156
|
+
<string>${server_file}</string>
|
|
157
|
+
</array>
|
|
158
|
+
<key>WorkingDirectory</key>
|
|
159
|
+
<string>${REPO_DIR}/dashboard</string>
|
|
160
|
+
<key>KeepAlive</key>
|
|
161
|
+
<true/>
|
|
162
|
+
<key>RunAtLoad</key>
|
|
163
|
+
<true/>
|
|
164
|
+
<key>StandardOutPath</key>
|
|
165
|
+
<string>${LOG_DIR}/dashboard.stdout.log</string>
|
|
166
|
+
<key>StandardErrorPath</key>
|
|
167
|
+
<string>${LOG_DIR}/dashboard.stderr.log</string>
|
|
168
|
+
<key>EnvironmentVariables</key>
|
|
169
|
+
<dict>
|
|
170
|
+
<key>PATH</key>
|
|
171
|
+
<string>/opt/homebrew/bin:\$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
172
|
+
<key>HOME</key>
|
|
173
|
+
<string>\$HOME</string>
|
|
174
|
+
</dict>
|
|
175
|
+
</dict>
|
|
176
|
+
</plist>
|
|
177
|
+
EOF
|
|
178
|
+
|
|
179
|
+
chmod 644 "$DASHBOARD_PLIST"
|
|
180
|
+
success "Created dashboard plist: ${DASHBOARD_PLIST}"
|
|
181
|
+
|
|
182
|
+
# ─── Create Connect Plist (only if team-config.json exists) ────────────────
|
|
183
|
+
if [[ -f "$TEAM_CONFIG" ]]; then
|
|
184
|
+
cat > "$CONNECT_PLIST" <<EOF
|
|
185
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
186
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
187
|
+
<plist version="1.0">
|
|
188
|
+
<dict>
|
|
189
|
+
<key>Label</key>
|
|
190
|
+
<string>com.shipwright.connect</string>
|
|
191
|
+
<key>ProgramArguments</key>
|
|
192
|
+
<array>
|
|
193
|
+
<string>${sw_bin}</string>
|
|
194
|
+
<string>connect</string>
|
|
195
|
+
<string>start</string>
|
|
196
|
+
</array>
|
|
197
|
+
<key>WorkingDirectory</key>
|
|
198
|
+
<string>${REPO_DIR}</string>
|
|
199
|
+
<key>KeepAlive</key>
|
|
200
|
+
<true/>
|
|
201
|
+
<key>RunAtLoad</key>
|
|
202
|
+
<true/>
|
|
203
|
+
<key>StandardOutPath</key>
|
|
204
|
+
<string>${LOG_DIR}/connect.log</string>
|
|
205
|
+
<key>StandardErrorPath</key>
|
|
206
|
+
<string>${LOG_DIR}/connect.err</string>
|
|
207
|
+
<key>EnvironmentVariables</key>
|
|
208
|
+
<dict>
|
|
209
|
+
<key>PATH</key>
|
|
210
|
+
<string>/opt/homebrew/bin:\$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
211
|
+
<key>HOME</key>
|
|
212
|
+
<string>\$HOME</string>
|
|
213
|
+
</dict>
|
|
214
|
+
</dict>
|
|
215
|
+
</plist>
|
|
216
|
+
EOF
|
|
217
|
+
|
|
218
|
+
chmod 644 "$CONNECT_PLIST"
|
|
219
|
+
success "Created connect plist: ${CONNECT_PLIST}"
|
|
220
|
+
else
|
|
221
|
+
info "Skipping connect plist — ${TEAM_CONFIG} not found"
|
|
222
|
+
fi
|
|
223
|
+
|
|
224
|
+
# ─── Load Services ─────────────────────────────────────────────────────────
|
|
225
|
+
info "Loading launchd services..."
|
|
226
|
+
|
|
227
|
+
if launchctl load "$DAEMON_PLIST" 2>/dev/null; then
|
|
228
|
+
success "Loaded daemon service"
|
|
229
|
+
else
|
|
230
|
+
warn "Could not load daemon service — it may already be loaded"
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
if launchctl load "$DASHBOARD_PLIST" 2>/dev/null; then
|
|
234
|
+
success "Loaded dashboard service"
|
|
235
|
+
else
|
|
236
|
+
warn "Could not load dashboard service — it may already be loaded"
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
if [[ -f "$CONNECT_PLIST" ]]; then
|
|
240
|
+
if launchctl load "$CONNECT_PLIST" 2>/dev/null; then
|
|
241
|
+
success "Loaded connect service"
|
|
242
|
+
else
|
|
243
|
+
warn "Could not load connect service — it may already be loaded"
|
|
244
|
+
fi
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
echo ""
|
|
248
|
+
info "Services will auto-start on next login"
|
|
249
|
+
info "View logs: ${DIM}tail -f ${LOG_DIR}/*.log${RESET}"
|
|
250
|
+
info "Uninstall: ${DIM}shipwright launchd uninstall${RESET}"
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# ─── Uninstall Command ──────────────────────────────────────────────────────
|
|
254
|
+
cmd_uninstall() {
|
|
255
|
+
check_macos
|
|
256
|
+
|
|
257
|
+
info "Uninstalling launchd agents..."
|
|
258
|
+
|
|
259
|
+
# Unload daemon
|
|
260
|
+
if [[ -f "$DAEMON_PLIST" ]]; then
|
|
261
|
+
if launchctl unload "$DAEMON_PLIST" 2>/dev/null; then
|
|
262
|
+
success "Unloaded daemon service"
|
|
263
|
+
else
|
|
264
|
+
warn "Could not unload daemon service — it may not be loaded"
|
|
265
|
+
fi
|
|
266
|
+
rm -f "$DAEMON_PLIST"
|
|
267
|
+
success "Removed daemon plist"
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
# Unload dashboard
|
|
271
|
+
if [[ -f "$DASHBOARD_PLIST" ]]; then
|
|
272
|
+
if launchctl unload "$DASHBOARD_PLIST" 2>/dev/null; then
|
|
273
|
+
success "Unloaded dashboard service"
|
|
274
|
+
else
|
|
275
|
+
warn "Could not unload dashboard service — it may not be loaded"
|
|
276
|
+
fi
|
|
277
|
+
rm -f "$DASHBOARD_PLIST"
|
|
278
|
+
success "Removed dashboard plist"
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
# Unload connect
|
|
282
|
+
if [[ -f "$CONNECT_PLIST" ]]; then
|
|
283
|
+
if launchctl unload "$CONNECT_PLIST" 2>/dev/null; then
|
|
284
|
+
success "Unloaded connect service"
|
|
285
|
+
else
|
|
286
|
+
warn "Could not unload connect service — it may not be loaded"
|
|
287
|
+
fi
|
|
288
|
+
rm -f "$CONNECT_PLIST"
|
|
289
|
+
success "Removed connect plist"
|
|
290
|
+
fi
|
|
291
|
+
|
|
292
|
+
echo ""
|
|
293
|
+
success "Uninstalled all launchd agents"
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
# ─── Status Command ─────────────────────────────────────────────────────────
|
|
297
|
+
cmd_status() {
|
|
298
|
+
check_macos
|
|
299
|
+
|
|
300
|
+
echo ""
|
|
301
|
+
echo -e "${CYAN}${BOLD}Launchd Services${RESET}"
|
|
302
|
+
echo -e "${DIM}════════════════════════════════════════════${RESET}"
|
|
303
|
+
echo ""
|
|
304
|
+
|
|
305
|
+
# Check daemon
|
|
306
|
+
if launchctl list | grep -q "com.shipwright.daemon" 2>/dev/null; then
|
|
307
|
+
echo -e " ${GREEN}●${RESET} Daemon service is ${GREEN}loaded${RESET}"
|
|
308
|
+
else
|
|
309
|
+
echo -e " ${RED}○${RESET} Daemon service is ${RED}not loaded${RESET}"
|
|
310
|
+
fi
|
|
311
|
+
|
|
312
|
+
# Check dashboard
|
|
313
|
+
if launchctl list | grep -q "com.shipwright.dashboard" 2>/dev/null; then
|
|
314
|
+
echo -e " ${GREEN}●${RESET} Dashboard service is ${GREEN}loaded${RESET}"
|
|
315
|
+
else
|
|
316
|
+
echo -e " ${RED}○${RESET} Dashboard service is ${RED}not loaded${RESET}"
|
|
317
|
+
fi
|
|
318
|
+
|
|
319
|
+
# Check connect
|
|
320
|
+
if launchctl list | grep -q "com.shipwright.connect" 2>/dev/null; then
|
|
321
|
+
echo -e " ${GREEN}●${RESET} Connect service is ${GREEN}loaded${RESET}"
|
|
322
|
+
else
|
|
323
|
+
echo -e " ${RED}○${RESET} Connect service is ${RED}not loaded${RESET}"
|
|
324
|
+
fi
|
|
325
|
+
|
|
326
|
+
echo ""
|
|
327
|
+
echo -e " Logs: ${DIM}${LOG_DIR}${RESET}"
|
|
328
|
+
echo ""
|
|
329
|
+
|
|
330
|
+
# Show recent log entries
|
|
331
|
+
if [[ -f "$LOG_DIR/daemon.stdout.log" ]]; then
|
|
332
|
+
echo -e "${DIM}Recent daemon logs:${RESET}"
|
|
333
|
+
tail -3 "$LOG_DIR/daemon.stdout.log" | sed 's/^/ /'
|
|
334
|
+
echo ""
|
|
335
|
+
fi
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
# ─── Main ───────────────────────────────────────────────────────────────────
|
|
339
|
+
main() {
|
|
340
|
+
local cmd="${1:-help}"
|
|
341
|
+
|
|
342
|
+
case "$cmd" in
|
|
343
|
+
install)
|
|
344
|
+
cmd_install
|
|
345
|
+
;;
|
|
346
|
+
uninstall)
|
|
347
|
+
cmd_uninstall
|
|
348
|
+
;;
|
|
349
|
+
status)
|
|
350
|
+
cmd_status
|
|
351
|
+
;;
|
|
352
|
+
help|--help|-h)
|
|
353
|
+
show_help
|
|
354
|
+
;;
|
|
355
|
+
*)
|
|
356
|
+
error "Unknown command: ${cmd}"
|
|
357
|
+
echo ""
|
|
358
|
+
show_help
|
|
359
|
+
exit 1
|
|
360
|
+
;;
|
|
361
|
+
esac
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
main "$@"
|