shipwright-cli 2.3.1 → 3.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/README.md +95 -28
- package/completions/_shipwright +1 -1
- package/completions/shipwright.bash +3 -8
- package/completions/shipwright.fish +1 -1
- package/config/defaults.json +111 -0
- package/config/event-schema.json +81 -0
- package/config/policy.json +155 -2
- package/config/policy.schema.json +162 -1
- package/dashboard/coverage/coverage-summary.json +14 -0
- package/dashboard/public/index.html +1 -1
- package/dashboard/server.ts +306 -17
- package/dashboard/src/components/charts/bar.test.ts +79 -0
- package/dashboard/src/components/charts/donut.test.ts +68 -0
- package/dashboard/src/components/charts/pipeline-rail.test.ts +117 -0
- package/dashboard/src/components/charts/sparkline.test.ts +125 -0
- package/dashboard/src/core/api.test.ts +309 -0
- package/dashboard/src/core/helpers.test.ts +301 -0
- package/dashboard/src/core/router.test.ts +307 -0
- package/dashboard/src/core/router.ts +7 -0
- package/dashboard/src/core/sse.test.ts +144 -0
- package/dashboard/src/views/metrics.test.ts +186 -0
- package/dashboard/src/views/overview.test.ts +173 -0
- package/dashboard/src/views/pipelines.test.ts +183 -0
- package/dashboard/src/views/team.test.ts +253 -0
- package/dashboard/vitest.config.ts +14 -5
- package/docs/TIPS.md +1 -1
- package/docs/patterns/README.md +1 -1
- package/package.json +15 -5
- package/scripts/adapters/docker-deploy.sh +1 -1
- package/scripts/adapters/tmux-adapter.sh +11 -1
- package/scripts/adapters/wezterm-adapter.sh +1 -1
- package/scripts/check-version-consistency.sh +1 -1
- package/scripts/lib/architecture.sh +126 -0
- package/scripts/lib/bootstrap.sh +75 -0
- package/scripts/lib/compat.sh +89 -6
- package/scripts/lib/config.sh +91 -0
- package/scripts/lib/daemon-adaptive.sh +3 -3
- package/scripts/lib/daemon-dispatch.sh +39 -16
- package/scripts/lib/daemon-health.sh +1 -1
- package/scripts/lib/daemon-patrol.sh +24 -12
- package/scripts/lib/daemon-poll.sh +37 -25
- package/scripts/lib/daemon-state.sh +115 -23
- package/scripts/lib/daemon-triage.sh +30 -8
- package/scripts/lib/fleet-failover.sh +63 -0
- package/scripts/lib/helpers.sh +30 -6
- package/scripts/lib/pipeline-detection.sh +2 -2
- package/scripts/lib/pipeline-github.sh +9 -9
- package/scripts/lib/pipeline-intelligence.sh +85 -35
- package/scripts/lib/pipeline-quality-checks.sh +16 -16
- package/scripts/lib/pipeline-quality.sh +1 -1
- package/scripts/lib/pipeline-stages.sh +242 -28
- package/scripts/lib/pipeline-state.sh +40 -4
- package/scripts/lib/test-helpers.sh +247 -0
- package/scripts/postinstall.mjs +3 -11
- package/scripts/sw +10 -4
- package/scripts/sw-activity.sh +1 -11
- package/scripts/sw-adaptive.sh +109 -85
- package/scripts/sw-adversarial.sh +4 -14
- package/scripts/sw-architecture-enforcer.sh +1 -11
- package/scripts/sw-auth.sh +8 -17
- package/scripts/sw-autonomous.sh +111 -49
- package/scripts/sw-changelog.sh +1 -11
- package/scripts/sw-checkpoint.sh +144 -20
- package/scripts/sw-ci.sh +2 -12
- package/scripts/sw-cleanup.sh +13 -17
- package/scripts/sw-code-review.sh +16 -36
- package/scripts/sw-connect.sh +5 -12
- package/scripts/sw-context.sh +9 -26
- package/scripts/sw-cost.sh +6 -16
- package/scripts/sw-daemon.sh +75 -70
- package/scripts/sw-dashboard.sh +57 -17
- package/scripts/sw-db.sh +506 -15
- package/scripts/sw-decompose.sh +1 -11
- package/scripts/sw-deps.sh +15 -25
- package/scripts/sw-developer-simulation.sh +1 -11
- package/scripts/sw-discovery.sh +112 -30
- package/scripts/sw-doc-fleet.sh +7 -17
- package/scripts/sw-docs-agent.sh +6 -16
- package/scripts/sw-docs.sh +4 -12
- package/scripts/sw-doctor.sh +134 -43
- package/scripts/sw-dora.sh +11 -19
- package/scripts/sw-durable.sh +35 -52
- package/scripts/sw-e2e-orchestrator.sh +11 -27
- package/scripts/sw-eventbus.sh +115 -115
- package/scripts/sw-evidence.sh +748 -0
- package/scripts/sw-feedback.sh +3 -13
- package/scripts/sw-fix.sh +2 -20
- package/scripts/sw-fleet-discover.sh +1 -11
- package/scripts/sw-fleet-viz.sh +10 -18
- package/scripts/sw-fleet.sh +13 -17
- package/scripts/sw-github-app.sh +6 -16
- package/scripts/sw-github-checks.sh +1 -11
- package/scripts/sw-github-deploy.sh +1 -11
- package/scripts/sw-github-graphql.sh +2 -12
- package/scripts/sw-guild.sh +1 -11
- package/scripts/sw-heartbeat.sh +49 -12
- package/scripts/sw-hygiene.sh +45 -43
- package/scripts/sw-incident.sh +284 -67
- package/scripts/sw-init.sh +35 -37
- package/scripts/sw-instrument.sh +1 -11
- package/scripts/sw-intelligence.sh +362 -51
- package/scripts/sw-jira.sh +5 -14
- package/scripts/sw-launchd.sh +2 -12
- package/scripts/sw-linear.sh +8 -17
- package/scripts/sw-logs.sh +4 -12
- package/scripts/sw-loop.sh +641 -90
- package/scripts/sw-memory.sh +243 -17
- package/scripts/sw-mission-control.sh +2 -12
- package/scripts/sw-model-router.sh +73 -34
- package/scripts/sw-otel.sh +11 -21
- package/scripts/sw-oversight.sh +1 -11
- package/scripts/sw-patrol-meta.sh +5 -11
- package/scripts/sw-pipeline-composer.sh +7 -17
- package/scripts/sw-pipeline-vitals.sh +1 -11
- package/scripts/sw-pipeline.sh +478 -122
- package/scripts/sw-pm.sh +2 -12
- package/scripts/sw-pr-lifecycle.sh +203 -29
- package/scripts/sw-predictive.sh +16 -22
- package/scripts/sw-prep.sh +6 -16
- package/scripts/sw-ps.sh +1 -11
- package/scripts/sw-public-dashboard.sh +2 -12
- package/scripts/sw-quality.sh +77 -10
- package/scripts/sw-reaper.sh +1 -11
- package/scripts/sw-recruit.sh +15 -25
- package/scripts/sw-regression.sh +11 -21
- package/scripts/sw-release-manager.sh +19 -28
- package/scripts/sw-release.sh +8 -16
- package/scripts/sw-remote.sh +1 -11
- package/scripts/sw-replay.sh +48 -44
- package/scripts/sw-retro.sh +70 -92
- package/scripts/sw-review-rerun.sh +220 -0
- package/scripts/sw-scale.sh +109 -32
- package/scripts/sw-security-audit.sh +12 -22
- package/scripts/sw-self-optimize.sh +239 -23
- package/scripts/sw-session.sh +3 -13
- package/scripts/sw-setup.sh +8 -18
- package/scripts/sw-standup.sh +5 -15
- package/scripts/sw-status.sh +32 -23
- package/scripts/sw-strategic.sh +129 -13
- package/scripts/sw-stream.sh +1 -11
- package/scripts/sw-swarm.sh +76 -36
- package/scripts/sw-team-stages.sh +10 -20
- package/scripts/sw-templates.sh +4 -14
- package/scripts/sw-testgen.sh +3 -13
- package/scripts/sw-tmux-pipeline.sh +1 -19
- package/scripts/sw-tmux-role-color.sh +0 -10
- package/scripts/sw-tmux-status.sh +3 -11
- package/scripts/sw-tmux.sh +2 -20
- package/scripts/sw-trace.sh +1 -19
- package/scripts/sw-tracker-github.sh +0 -10
- package/scripts/sw-tracker-jira.sh +1 -11
- package/scripts/sw-tracker-linear.sh +1 -11
- package/scripts/sw-tracker.sh +7 -24
- package/scripts/sw-triage.sh +24 -34
- package/scripts/sw-upgrade.sh +5 -23
- package/scripts/sw-ux.sh +1 -19
- package/scripts/sw-webhook.sh +18 -32
- package/scripts/sw-widgets.sh +3 -21
- package/scripts/sw-worktree.sh +11 -27
- package/scripts/update-homebrew-sha.sh +67 -0
- package/templates/pipelines/tdd.json +72 -0
- package/scripts/sw-pipeline.sh.mock +0 -7
package/scripts/sw-feedback.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -34,16 +34,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
34
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
35
|
}
|
|
36
36
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
37
|
# ─── Storage Paths ──────────────────────────────────────────────────────────
|
|
48
38
|
INCIDENTS_FILE="${HOME}/.shipwright/incidents.jsonl"
|
|
49
39
|
ERROR_THRESHOLD=5 # Create issue if error count >= threshold
|
|
@@ -262,7 +252,7 @@ git show $regression_commit
|
|
|
262
252
|
EOF
|
|
263
253
|
)
|
|
264
254
|
|
|
265
|
-
if ! command -v gh
|
|
255
|
+
if ! command -v gh >/dev/null 2>&1; then
|
|
266
256
|
error "gh CLI not found — cannot create issue"
|
|
267
257
|
return 1
|
|
268
258
|
fi
|
|
@@ -275,7 +265,7 @@ EOF
|
|
|
275
265
|
--body "$issue_body" \
|
|
276
266
|
--label "shipwright" \
|
|
277
267
|
--label "hotfix" \
|
|
278
|
-
2>&1 | tail -1)
|
|
268
|
+
2>&1 | tail -1) || true
|
|
279
269
|
|
|
280
270
|
if [[ -n "$issue_url" ]]; then
|
|
281
271
|
success "Created issue: $issue_url"
|
package/scripts/sw-fix.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -25,24 +25,6 @@ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
|
|
|
25
25
|
now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
|
|
26
26
|
now_epoch() { date +%s; }
|
|
27
27
|
fi
|
|
28
|
-
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
29
|
-
emit_event() {
|
|
30
|
-
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
31
|
-
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
32
|
-
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
33
|
-
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
34
|
-
}
|
|
35
|
-
fi
|
|
36
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
37
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
38
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
39
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
40
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
41
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
42
|
-
DIM="${DIM:-\033[2m}"
|
|
43
|
-
BOLD="${BOLD:-\033[1m}"
|
|
44
|
-
RESET="${RESET:-\033[0m}"
|
|
45
|
-
|
|
46
28
|
format_duration() {
|
|
47
29
|
local secs="$1"
|
|
48
30
|
if [[ "$secs" -ge 3600 ]]; then
|
|
@@ -341,7 +323,7 @@ fix_start() {
|
|
|
341
323
|
|
|
342
324
|
# Spawn pipeline in subshell
|
|
343
325
|
(
|
|
344
|
-
cd "$expanded"
|
|
326
|
+
cd "$expanded" || exit 1
|
|
345
327
|
|
|
346
328
|
# Determine base branch
|
|
347
329
|
local base
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -34,16 +34,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
34
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
35
|
}
|
|
36
36
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
37
|
# ─── Help ───────────────────────────────────────────────────────────────────
|
|
48
38
|
|
|
49
39
|
show_help() {
|
package/scripts/sw-fleet-viz.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -19,6 +19,8 @@ REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
19
19
|
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
|
|
20
20
|
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
|
|
21
21
|
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
|
|
22
|
+
# Color fallbacks when helpers not loaded
|
|
23
|
+
: "${CYAN:=}" "${BOLD:=}" "${RESET:=}" "${DIM:=}" "${GREEN:=}" "${RED:=}" "${YELLOW:=}" "${PURPLE:=}" "${WHITE:=}" "${BLUE:=}"
|
|
22
24
|
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
|
|
23
25
|
[[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
|
|
24
26
|
[[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
|
|
@@ -34,16 +36,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
36
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
37
|
}
|
|
36
38
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
39
|
format_duration() {
|
|
48
40
|
local secs="$1"
|
|
49
41
|
if [[ "$secs" -ge 3600 ]]; then
|
|
@@ -70,7 +62,7 @@ get_health_status() {
|
|
|
70
62
|
# degraded (yellow) = some failures but recovering
|
|
71
63
|
# failing (red) = persistent failures
|
|
72
64
|
|
|
73
|
-
if ! command -v jq
|
|
65
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
74
66
|
echo "unknown"
|
|
75
67
|
return
|
|
76
68
|
fi
|
|
@@ -98,7 +90,7 @@ color_health() {
|
|
|
98
90
|
|
|
99
91
|
# ─── Overview Subcommand ───────────────────────────────────────────────────
|
|
100
92
|
show_overview() {
|
|
101
|
-
if ! command -v jq
|
|
93
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
102
94
|
error "jq is required for fleet visualization"
|
|
103
95
|
exit 1
|
|
104
96
|
fi
|
|
@@ -144,7 +136,7 @@ show_overview() {
|
|
|
144
136
|
|
|
145
137
|
# ─── Workers Subcommand ────────────────────────────────────────────────────
|
|
146
138
|
show_workers() {
|
|
147
|
-
if ! command -v jq
|
|
139
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
148
140
|
error "jq is required for fleet visualization"
|
|
149
141
|
exit 1
|
|
150
142
|
fi
|
|
@@ -197,7 +189,7 @@ show_workers() {
|
|
|
197
189
|
|
|
198
190
|
# ─── Insights Subcommand ───────────────────────────────────────────────────
|
|
199
191
|
show_insights() {
|
|
200
|
-
if ! command -v jq
|
|
192
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
201
193
|
error "jq is required for fleet visualization"
|
|
202
194
|
exit 1
|
|
203
195
|
fi
|
|
@@ -238,7 +230,7 @@ show_insights() {
|
|
|
238
230
|
|
|
239
231
|
# ─── Queue Subcommand ──────────────────────────────────────────────────────
|
|
240
232
|
show_queue() {
|
|
241
|
-
if ! command -v jq
|
|
233
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
242
234
|
error "jq is required for fleet visualization"
|
|
243
235
|
exit 1
|
|
244
236
|
fi
|
|
@@ -281,7 +273,7 @@ show_queue() {
|
|
|
281
273
|
|
|
282
274
|
# ─── Costs Subcommand ──────────────────────────────────────────────────────
|
|
283
275
|
show_costs() {
|
|
284
|
-
if ! command -v jq
|
|
276
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
285
277
|
error "jq is required for fleet visualization"
|
|
286
278
|
exit 1
|
|
287
279
|
fi
|
|
@@ -323,7 +315,7 @@ show_costs() {
|
|
|
323
315
|
|
|
324
316
|
# ─── Export Subcommand ─────────────────────────────────────────────────────
|
|
325
317
|
show_export() {
|
|
326
|
-
if ! command -v jq
|
|
318
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
327
319
|
error "jq is required for fleet visualization"
|
|
328
320
|
exit 1
|
|
329
321
|
fi
|
package/scripts/sw-fleet.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -34,16 +34,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
34
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
35
|
}
|
|
36
36
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
37
|
epoch_to_iso() {
|
|
48
38
|
local epoch="$1"
|
|
49
39
|
date -u -r "$epoch" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || \
|
|
@@ -200,7 +190,7 @@ _fleet_repo_priority() {
|
|
|
200
190
|
local repo_path="$1"
|
|
201
191
|
local priority=50 # default neutral priority
|
|
202
192
|
|
|
203
|
-
type _gh_detect_repo
|
|
193
|
+
type _gh_detect_repo >/dev/null 2>&1 || { echo "$priority"; return 0; }
|
|
204
194
|
|
|
205
195
|
# Detect repo from the repo path (run in subshell to avoid cd side-effects)
|
|
206
196
|
local gh_priority
|
|
@@ -213,7 +203,7 @@ _fleet_repo_priority() {
|
|
|
213
203
|
local p=50
|
|
214
204
|
|
|
215
205
|
# Factor: security alerts (urgent work)
|
|
216
|
-
if type gh_security_alerts
|
|
206
|
+
if type gh_security_alerts >/dev/null 2>&1; then
|
|
217
207
|
local alerts
|
|
218
208
|
alerts=$(gh_security_alerts "$owner" "$repo" 2>/dev/null | jq 'length' 2>/dev/null || echo "0")
|
|
219
209
|
if [[ "${alerts:-0}" -gt 5 ]]; then
|
|
@@ -224,7 +214,7 @@ _fleet_repo_priority() {
|
|
|
224
214
|
fi
|
|
225
215
|
|
|
226
216
|
# Factor: contributor count (more contributors = more active = higher priority)
|
|
227
|
-
if type gh_contributors
|
|
217
|
+
if type gh_contributors >/dev/null 2>&1; then
|
|
228
218
|
local contribs
|
|
229
219
|
contribs=$(gh_contributors "$owner" "$repo" 2>/dev/null | jq 'length' 2>/dev/null || echo "0")
|
|
230
220
|
if [[ "${contribs:-0}" -gt 10 ]]; then
|
|
@@ -643,6 +633,12 @@ check_machine_health() {
|
|
|
643
633
|
emit_event "fleet.machine_offline" "machine=$name" "host=$host"
|
|
644
634
|
fi
|
|
645
635
|
done
|
|
636
|
+
|
|
637
|
+
# After health checks: trigger failover to re-queue work from offline machines
|
|
638
|
+
if [[ -f "$SCRIPT_DIR/lib/fleet-failover.sh" ]]; then
|
|
639
|
+
source "$SCRIPT_DIR/lib/fleet-failover.sh" 2>/dev/null || true
|
|
640
|
+
fleet_failover_check 2>/dev/null || true
|
|
641
|
+
fi
|
|
646
642
|
}
|
|
647
643
|
|
|
648
644
|
# ─── Cross-Machine Event Aggregation ───────────────────────────────────
|
|
@@ -749,12 +745,12 @@ fleet_start() {
|
|
|
749
745
|
echo -e "${PURPLE}${BOLD}━━━ shipwright fleet v${VERSION} — start ━━━${RESET}"
|
|
750
746
|
echo ""
|
|
751
747
|
|
|
752
|
-
if ! command -v tmux
|
|
748
|
+
if ! command -v tmux >/dev/null 2>&1; then
|
|
753
749
|
error "tmux is required for fleet mode"
|
|
754
750
|
exit 1
|
|
755
751
|
fi
|
|
756
752
|
|
|
757
|
-
if ! command -v jq
|
|
753
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
758
754
|
error "jq is required. Install: brew install jq"
|
|
759
755
|
exit 1
|
|
760
756
|
fi
|
|
@@ -1146,7 +1142,7 @@ fleet_metrics() {
|
|
|
1146
1142
|
exit 1
|
|
1147
1143
|
fi
|
|
1148
1144
|
|
|
1149
|
-
if ! command -v jq
|
|
1145
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
1150
1146
|
error "jq is required. Install: brew install jq"
|
|
1151
1147
|
exit 1
|
|
1152
1148
|
fi
|
package/scripts/sw-github-app.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -34,16 +34,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
34
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
35
|
}
|
|
36
36
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
37
|
# ─── Config File Locations ────────────────────────────────────────────────
|
|
48
38
|
CONFIG_DIR="${HOME}/.shipwright"
|
|
49
39
|
CONFIG_FILE="${CONFIG_DIR}/github-app.json"
|
|
@@ -76,16 +66,16 @@ cmd_setup() {
|
|
|
76
66
|
info "GitHub App Configuration"
|
|
77
67
|
echo ""
|
|
78
68
|
|
|
79
|
-
read -
|
|
80
|
-
read -
|
|
69
|
+
read -rp "App ID: " app_id
|
|
70
|
+
read -rp "Private key file path: " key_path
|
|
81
71
|
|
|
82
72
|
if [[ ! -f "$key_path" ]]; then
|
|
83
73
|
error "Private key file not found: $key_path"
|
|
84
74
|
return 1
|
|
85
75
|
fi
|
|
86
76
|
|
|
87
|
-
read -
|
|
88
|
-
read -
|
|
77
|
+
read -rp "Installation ID: " installation_id
|
|
78
|
+
read -rp "Webhook secret (optional, press Enter to skip): " webhook_secret
|
|
89
79
|
|
|
90
80
|
# Create config atomically
|
|
91
81
|
local tmp_config
|
|
@@ -171,7 +161,7 @@ _get_installation_token() {
|
|
|
171
161
|
fi
|
|
172
162
|
|
|
173
163
|
local response
|
|
174
|
-
response=$(curl -s -H "Authorization: Bearer $jwt" \
|
|
164
|
+
response=$(curl -s --connect-timeout 10 --max-time 30 -H "Authorization: Bearer $jwt" \
|
|
175
165
|
-H "Accept: application/vnd.github+json" \
|
|
176
166
|
"https://api.github.com/app/installations/${installation_id}/access_tokens" \
|
|
177
167
|
-d '{}' -X POST 2>/dev/null) || true
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
11
11
|
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
12
12
|
|
|
@@ -34,16 +34,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
34
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
35
|
}
|
|
36
36
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
37
|
# ─── Artifacts Directory ─────────────────────────────────────────────────────
|
|
48
38
|
ARTIFACTS_DIR="${REPO_DIR}/.claude/pipeline-artifacts"
|
|
49
39
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -34,16 +34,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
34
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
35
|
}
|
|
36
36
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
37
|
# ─── Artifacts Directory ─────────────────────────────────────────────────────
|
|
48
38
|
ARTIFACTS_DIR="${REPO_DIR}/.claude/pipeline-artifacts"
|
|
49
39
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -34,16 +34,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
34
34
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
35
|
}
|
|
36
36
|
fi
|
|
37
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
38
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
39
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
40
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
41
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
42
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
43
|
-
DIM="${DIM:-\033[2m}"
|
|
44
|
-
BOLD="${BOLD:-\033[1m}"
|
|
45
|
-
RESET="${RESET:-\033[0m}"
|
|
46
|
-
|
|
47
37
|
# ─── Structured Event Log ──────────────────────────────────────────────────
|
|
48
38
|
EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
|
|
49
39
|
|
|
@@ -87,7 +77,7 @@ _gh_cache_get() {
|
|
|
87
77
|
# Check file age
|
|
88
78
|
local file_epoch now
|
|
89
79
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
90
|
-
file_epoch=$(
|
|
80
|
+
file_epoch=$(file_mtime "$cache_file")
|
|
91
81
|
else
|
|
92
82
|
file_epoch=$(stat -c '%Y' "$cache_file" 2>/dev/null || echo "0")
|
|
93
83
|
fi
|
package/scripts/sw-guild.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -33,16 +33,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
33
33
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
34
34
|
}
|
|
35
35
|
fi
|
|
36
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
37
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
38
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
39
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
40
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
41
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
42
|
-
DIM="${DIM:-\033[2m}"
|
|
43
|
-
BOLD="${BOLD:-\033[1m}"
|
|
44
|
-
RESET="${RESET:-\033[0m}"
|
|
45
|
-
|
|
46
36
|
# ─── Guild Storage Paths ───────────────────────────────────────────────────
|
|
47
37
|
GUILD_ROOT="${HOME}/.shipwright/guilds"
|
|
48
38
|
GUILD_CONFIG="${GUILD_ROOT}/config.json"
|
package/scripts/sw-heartbeat.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="
|
|
9
|
+
VERSION="3.0.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -16,6 +16,10 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
16
16
|
# Canonical helpers (colors, output, events)
|
|
17
17
|
# shellcheck source=lib/helpers.sh
|
|
18
18
|
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
|
|
19
|
+
|
|
20
|
+
# SQLite persistence (DB as primary read path)
|
|
21
|
+
# shellcheck source=sw-db.sh
|
|
22
|
+
[[ -f "$SCRIPT_DIR/sw-db.sh" ]] && source "$SCRIPT_DIR/sw-db.sh"
|
|
19
23
|
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
|
|
20
24
|
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
|
|
21
25
|
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
|
|
@@ -33,16 +37,6 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
33
37
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
34
38
|
}
|
|
35
39
|
fi
|
|
36
|
-
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
37
|
-
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
38
|
-
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
39
|
-
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
40
|
-
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
41
|
-
RED="${RED:-\033[38;2;248;113;113m}"
|
|
42
|
-
DIM="${DIM:-\033[2m}"
|
|
43
|
-
BOLD="${BOLD:-\033[1m}"
|
|
44
|
-
RESET="${RESET:-\033[0m}"
|
|
45
|
-
|
|
46
40
|
# ─── Constants ──────────────────────────────────────────────────────────────
|
|
47
41
|
HEARTBEAT_DIR="$HOME/.shipwright/heartbeats"
|
|
48
42
|
|
|
@@ -167,6 +161,11 @@ cmd_write() {
|
|
|
167
161
|
|
|
168
162
|
# Atomic write
|
|
169
163
|
mv "$tmp_file" "${HEARTBEAT_DIR}/${job_id}.json"
|
|
164
|
+
|
|
165
|
+
# Dual-write to DB when available
|
|
166
|
+
if type db_record_heartbeat >/dev/null 2>&1 && db_available 2>/dev/null; then
|
|
167
|
+
db_record_heartbeat "$job_id" "$pid" "${issue:-0}" "$stage" "${iteration:-0}" "$activity" "$memory_mb" 2>/dev/null || true
|
|
168
|
+
fi
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
# ─── Check Heartbeat ───────────────────────────────────────────────────────
|
|
@@ -190,6 +189,30 @@ cmd_check() {
|
|
|
190
189
|
esac
|
|
191
190
|
done
|
|
192
191
|
|
|
192
|
+
# Try DB first when available
|
|
193
|
+
if type db_list_heartbeats >/dev/null 2>&1 && db_available 2>/dev/null; then
|
|
194
|
+
local hb_json
|
|
195
|
+
hb_json=$(db_list_heartbeats 2>/dev/null | jq -r --arg id "$job_id" '.[] | select(.job_id == $id) | .updated_at' 2>/dev/null || true)
|
|
196
|
+
if [[ -n "$hb_json" ]]; then
|
|
197
|
+
local updated_at="$hb_json"
|
|
198
|
+
local hb_epoch now_epoch age_secs
|
|
199
|
+
if TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$updated_at" +%s >/dev/null 2>&1; then
|
|
200
|
+
hb_epoch="$(TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$updated_at" +%s 2>/dev/null)"
|
|
201
|
+
else
|
|
202
|
+
hb_epoch="$(date -d "$updated_at" +%s 2>/dev/null || echo 0)"
|
|
203
|
+
fi
|
|
204
|
+
now_epoch="$(date +%s)"
|
|
205
|
+
age_secs=$((now_epoch - hb_epoch))
|
|
206
|
+
if [[ "$age_secs" -le "$timeout" ]]; then
|
|
207
|
+
success "Job ${job_id} alive (${age_secs}s ago)"
|
|
208
|
+
return 0
|
|
209
|
+
else
|
|
210
|
+
warn "Job ${job_id} stale (${age_secs}s ago, timeout: ${timeout}s)"
|
|
211
|
+
return 1
|
|
212
|
+
fi
|
|
213
|
+
fi
|
|
214
|
+
fi
|
|
215
|
+
|
|
193
216
|
local hb_file="${HEARTBEAT_DIR}/${job_id}.json"
|
|
194
217
|
|
|
195
218
|
if [[ ! -f "$hb_file" ]]; then
|
|
@@ -209,7 +232,7 @@ cmd_check() {
|
|
|
209
232
|
local hb_epoch now_epoch age_secs
|
|
210
233
|
|
|
211
234
|
# macOS date -j -f vs GNU date -d (TZ=UTC since timestamps are UTC)
|
|
212
|
-
if TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$updated_at" +%s
|
|
235
|
+
if TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$updated_at" +%s >/dev/null 2>&1; then
|
|
213
236
|
hb_epoch="$(TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$updated_at" +%s 2>/dev/null)"
|
|
214
237
|
else
|
|
215
238
|
hb_epoch="$(date -d "$updated_at" +%s 2>/dev/null || echo 0)"
|
|
@@ -231,6 +254,16 @@ cmd_check() {
|
|
|
231
254
|
cmd_list() {
|
|
232
255
|
ensure_dir
|
|
233
256
|
|
|
257
|
+
# Try DB first when available
|
|
258
|
+
if type db_list_heartbeats >/dev/null 2>&1 && db_available 2>/dev/null; then
|
|
259
|
+
local db_result
|
|
260
|
+
db_result=$(db_list_heartbeats 2>/dev/null || echo "[]")
|
|
261
|
+
if [[ -n "$db_result" ]] && echo "$db_result" | jq -e 'length > 0' >/dev/null 2>&1; then
|
|
262
|
+
echo "$db_result" | jq -c '[.[] | . + {cpu_pct: 0}]' 2>/dev/null || echo "[]"
|
|
263
|
+
return 0
|
|
264
|
+
fi
|
|
265
|
+
fi
|
|
266
|
+
|
|
234
267
|
local result="["
|
|
235
268
|
local first=true
|
|
236
269
|
|
|
@@ -272,6 +305,10 @@ cmd_clear() {
|
|
|
272
305
|
|
|
273
306
|
local hb_file="${HEARTBEAT_DIR}/${job_id}.json"
|
|
274
307
|
|
|
308
|
+
if type db_clear_heartbeat >/dev/null 2>&1 && db_available 2>/dev/null; then
|
|
309
|
+
db_clear_heartbeat "$job_id" 2>/dev/null || true
|
|
310
|
+
fi
|
|
311
|
+
|
|
275
312
|
if [[ -f "$hb_file" ]]; then
|
|
276
313
|
rm -f "$hb_file"
|
|
277
314
|
success "Cleared heartbeat for job: ${job_id}"
|