shipwright-cli 1.9.0 → 2.0.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/hooks/post-tool-use.sh +12 -5
- package/README.md +114 -36
- package/completions/_shipwright +212 -32
- package/completions/shipwright.bash +97 -25
- package/docs/strategy/01-market-research.md +619 -0
- package/docs/strategy/02-mission-and-brand.md +587 -0
- package/docs/strategy/03-gtm-and-roadmap.md +759 -0
- package/docs/strategy/QUICK-START.txt +289 -0
- package/docs/strategy/README.md +172 -0
- package/package.json +4 -2
- package/scripts/sw +217 -2
- package/scripts/sw-activity.sh +500 -0
- package/scripts/sw-adaptive.sh +925 -0
- package/scripts/sw-adversarial.sh +1 -1
- package/scripts/sw-architecture-enforcer.sh +1 -1
- package/scripts/sw-auth.sh +613 -0
- package/scripts/sw-autonomous.sh +664 -0
- package/scripts/sw-changelog.sh +704 -0
- package/scripts/sw-checkpoint.sh +79 -1
- package/scripts/sw-ci.sh +602 -0
- package/scripts/sw-cleanup.sh +192 -7
- package/scripts/sw-code-review.sh +637 -0
- package/scripts/sw-connect.sh +1 -1
- package/scripts/sw-context.sh +605 -0
- package/scripts/sw-cost.sh +1 -1
- package/scripts/sw-daemon.sh +812 -138
- package/scripts/sw-dashboard.sh +1 -1
- package/scripts/sw-db.sh +540 -0
- package/scripts/sw-decompose.sh +539 -0
- package/scripts/sw-deps.sh +551 -0
- package/scripts/sw-developer-simulation.sh +1 -1
- package/scripts/sw-discovery.sh +412 -0
- package/scripts/sw-docs-agent.sh +539 -0
- package/scripts/sw-docs.sh +1 -1
- package/scripts/sw-doctor.sh +59 -1
- package/scripts/sw-dora.sh +615 -0
- package/scripts/sw-durable.sh +710 -0
- package/scripts/sw-e2e-orchestrator.sh +535 -0
- package/scripts/sw-eventbus.sh +393 -0
- package/scripts/sw-feedback.sh +471 -0
- package/scripts/sw-fix.sh +1 -1
- package/scripts/sw-fleet-discover.sh +567 -0
- package/scripts/sw-fleet-viz.sh +404 -0
- package/scripts/sw-fleet.sh +8 -1
- package/scripts/sw-github-app.sh +596 -0
- package/scripts/sw-github-checks.sh +1 -1
- package/scripts/sw-github-deploy.sh +1 -1
- package/scripts/sw-github-graphql.sh +1 -1
- package/scripts/sw-guild.sh +569 -0
- package/scripts/sw-heartbeat.sh +1 -1
- package/scripts/sw-hygiene.sh +559 -0
- package/scripts/sw-incident.sh +617 -0
- package/scripts/sw-init.sh +88 -1
- package/scripts/sw-instrument.sh +699 -0
- package/scripts/sw-intelligence.sh +1 -1
- package/scripts/sw-jira.sh +1 -1
- package/scripts/sw-launchd.sh +366 -31
- package/scripts/sw-linear.sh +1 -1
- package/scripts/sw-logs.sh +1 -1
- package/scripts/sw-loop.sh +507 -51
- package/scripts/sw-memory.sh +198 -3
- package/scripts/sw-mission-control.sh +487 -0
- package/scripts/sw-model-router.sh +545 -0
- package/scripts/sw-otel.sh +596 -0
- package/scripts/sw-oversight.sh +689 -0
- package/scripts/sw-pipeline-composer.sh +8 -8
- package/scripts/sw-pipeline-vitals.sh +1096 -0
- package/scripts/sw-pipeline.sh +2451 -180
- package/scripts/sw-pm.sh +693 -0
- package/scripts/sw-pr-lifecycle.sh +522 -0
- package/scripts/sw-predictive.sh +1 -1
- package/scripts/sw-prep.sh +1 -1
- package/scripts/sw-ps.sh +4 -3
- package/scripts/sw-public-dashboard.sh +798 -0
- package/scripts/sw-quality.sh +595 -0
- package/scripts/sw-reaper.sh +5 -3
- package/scripts/sw-recruit.sh +573 -0
- package/scripts/sw-regression.sh +642 -0
- package/scripts/sw-release-manager.sh +736 -0
- package/scripts/sw-release.sh +706 -0
- package/scripts/sw-remote.sh +1 -1
- package/scripts/sw-replay.sh +520 -0
- package/scripts/sw-retro.sh +691 -0
- package/scripts/sw-scale.sh +444 -0
- package/scripts/sw-security-audit.sh +505 -0
- package/scripts/sw-self-optimize.sh +109 -8
- package/scripts/sw-session.sh +31 -9
- package/scripts/sw-setup.sh +1 -1
- package/scripts/sw-standup.sh +712 -0
- package/scripts/sw-status.sh +192 -1
- package/scripts/sw-strategic.sh +658 -0
- package/scripts/sw-stream.sh +450 -0
- package/scripts/sw-swarm.sh +583 -0
- package/scripts/sw-team-stages.sh +511 -0
- package/scripts/sw-templates.sh +1 -1
- package/scripts/sw-testgen.sh +515 -0
- package/scripts/sw-tmux-pipeline.sh +554 -0
- package/scripts/sw-tmux.sh +1 -1
- package/scripts/sw-trace.sh +485 -0
- package/scripts/sw-tracker-github.sh +188 -0
- package/scripts/sw-tracker-jira.sh +172 -0
- package/scripts/sw-tracker-linear.sh +251 -0
- package/scripts/sw-tracker.sh +117 -2
- package/scripts/sw-triage.sh +603 -0
- package/scripts/sw-upgrade.sh +1 -1
- package/scripts/sw-ux.sh +677 -0
- package/scripts/sw-webhook.sh +627 -0
- package/scripts/sw-widgets.sh +530 -0
- package/scripts/sw-worktree.sh +1 -1
- package/templates/pipelines/autonomous.json +8 -1
- 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 +16 -2
- package/templates/pipelines/hotfix.json +19 -0
- package/templates/pipelines/standard.json +19 -0
package/scripts/sw-jira.sh
CHANGED
package/scripts/sw-launchd.sh
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
|
-
# ║ shipwright launchd — Process supervision
|
|
4
|
-
# ║ Auto-start daemon + dashboard on boot via launchd
|
|
3
|
+
# ║ shipwright launchd — Process supervision (macOS + Linux) ║
|
|
4
|
+
# ║ Auto-start daemon + dashboard on boot via launchd (macOS) or systemd ║
|
|
5
5
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="2.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -31,48 +31,111 @@ success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
|
|
|
31
31
|
warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
|
|
32
32
|
error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
|
|
33
33
|
|
|
34
|
-
# ───
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
# ─── Check macOS ─────────────────────────────────────────────────────────────
|
|
43
|
-
check_macos() {
|
|
44
|
-
if [[ "$OSTYPE" != "darwin"* ]]; then
|
|
45
|
-
error "launchd is only available on macOS"
|
|
46
|
-
exit 1
|
|
34
|
+
# ─── OS Detection ───────────────────────────────────────────────────────────
|
|
35
|
+
detect_os() {
|
|
36
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
37
|
+
echo "macos"
|
|
38
|
+
elif [[ "$OSTYPE" == "linux-gnu"* ]] || [[ "$OSTYPE" == "linux"* ]]; then
|
|
39
|
+
echo "linux"
|
|
40
|
+
else
|
|
41
|
+
echo "unknown"
|
|
47
42
|
fi
|
|
48
43
|
}
|
|
49
44
|
|
|
45
|
+
OS_TYPE=$(detect_os)
|
|
46
|
+
|
|
47
|
+
# ─── Platform-specific Constants ────────────────────────────────────────────
|
|
48
|
+
if [[ "$OS_TYPE" == "macos" ]]; then
|
|
49
|
+
PLIST_DIR="$HOME/Library/LaunchAgents"
|
|
50
|
+
DAEMON_PLIST="$PLIST_DIR/com.shipwright.daemon.plist"
|
|
51
|
+
DASHBOARD_PLIST="$PLIST_DIR/com.shipwright.dashboard.plist"
|
|
52
|
+
CONNECT_PLIST="$PLIST_DIR/com.shipwright.connect.plist"
|
|
53
|
+
LOG_DIR="$HOME/.shipwright/logs"
|
|
54
|
+
elif [[ "$OS_TYPE" == "linux" ]]; then
|
|
55
|
+
SYSTEMD_USER_DIR="$HOME/.config/systemd/user"
|
|
56
|
+
DAEMON_SERVICE="$SYSTEMD_USER_DIR/shipwright-daemon.service"
|
|
57
|
+
DASHBOARD_SERVICE="$SYSTEMD_USER_DIR/shipwright-dashboard.service"
|
|
58
|
+
CONNECT_SERVICE="$SYSTEMD_USER_DIR/shipwright-connect.service"
|
|
59
|
+
LOG_DIR="$HOME/.shipwright/logs"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
TEAM_CONFIG="$HOME/.shipwright/team-config.json"
|
|
63
|
+
|
|
50
64
|
# ─── Help ───────────────────────────────────────────────────────────────────
|
|
51
65
|
show_help() {
|
|
52
66
|
echo ""
|
|
53
|
-
echo -e "${CYAN}${BOLD} Shipwright
|
|
67
|
+
echo -e "${CYAN}${BOLD} Shipwright Supervisor${RESET} ${DIM}v${VERSION}${RESET}"
|
|
54
68
|
echo -e "${DIM} ════════════════════════════════════════════${RESET}"
|
|
55
69
|
echo ""
|
|
56
70
|
echo -e " ${BOLD}USAGE${RESET}"
|
|
57
71
|
echo -e " shipwright launchd <command>"
|
|
58
72
|
echo ""
|
|
73
|
+
echo -e " ${BOLD}PLATFORM${RESET}: $OS_TYPE"
|
|
74
|
+
echo ""
|
|
59
75
|
echo -e " ${BOLD}COMMANDS${RESET}"
|
|
60
|
-
echo -e " ${CYAN}install${RESET} Install
|
|
61
|
-
echo -e " ${CYAN}uninstall${RESET} Remove
|
|
62
|
-
echo -e " ${CYAN}status${RESET} Check status of
|
|
76
|
+
echo -e " ${CYAN}install${RESET} Install services for daemon and dashboard (auto-start on boot)"
|
|
77
|
+
echo -e " ${CYAN}uninstall${RESET} Remove services and stop running daemons"
|
|
78
|
+
echo -e " ${CYAN}status${RESET} Check status of services"
|
|
79
|
+
echo -e " ${CYAN}logs${RESET} Tail service logs (systemd only)"
|
|
63
80
|
echo -e " ${CYAN}help${RESET} Show this help message"
|
|
64
81
|
echo ""
|
|
65
82
|
echo -e " ${BOLD}EXAMPLES${RESET}"
|
|
66
83
|
echo -e " ${DIM}shipwright launchd install${RESET} # Set up auto-start on boot"
|
|
67
84
|
echo -e " ${DIM}shipwright launchd status${RESET} # Check if services are running"
|
|
85
|
+
echo -e " ${DIM}shipwright launchd logs${RESET} # View service logs"
|
|
68
86
|
echo -e " ${DIM}shipwright launchd uninstall${RESET} # Remove auto-start"
|
|
69
87
|
echo ""
|
|
70
88
|
}
|
|
71
89
|
|
|
90
|
+
# ─── Systemd Unit File Generator (Linux) ──────────────────────────────────
|
|
91
|
+
create_systemd_unit() {
|
|
92
|
+
local unit_name="$1"
|
|
93
|
+
local description="$2"
|
|
94
|
+
local exec_start="$3"
|
|
95
|
+
local output_file="$4"
|
|
96
|
+
|
|
97
|
+
mkdir -p "$(dirname "$output_file")"
|
|
98
|
+
|
|
99
|
+
cat > "$output_file" <<EOF
|
|
100
|
+
[Unit]
|
|
101
|
+
Description=${description}
|
|
102
|
+
After=network.target
|
|
103
|
+
Wants=network-online.target
|
|
104
|
+
|
|
105
|
+
[Service]
|
|
106
|
+
Type=simple
|
|
107
|
+
ExecStart=${exec_start}
|
|
108
|
+
Restart=on-failure
|
|
109
|
+
RestartSec=10
|
|
110
|
+
StandardOutput=journal
|
|
111
|
+
StandardError=journal
|
|
112
|
+
SyslogIdentifier=${unit_name}
|
|
113
|
+
Environment="PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:\$HOME/.local/bin"
|
|
114
|
+
Environment="HOME=\$HOME"
|
|
115
|
+
|
|
116
|
+
[Install]
|
|
117
|
+
WantedBy=default.target
|
|
118
|
+
EOF
|
|
119
|
+
|
|
120
|
+
chmod 644 "$output_file"
|
|
121
|
+
}
|
|
122
|
+
|
|
72
123
|
# ─── Install Command ─────────────────────────────────────────────────────────
|
|
73
124
|
cmd_install() {
|
|
74
|
-
|
|
125
|
+
if [[ "$OS_TYPE" == "unknown" ]]; then
|
|
126
|
+
error "Unsupported OS type: $OSTYPE"
|
|
127
|
+
exit 1
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
if [[ "$OS_TYPE" == "macos" ]]; then
|
|
131
|
+
cmd_install_macos
|
|
132
|
+
else
|
|
133
|
+
cmd_install_linux
|
|
134
|
+
fi
|
|
135
|
+
}
|
|
75
136
|
|
|
137
|
+
# ─── Install macOS launchd agents ──────────────────────────────────────────
|
|
138
|
+
cmd_install_macos() {
|
|
76
139
|
info "Installing launchd agents..."
|
|
77
140
|
|
|
78
141
|
# Create directories
|
|
@@ -121,7 +184,7 @@ cmd_install() {
|
|
|
121
184
|
<key>EnvironmentVariables</key>
|
|
122
185
|
<dict>
|
|
123
186
|
<key>PATH</key>
|
|
124
|
-
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
187
|
+
<string>/opt/homebrew/bin:\$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
125
188
|
<key>HOME</key>
|
|
126
189
|
<string>\$HOME</string>
|
|
127
190
|
</dict>
|
|
@@ -168,7 +231,7 @@ EOF
|
|
|
168
231
|
<key>EnvironmentVariables</key>
|
|
169
232
|
<dict>
|
|
170
233
|
<key>PATH</key>
|
|
171
|
-
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
234
|
+
<string>/opt/homebrew/bin:\$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
172
235
|
<key>HOME</key>
|
|
173
236
|
<string>\$HOME</string>
|
|
174
237
|
</dict>
|
|
@@ -207,7 +270,7 @@ EOF
|
|
|
207
270
|
<key>EnvironmentVariables</key>
|
|
208
271
|
<dict>
|
|
209
272
|
<key>PATH</key>
|
|
210
|
-
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
273
|
+
<string>/opt/homebrew/bin:\$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
211
274
|
<key>HOME</key>
|
|
212
275
|
<string>\$HOME</string>
|
|
213
276
|
</dict>
|
|
@@ -250,10 +313,135 @@ EOF
|
|
|
250
313
|
info "Uninstall: ${DIM}shipwright launchd uninstall${RESET}"
|
|
251
314
|
}
|
|
252
315
|
|
|
316
|
+
# ─── Install Linux systemd user services ───────────────────────────────────
|
|
317
|
+
cmd_install_linux() {
|
|
318
|
+
info "Installing systemd user services..."
|
|
319
|
+
|
|
320
|
+
# Create directories
|
|
321
|
+
mkdir -p "$SYSTEMD_USER_DIR" "$LOG_DIR"
|
|
322
|
+
|
|
323
|
+
# Find the full path to the sw CLI
|
|
324
|
+
local sw_bin
|
|
325
|
+
if [[ -x "$SCRIPT_DIR/sw" ]]; then
|
|
326
|
+
sw_bin="$SCRIPT_DIR/sw"
|
|
327
|
+
else
|
|
328
|
+
# Try to find it via PATH
|
|
329
|
+
sw_bin=$(command -v sw 2>/dev/null || echo "")
|
|
330
|
+
if [[ -z "$sw_bin" ]]; then
|
|
331
|
+
error "Could not find 'sw' binary — make sure Shipwright is installed"
|
|
332
|
+
exit 1
|
|
333
|
+
fi
|
|
334
|
+
fi
|
|
335
|
+
|
|
336
|
+
# Resolve symlinks in case sw is symlinked
|
|
337
|
+
sw_bin=$(cd "$(dirname "$sw_bin")" && pwd)/$(basename "$sw_bin")
|
|
338
|
+
|
|
339
|
+
# ─── Create Daemon Service ─────────────────────────────────────────────────
|
|
340
|
+
create_systemd_unit "shipwright-daemon" \
|
|
341
|
+
"Shipwright Daemon - Autonomous Issue Processor" \
|
|
342
|
+
"env -u CLAUDECODE ${sw_bin} daemon start --detach" \
|
|
343
|
+
"$DAEMON_SERVICE"
|
|
344
|
+
|
|
345
|
+
success "Created daemon service: ${DAEMON_SERVICE}"
|
|
346
|
+
|
|
347
|
+
# ─── Create Dashboard Service ──────────────────────────────────────────────
|
|
348
|
+
local bun_bin
|
|
349
|
+
bun_bin=$(command -v bun 2>/dev/null || echo "bun")
|
|
350
|
+
|
|
351
|
+
local server_file="$REPO_DIR/dashboard/server.ts"
|
|
352
|
+
if [[ ! -f "$server_file" ]]; then
|
|
353
|
+
warn "server.ts not found at $server_file — dashboard service will reference a missing file"
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
create_systemd_unit "shipwright-dashboard" \
|
|
357
|
+
"Shipwright Dashboard - Real-time Team Status" \
|
|
358
|
+
"${bun_bin} run ${server_file}" \
|
|
359
|
+
"$DASHBOARD_SERVICE"
|
|
360
|
+
|
|
361
|
+
success "Created dashboard service: ${DASHBOARD_SERVICE}"
|
|
362
|
+
|
|
363
|
+
# ─── Create Connect Service (only if team-config.json exists) ──────────────
|
|
364
|
+
if [[ -f "$TEAM_CONFIG" ]]; then
|
|
365
|
+
create_systemd_unit "shipwright-connect" \
|
|
366
|
+
"Shipwright Connect - Team Sync Service" \
|
|
367
|
+
"env -u CLAUDECODE ${sw_bin} connect start" \
|
|
368
|
+
"$CONNECT_SERVICE"
|
|
369
|
+
|
|
370
|
+
success "Created connect service: ${CONNECT_SERVICE}"
|
|
371
|
+
else
|
|
372
|
+
info "Skipping connect service — ${TEAM_CONFIG} not found"
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
# ─── Enable and Start Services ─────────────────────────────────────────────
|
|
376
|
+
info "Enabling systemd user services..."
|
|
377
|
+
|
|
378
|
+
if systemctl --user enable shipwright-daemon.service 2>/dev/null; then
|
|
379
|
+
success "Enabled daemon service"
|
|
380
|
+
else
|
|
381
|
+
warn "Could not enable daemon service"
|
|
382
|
+
fi
|
|
383
|
+
|
|
384
|
+
if systemctl --user enable shipwright-dashboard.service 2>/dev/null; then
|
|
385
|
+
success "Enabled dashboard service"
|
|
386
|
+
else
|
|
387
|
+
warn "Could not enable dashboard service"
|
|
388
|
+
fi
|
|
389
|
+
|
|
390
|
+
if [[ -f "$CONNECT_SERVICE" ]]; then
|
|
391
|
+
if systemctl --user enable shipwright-connect.service 2>/dev/null; then
|
|
392
|
+
success "Enabled connect service"
|
|
393
|
+
else
|
|
394
|
+
warn "Could not enable connect service"
|
|
395
|
+
fi
|
|
396
|
+
fi
|
|
397
|
+
|
|
398
|
+
# Start services immediately
|
|
399
|
+
info "Starting systemd user services..."
|
|
400
|
+
|
|
401
|
+
if systemctl --user start shipwright-daemon.service 2>/dev/null; then
|
|
402
|
+
success "Started daemon service"
|
|
403
|
+
else
|
|
404
|
+
warn "Could not start daemon service — enable user lingering first: loginctl enable-linger"
|
|
405
|
+
fi
|
|
406
|
+
|
|
407
|
+
if systemctl --user start shipwright-dashboard.service 2>/dev/null; then
|
|
408
|
+
success "Started dashboard service"
|
|
409
|
+
else
|
|
410
|
+
warn "Could not start dashboard service"
|
|
411
|
+
fi
|
|
412
|
+
|
|
413
|
+
if [[ -f "$CONNECT_SERVICE" ]]; then
|
|
414
|
+
if systemctl --user start shipwright-connect.service 2>/dev/null; then
|
|
415
|
+
success "Started connect service"
|
|
416
|
+
else
|
|
417
|
+
warn "Could not start connect service"
|
|
418
|
+
fi
|
|
419
|
+
fi
|
|
420
|
+
|
|
421
|
+
echo ""
|
|
422
|
+
info "Services will auto-start on next login (with systemd lingering enabled)"
|
|
423
|
+
info "Enable lingering: ${DIM}loginctl enable-linger${RESET}"
|
|
424
|
+
info "View logs: ${DIM}journalctl --user -u shipwright-daemon -f${RESET}"
|
|
425
|
+
info "View all logs: ${DIM}journalctl --user -u shipwright-* -f${RESET}"
|
|
426
|
+
info "Uninstall: ${DIM}shipwright launchd uninstall${RESET}"
|
|
427
|
+
}
|
|
428
|
+
|
|
253
429
|
# ─── Uninstall Command ──────────────────────────────────────────────────────
|
|
254
430
|
cmd_uninstall() {
|
|
255
|
-
|
|
431
|
+
if [[ "$OS_TYPE" == "unknown" ]]; then
|
|
432
|
+
error "Unsupported OS type: $OSTYPE"
|
|
433
|
+
exit 1
|
|
434
|
+
fi
|
|
435
|
+
|
|
436
|
+
if [[ "$OS_TYPE" == "macos" ]]; then
|
|
437
|
+
cmd_uninstall_macos
|
|
438
|
+
else
|
|
439
|
+
cmd_uninstall_linux
|
|
440
|
+
fi
|
|
441
|
+
}
|
|
256
442
|
|
|
443
|
+
# ─── Uninstall macOS launchd agents ────────────────────────────────────────
|
|
444
|
+
cmd_uninstall_macos() {
|
|
257
445
|
info "Uninstalling launchd agents..."
|
|
258
446
|
|
|
259
447
|
# Unload daemon
|
|
@@ -293,31 +481,112 @@ cmd_uninstall() {
|
|
|
293
481
|
success "Uninstalled all launchd agents"
|
|
294
482
|
}
|
|
295
483
|
|
|
484
|
+
# ─── Uninstall Linux systemd user services ────────────────────────────────
|
|
485
|
+
cmd_uninstall_linux() {
|
|
486
|
+
info "Uninstalling systemd user services..."
|
|
487
|
+
|
|
488
|
+
# Stop and disable daemon
|
|
489
|
+
if systemctl --user is-active --quiet shipwright-daemon.service 2>/dev/null; then
|
|
490
|
+
if systemctl --user stop shipwright-daemon.service 2>/dev/null; then
|
|
491
|
+
success "Stopped daemon service"
|
|
492
|
+
else
|
|
493
|
+
warn "Could not stop daemon service"
|
|
494
|
+
fi
|
|
495
|
+
fi
|
|
496
|
+
|
|
497
|
+
if systemctl --user is-enabled --quiet shipwright-daemon.service 2>/dev/null; then
|
|
498
|
+
if systemctl --user disable shipwright-daemon.service 2>/dev/null; then
|
|
499
|
+
success "Disabled daemon service"
|
|
500
|
+
else
|
|
501
|
+
warn "Could not disable daemon service"
|
|
502
|
+
fi
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
# Stop and disable dashboard
|
|
506
|
+
if systemctl --user is-active --quiet shipwright-dashboard.service 2>/dev/null; then
|
|
507
|
+
if systemctl --user stop shipwright-dashboard.service 2>/dev/null; then
|
|
508
|
+
success "Stopped dashboard service"
|
|
509
|
+
else
|
|
510
|
+
warn "Could not stop dashboard service"
|
|
511
|
+
fi
|
|
512
|
+
fi
|
|
513
|
+
|
|
514
|
+
if systemctl --user is-enabled --quiet shipwright-dashboard.service 2>/dev/null; then
|
|
515
|
+
if systemctl --user disable shipwright-dashboard.service 2>/dev/null; then
|
|
516
|
+
success "Disabled dashboard service"
|
|
517
|
+
else
|
|
518
|
+
warn "Could not disable dashboard service"
|
|
519
|
+
fi
|
|
520
|
+
fi
|
|
521
|
+
|
|
522
|
+
# Stop and disable connect
|
|
523
|
+
if systemctl --user is-active --quiet shipwright-connect.service 2>/dev/null; then
|
|
524
|
+
if systemctl --user stop shipwright-connect.service 2>/dev/null; then
|
|
525
|
+
success "Stopped connect service"
|
|
526
|
+
else
|
|
527
|
+
warn "Could not stop connect service"
|
|
528
|
+
fi
|
|
529
|
+
fi
|
|
530
|
+
|
|
531
|
+
if systemctl --user is-enabled --quiet shipwright-connect.service 2>/dev/null; then
|
|
532
|
+
if systemctl --user disable shipwright-connect.service 2>/dev/null; then
|
|
533
|
+
success "Disabled connect service"
|
|
534
|
+
else
|
|
535
|
+
warn "Could not disable connect service"
|
|
536
|
+
fi
|
|
537
|
+
fi
|
|
538
|
+
|
|
539
|
+
# Remove service files
|
|
540
|
+
[[ -f "$DAEMON_SERVICE" ]] && rm -f "$DAEMON_SERVICE" && success "Removed daemon service file"
|
|
541
|
+
[[ -f "$DASHBOARD_SERVICE" ]] && rm -f "$DASHBOARD_SERVICE" && success "Removed dashboard service file"
|
|
542
|
+
[[ -f "$CONNECT_SERVICE" ]] && rm -f "$CONNECT_SERVICE" && success "Removed connect service file"
|
|
543
|
+
|
|
544
|
+
# Reload systemd daemon
|
|
545
|
+
if systemctl --user daemon-reload 2>/dev/null; then
|
|
546
|
+
success "Reloaded systemd user daemon"
|
|
547
|
+
fi
|
|
548
|
+
|
|
549
|
+
echo ""
|
|
550
|
+
success "Uninstalled all systemd user services"
|
|
551
|
+
}
|
|
552
|
+
|
|
296
553
|
# ─── Status Command ─────────────────────────────────────────────────────────
|
|
297
554
|
cmd_status() {
|
|
298
|
-
|
|
555
|
+
if [[ "$OS_TYPE" == "unknown" ]]; then
|
|
556
|
+
error "Unsupported OS type: $OSTYPE"
|
|
557
|
+
exit 1
|
|
558
|
+
fi
|
|
299
559
|
|
|
560
|
+
if [[ "$OS_TYPE" == "macos" ]]; then
|
|
561
|
+
cmd_status_macos
|
|
562
|
+
else
|
|
563
|
+
cmd_status_linux
|
|
564
|
+
fi
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
# ─── Status macOS launchd services ─────────────────────────────────────────
|
|
568
|
+
cmd_status_macos() {
|
|
300
569
|
echo ""
|
|
301
570
|
echo -e "${CYAN}${BOLD}Launchd Services${RESET}"
|
|
302
571
|
echo -e "${DIM}════════════════════════════════════════════${RESET}"
|
|
303
572
|
echo ""
|
|
304
573
|
|
|
305
574
|
# Check daemon
|
|
306
|
-
if launchctl list | grep -q "com.shipwright.daemon"
|
|
575
|
+
if launchctl list 2>/dev/null | grep -q "com.shipwright.daemon"; then
|
|
307
576
|
echo -e " ${GREEN}●${RESET} Daemon service is ${GREEN}loaded${RESET}"
|
|
308
577
|
else
|
|
309
578
|
echo -e " ${RED}○${RESET} Daemon service is ${RED}not loaded${RESET}"
|
|
310
579
|
fi
|
|
311
580
|
|
|
312
581
|
# Check dashboard
|
|
313
|
-
if launchctl list | grep -q "com.shipwright.dashboard"
|
|
582
|
+
if launchctl list 2>/dev/null | grep -q "com.shipwright.dashboard"; then
|
|
314
583
|
echo -e " ${GREEN}●${RESET} Dashboard service is ${GREEN}loaded${RESET}"
|
|
315
584
|
else
|
|
316
585
|
echo -e " ${RED}○${RESET} Dashboard service is ${RED}not loaded${RESET}"
|
|
317
586
|
fi
|
|
318
587
|
|
|
319
588
|
# Check connect
|
|
320
|
-
if launchctl list | grep -q "com.shipwright.connect"
|
|
589
|
+
if launchctl list 2>/dev/null | grep -q "com.shipwright.connect"; then
|
|
321
590
|
echo -e " ${GREEN}●${RESET} Connect service is ${GREEN}loaded${RESET}"
|
|
322
591
|
else
|
|
323
592
|
echo -e " ${RED}○${RESET} Connect service is ${RED}not loaded${RESET}"
|
|
@@ -330,11 +599,72 @@ cmd_status() {
|
|
|
330
599
|
# Show recent log entries
|
|
331
600
|
if [[ -f "$LOG_DIR/daemon.stdout.log" ]]; then
|
|
332
601
|
echo -e "${DIM}Recent daemon logs:${RESET}"
|
|
333
|
-
tail -3 "$LOG_DIR/daemon.stdout.log" | sed 's/^/ /'
|
|
602
|
+
tail -3 "$LOG_DIR/daemon.stdout.log" 2>/dev/null | sed 's/^/ /'
|
|
334
603
|
echo ""
|
|
335
604
|
fi
|
|
336
605
|
}
|
|
337
606
|
|
|
607
|
+
# ─── Status Linux systemd services ────────────────────────────────────────
|
|
608
|
+
cmd_status_linux() {
|
|
609
|
+
echo ""
|
|
610
|
+
echo -e "${CYAN}${BOLD}Systemd User Services${RESET}"
|
|
611
|
+
echo -e "${DIM}════════════════════════════════════════════${RESET}"
|
|
612
|
+
echo ""
|
|
613
|
+
|
|
614
|
+
# Check daemon
|
|
615
|
+
if systemctl --user is-active --quiet shipwright-daemon.service 2>/dev/null; then
|
|
616
|
+
echo -e " ${GREEN}●${RESET} Daemon service is ${GREEN}running${RESET}"
|
|
617
|
+
else
|
|
618
|
+
echo -e " ${RED}○${RESET} Daemon service is ${RED}not running${RESET}"
|
|
619
|
+
fi
|
|
620
|
+
|
|
621
|
+
# Check dashboard
|
|
622
|
+
if systemctl --user is-active --quiet shipwright-dashboard.service 2>/dev/null; then
|
|
623
|
+
echo -e " ${GREEN}●${RESET} Dashboard service is ${GREEN}running${RESET}"
|
|
624
|
+
else
|
|
625
|
+
echo -e " ${RED}○${RESET} Dashboard service is ${RED}not running${RESET}"
|
|
626
|
+
fi
|
|
627
|
+
|
|
628
|
+
# Check connect
|
|
629
|
+
if systemctl --user is-active --quiet shipwright-connect.service 2>/dev/null; then
|
|
630
|
+
echo -e " ${GREEN}●${RESET} Connect service is ${GREEN}running${RESET}"
|
|
631
|
+
else
|
|
632
|
+
echo -e " ${RED}○${RESET} Connect service is ${RED}not running${RESET}"
|
|
633
|
+
fi
|
|
634
|
+
|
|
635
|
+
echo ""
|
|
636
|
+
echo -e " Services: ${DIM}${SYSTEMD_USER_DIR}${RESET}"
|
|
637
|
+
echo -e " Logs: ${DIM}journalctl --user${RESET}"
|
|
638
|
+
echo ""
|
|
639
|
+
|
|
640
|
+
# Show recent journal entries for daemon
|
|
641
|
+
if command -v journalctl &>/dev/null; then
|
|
642
|
+
echo -e "${DIM}Recent daemon logs:${RESET}"
|
|
643
|
+
journalctl --user -u shipwright-daemon.service -n 3 --no-pager 2>/dev/null | tail -3 | sed 's/^/ /' || true
|
|
644
|
+
echo ""
|
|
645
|
+
fi
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
# ─── Logs Command (systemd only) ────────────────────────────────────────────
|
|
649
|
+
cmd_logs() {
|
|
650
|
+
if [[ "$OS_TYPE" != "linux" ]]; then
|
|
651
|
+
error "logs command is only available on Linux (systemd)"
|
|
652
|
+
exit 1
|
|
653
|
+
fi
|
|
654
|
+
|
|
655
|
+
local service="${1:-shipwright-daemon.service}"
|
|
656
|
+
|
|
657
|
+
if ! systemctl --user is-active --quiet "$service" 2>/dev/null; then
|
|
658
|
+
warn "Service $service is not running"
|
|
659
|
+
fi
|
|
660
|
+
|
|
661
|
+
echo ""
|
|
662
|
+
info "Tailing logs for $service (Ctrl-C to stop)..."
|
|
663
|
+
echo ""
|
|
664
|
+
|
|
665
|
+
journalctl --user -u "$service" -f --no-pager
|
|
666
|
+
}
|
|
667
|
+
|
|
338
668
|
# ─── Main ───────────────────────────────────────────────────────────────────
|
|
339
669
|
main() {
|
|
340
670
|
local cmd="${1:-help}"
|
|
@@ -349,6 +679,9 @@ main() {
|
|
|
349
679
|
status)
|
|
350
680
|
cmd_status
|
|
351
681
|
;;
|
|
682
|
+
logs)
|
|
683
|
+
cmd_logs "${2:-}"
|
|
684
|
+
;;
|
|
352
685
|
help|--help|-h)
|
|
353
686
|
show_help
|
|
354
687
|
;;
|
|
@@ -361,4 +694,6 @@ main() {
|
|
|
361
694
|
esac
|
|
362
695
|
}
|
|
363
696
|
|
|
364
|
-
|
|
697
|
+
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
|
698
|
+
main "$@"
|
|
699
|
+
fi
|
package/scripts/sw-linear.sh
CHANGED
package/scripts/sw-logs.sh
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# ║ ║
|
|
5
5
|
# ║ Captures tmux pane scrollback and provides log browsing/search. ║
|
|
6
6
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
7
|
-
VERSION="
|
|
7
|
+
VERSION="2.0.0"
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
10
10
|
|