shipwright-cli 3.0.0 → 3.2.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 +21 -7
- package/completions/_shipwright +247 -93
- package/completions/shipwright.bash +69 -15
- package/completions/shipwright.fish +309 -41
- package/config/decision-tiers.json +55 -0
- package/config/defaults.json +25 -2
- package/config/event-schema.json +142 -5
- package/config/policy.json +8 -0
- package/dashboard/public/index.html +6 -0
- package/dashboard/public/styles.css +76 -0
- package/dashboard/server.ts +51 -0
- package/dashboard/src/core/api.ts +5 -0
- package/dashboard/src/types/api.ts +10 -0
- package/dashboard/src/views/metrics.ts +69 -1
- package/package.json +3 -3
- package/scripts/lib/architecture.sh +2 -1
- package/scripts/lib/bootstrap.sh +0 -0
- package/scripts/lib/config.sh +0 -0
- package/scripts/lib/daemon-adaptive.sh +4 -2
- package/scripts/lib/daemon-dispatch.sh +24 -1
- package/scripts/lib/daemon-failure.sh +0 -0
- package/scripts/lib/daemon-health.sh +0 -0
- package/scripts/lib/daemon-patrol.sh +42 -7
- package/scripts/lib/daemon-poll.sh +17 -0
- package/scripts/lib/daemon-state.sh +17 -0
- package/scripts/lib/daemon-triage.sh +1 -1
- package/scripts/lib/decide-autonomy.sh +295 -0
- package/scripts/lib/decide-scoring.sh +228 -0
- package/scripts/lib/decide-signals.sh +462 -0
- package/scripts/lib/fleet-failover.sh +0 -0
- package/scripts/lib/helpers.sh +19 -18
- package/scripts/lib/pipeline-detection.sh +1 -1
- package/scripts/lib/pipeline-github.sh +0 -0
- package/scripts/lib/pipeline-intelligence.sh +23 -4
- package/scripts/lib/pipeline-quality-checks.sh +11 -6
- package/scripts/lib/pipeline-quality.sh +0 -0
- package/scripts/lib/pipeline-stages.sh +330 -33
- package/scripts/lib/pipeline-state.sh +14 -0
- package/scripts/lib/policy.sh +0 -0
- package/scripts/lib/test-helpers.sh +0 -0
- package/scripts/postinstall.mjs +75 -1
- package/scripts/signals/example-collector.sh +36 -0
- package/scripts/sw +8 -4
- package/scripts/sw-activity.sh +1 -7
- package/scripts/sw-adaptive.sh +7 -7
- package/scripts/sw-adversarial.sh +1 -1
- package/scripts/sw-architecture-enforcer.sh +1 -1
- package/scripts/sw-auth.sh +1 -1
- package/scripts/sw-autonomous.sh +1 -1
- package/scripts/sw-changelog.sh +1 -1
- package/scripts/sw-checkpoint.sh +1 -1
- package/scripts/sw-ci.sh +11 -6
- package/scripts/sw-cleanup.sh +1 -1
- package/scripts/sw-code-review.sh +36 -17
- package/scripts/sw-connect.sh +1 -1
- package/scripts/sw-context.sh +1 -1
- package/scripts/sw-cost.sh +71 -5
- package/scripts/sw-daemon.sh +6 -3
- package/scripts/sw-dashboard.sh +1 -1
- package/scripts/sw-db.sh +53 -38
- package/scripts/sw-decide.sh +685 -0
- package/scripts/sw-decompose.sh +1 -1
- package/scripts/sw-deps.sh +1 -1
- package/scripts/sw-developer-simulation.sh +1 -1
- package/scripts/sw-discovery.sh +80 -4
- package/scripts/sw-doc-fleet.sh +1 -1
- package/scripts/sw-docs-agent.sh +1 -1
- package/scripts/sw-docs.sh +1 -1
- package/scripts/sw-doctor.sh +1 -1
- package/scripts/sw-dora.sh +1 -1
- package/scripts/sw-durable.sh +9 -5
- package/scripts/sw-e2e-orchestrator.sh +1 -1
- package/scripts/sw-eventbus.sh +7 -4
- package/scripts/sw-evidence.sh +1 -1
- package/scripts/sw-feedback.sh +1 -1
- package/scripts/sw-fix.sh +1 -1
- package/scripts/sw-fleet-discover.sh +1 -1
- package/scripts/sw-fleet-viz.sh +6 -4
- package/scripts/sw-fleet.sh +1 -1
- package/scripts/sw-github-app.sh +3 -2
- 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 +1 -1
- package/scripts/sw-heartbeat.sh +1 -1
- package/scripts/sw-hygiene.sh +5 -3
- package/scripts/sw-incident.sh +9 -5
- package/scripts/sw-init.sh +1 -1
- package/scripts/sw-instrument.sh +1 -1
- package/scripts/sw-intelligence.sh +11 -6
- package/scripts/sw-jira.sh +1 -1
- package/scripts/sw-launchd.sh +1 -1
- package/scripts/sw-linear.sh +1 -1
- package/scripts/sw-logs.sh +1 -1
- package/scripts/sw-loop.sh +338 -32
- package/scripts/sw-memory.sh +23 -6
- package/scripts/sw-mission-control.sh +1 -1
- package/scripts/sw-model-router.sh +3 -2
- package/scripts/sw-otel.sh +8 -4
- package/scripts/sw-oversight.sh +1 -1
- package/scripts/sw-pipeline-composer.sh +3 -1
- package/scripts/sw-pipeline-vitals.sh +11 -6
- package/scripts/sw-pipeline.sh +92 -8
- package/scripts/sw-pm.sh +5 -4
- package/scripts/sw-pr-lifecycle.sh +7 -4
- package/scripts/sw-predictive.sh +11 -5
- package/scripts/sw-prep.sh +1 -1
- package/scripts/sw-ps.sh +1 -1
- package/scripts/sw-public-dashboard.sh +3 -2
- package/scripts/sw-quality.sh +21 -10
- package/scripts/sw-reaper.sh +1 -1
- package/scripts/sw-recruit.sh +1 -1
- package/scripts/sw-regression.sh +1 -1
- package/scripts/sw-release-manager.sh +1 -1
- package/scripts/sw-release.sh +1 -1
- package/scripts/sw-remote.sh +1 -1
- package/scripts/sw-replay.sh +1 -1
- package/scripts/sw-retro.sh +1 -1
- package/scripts/sw-review-rerun.sh +1 -1
- package/scripts/sw-scale.sh +69 -11
- package/scripts/sw-security-audit.sh +1 -1
- package/scripts/sw-self-optimize.sh +168 -4
- package/scripts/sw-session.sh +3 -3
- package/scripts/sw-setup.sh +1 -1
- package/scripts/sw-standup.sh +1 -1
- package/scripts/sw-status.sh +1 -1
- package/scripts/sw-strategic.sh +11 -6
- package/scripts/sw-stream.sh +7 -4
- package/scripts/sw-swarm.sh +3 -2
- package/scripts/sw-team-stages.sh +1 -1
- package/scripts/sw-templates.sh +3 -3
- package/scripts/sw-testgen.sh +11 -6
- package/scripts/sw-tmux-pipeline.sh +1 -1
- package/scripts/sw-tmux.sh +35 -1
- package/scripts/sw-trace.sh +1 -1
- package/scripts/sw-tracker.sh +1 -1
- package/scripts/sw-triage.sh +7 -7
- package/scripts/sw-upgrade.sh +1 -1
- package/scripts/sw-ux.sh +1 -1
- package/scripts/sw-webhook.sh +3 -2
- package/scripts/sw-widgets.sh +7 -4
- package/scripts/sw-worktree.sh +1 -1
- package/scripts/update-homebrew-sha.sh +21 -15
package/scripts/sw-deps.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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
package/scripts/sw-discovery.sh
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
9
9
|
|
|
10
|
-
VERSION="3.
|
|
10
|
+
VERSION="3.2.0"
|
|
11
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
12
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
13
13
|
|
|
@@ -46,6 +46,13 @@ DISCOVERIES_FILE="${HOME}/.shipwright/discoveries.jsonl"
|
|
|
46
46
|
DISCOVERIES_DIR="${HOME}/.shipwright/discoveries"
|
|
47
47
|
DISCOVERY_TTL_SECS=$((24 * 60 * 60)) # 24 hours default
|
|
48
48
|
|
|
49
|
+
# ─── Remote Discovery Server (optional) ─────────────────────────────────────
|
|
50
|
+
# Set via env var or daemon-config.json: "discovery_server_url"
|
|
51
|
+
DISCOVERY_SERVER_URL="${DISCOVERY_SERVER_URL:-}"
|
|
52
|
+
if [[ -z "$DISCOVERY_SERVER_URL" && -f ".claude/daemon-config.json" ]]; then
|
|
53
|
+
DISCOVERY_SERVER_URL=$(jq -r '.discovery_server_url // ""' ".claude/daemon-config.json" 2>/dev/null || true)
|
|
54
|
+
fi
|
|
55
|
+
|
|
49
56
|
ensure_discoveries_dir() {
|
|
50
57
|
mkdir -p "$DISCOVERIES_DIR"
|
|
51
58
|
}
|
|
@@ -82,6 +89,15 @@ broadcast_discovery() {
|
|
|
82
89
|
|
|
83
90
|
echo "$entry" >> "$DISCOVERIES_FILE"
|
|
84
91
|
type rotate_jsonl >/dev/null 2>&1 && rotate_jsonl "$DISCOVERIES_FILE" 5000
|
|
92
|
+
|
|
93
|
+
# Fire-and-forget POST to remote discovery server if configured
|
|
94
|
+
if [[ -n "${DISCOVERY_SERVER_URL:-}" ]]; then
|
|
95
|
+
curl -sS -X POST "${DISCOVERY_SERVER_URL}/api/discoveries" \
|
|
96
|
+
-H "Content-Type: application/json" \
|
|
97
|
+
-d "$entry" \
|
|
98
|
+
--max-time 5 >/dev/null 2>&1 &
|
|
99
|
+
fi
|
|
100
|
+
|
|
85
101
|
success "Broadcast discovery: ${category} (${file_patterns})"
|
|
86
102
|
}
|
|
87
103
|
|
|
@@ -93,6 +109,16 @@ query_discoveries() {
|
|
|
93
109
|
|
|
94
110
|
ensure_discoveries_dir
|
|
95
111
|
|
|
112
|
+
# Merge remote discoveries if server configured (best-effort)
|
|
113
|
+
if [[ -n "${DISCOVERY_SERVER_URL:-}" ]]; then
|
|
114
|
+
local remote_results
|
|
115
|
+
remote_results=$(curl -sS "${DISCOVERY_SERVER_URL}/api/discoveries?patterns=${file_patterns}" \
|
|
116
|
+
--max-time 5 2>/dev/null || true)
|
|
117
|
+
if [[ -n "$remote_results" ]] && echo "$remote_results" | jq -e '.' >/dev/null 2>&1; then
|
|
118
|
+
echo "$remote_results" | jq -cr '.[]' >> "$DISCOVERIES_FILE" 2>/dev/null || true
|
|
119
|
+
fi
|
|
120
|
+
fi
|
|
121
|
+
|
|
96
122
|
[[ ! -f "$DISCOVERIES_FILE" ]] && {
|
|
97
123
|
info "No discoveries yet"
|
|
98
124
|
return 0
|
|
@@ -130,10 +156,60 @@ query_discoveries() {
|
|
|
130
156
|
fi
|
|
131
157
|
done < "$DISCOVERIES_FILE"
|
|
132
158
|
|
|
133
|
-
#
|
|
159
|
+
# Use Claude to rank candidates by relevance when there are many
|
|
134
160
|
if [[ "${INTELLIGENCE_ENABLED:-auto}" != "false" ]] && command -v claude &>/dev/null 2>&1 && [[ ${#candidates[@]} -gt 5 ]]; then
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
local ranked_json=""
|
|
162
|
+
local candidate_summaries=""
|
|
163
|
+
local idx=0
|
|
164
|
+
for line in "${candidates[@]+"${candidates[@]}"}"; do
|
|
165
|
+
local disc cat_name
|
|
166
|
+
disc=$(echo "$line" | jq -r '.discovery // ""' 2>/dev/null || echo "")
|
|
167
|
+
cat_name=$(echo "$line" | jq -r '.category // ""' 2>/dev/null || echo "")
|
|
168
|
+
candidate_summaries="${candidate_summaries}${idx}: [${cat_name}] ${disc}"$'\n'
|
|
169
|
+
idx=$((idx + 1))
|
|
170
|
+
done
|
|
171
|
+
|
|
172
|
+
local rank_prompt
|
|
173
|
+
rank_prompt="Given these discoveries and the query context '${query_context}', return a JSON array of indices sorted by relevance (most relevant first). Only return the JSON array, no explanation.
|
|
174
|
+
|
|
175
|
+
Discoveries:
|
|
176
|
+
${candidate_summaries}"
|
|
177
|
+
|
|
178
|
+
local _claude_timeout
|
|
179
|
+
_claude_timeout=30
|
|
180
|
+
local _timeout_cmd=""
|
|
181
|
+
if command -v gtimeout >/dev/null 2>&1; then _timeout_cmd="gtimeout $_claude_timeout"
|
|
182
|
+
elif command -v timeout >/dev/null 2>&1; then _timeout_cmd="timeout $_claude_timeout"
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
ranked_json=$($_timeout_cmd claude -p "$rank_prompt" 2>/dev/null || true)
|
|
186
|
+
|
|
187
|
+
# Extract array from response (handle markdown fences)
|
|
188
|
+
local indices_str=""
|
|
189
|
+
if [[ -n "$ranked_json" ]]; then
|
|
190
|
+
indices_str=$(echo "$ranked_json" | sed -n 's/.*\(\[[ 0-9,]*\]\).*/\1/p' | head -1)
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
if [[ -n "$indices_str" ]] && echo "$indices_str" | jq -e 'type == "array"' >/dev/null 2>&1; then
|
|
194
|
+
local reordered=()
|
|
195
|
+
local seen=""
|
|
196
|
+
while IFS= read -r rank_idx; do
|
|
197
|
+
[[ -z "$rank_idx" ]] && continue
|
|
198
|
+
if [[ "$rank_idx" -ge 0 && "$rank_idx" -lt "${#candidates[@]}" ]]; then
|
|
199
|
+
# Avoid duplicates
|
|
200
|
+
case " $seen " in *" $rank_idx "*) continue ;; esac
|
|
201
|
+
seen="$seen $rank_idx"
|
|
202
|
+
reordered+=("${candidates[$rank_idx]}")
|
|
203
|
+
fi
|
|
204
|
+
done < <(echo "$indices_str" | jq -r '.[]' 2>/dev/null)
|
|
205
|
+
# Append any candidates not in the ranking
|
|
206
|
+
idx=0
|
|
207
|
+
for line in "${candidates[@]+"${candidates[@]}"}"; do
|
|
208
|
+
case " $seen " in *" $idx "*) ;; *) reordered+=("$line") ;; esac
|
|
209
|
+
idx=$((idx + 1))
|
|
210
|
+
done
|
|
211
|
+
candidates=("${reordered[@]+"${reordered[@]}"}")
|
|
212
|
+
fi
|
|
137
213
|
fi
|
|
138
214
|
|
|
139
215
|
# Output up to limit
|
package/scripts/sw-doc-fleet.sh
CHANGED
package/scripts/sw-docs-agent.sh
CHANGED
package/scripts/sw-docs.sh
CHANGED
package/scripts/sw-doctor.sh
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# ║ ║
|
|
5
5
|
# ║ Checks prerequisites, installed files, PATH, and common issues. ║
|
|
6
6
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
7
|
-
VERSION="3.
|
|
7
|
+
VERSION="3.2.0"
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
10
10
|
|
package/scripts/sw-dora.sh
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
10
10
|
|
|
11
|
-
VERSION="3.
|
|
11
|
+
VERSION="3.2.0"
|
|
12
12
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
13
|
|
|
14
14
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
package/scripts/sw-durable.sh
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
9
9
|
|
|
10
|
-
VERSION="3.
|
|
10
|
+
VERSION="3.2.0"
|
|
11
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
12
|
|
|
13
13
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -481,17 +481,21 @@ cmd_status() {
|
|
|
481
481
|
locks_dir="${DURABLE_DIR}/locks"
|
|
482
482
|
|
|
483
483
|
local log_events log_size
|
|
484
|
-
log_events=$(wc -l < "$log_file" 2>/dev/null ||
|
|
484
|
+
log_events=$(wc -l < "$log_file" 2>/dev/null || true)
|
|
485
|
+
log_events="${log_events:-0}"
|
|
485
486
|
log_size=$(du -h "$log_file" 2>/dev/null | awk '{print $1}' || echo "0")
|
|
486
487
|
|
|
487
488
|
local dlq_events
|
|
488
|
-
dlq_events=$(wc -l < "$dlq_file" 2>/dev/null ||
|
|
489
|
+
dlq_events=$(wc -l < "$dlq_file" 2>/dev/null || true)
|
|
490
|
+
dlq_events="${dlq_events:-0}"
|
|
489
491
|
|
|
490
492
|
local consumer_count
|
|
491
|
-
consumer_count=$(find "$offsets_dir" -name "consumer-*.offset" 2>/dev/null | wc -l ||
|
|
493
|
+
consumer_count=$(find "$offsets_dir" -name "consumer-*.offset" 2>/dev/null | wc -l || true)
|
|
494
|
+
consumer_count="${consumer_count:-0}"
|
|
492
495
|
|
|
493
496
|
local active_locks
|
|
494
|
-
active_locks=$(find "$locks_dir" -type d -mindepth 1 2>/dev/null | wc -l ||
|
|
497
|
+
active_locks=$(find "$locks_dir" -type d -mindepth 1 2>/dev/null | wc -l || true)
|
|
498
|
+
active_locks="${active_locks:-0}"
|
|
495
499
|
|
|
496
500
|
echo ""
|
|
497
501
|
echo -e "${CYAN}${BOLD} Durable Workflow Status${RESET} ${DIM}v${VERSION}${RESET}"
|
package/scripts/sw-eventbus.sh
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
9
9
|
|
|
10
|
-
VERSION="3.
|
|
10
|
+
VERSION="3.2.0"
|
|
11
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
12
|
|
|
13
13
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -251,7 +251,8 @@ cmd_status() {
|
|
|
251
251
|
fi
|
|
252
252
|
elif [[ -f "$EVENTS_FILE" ]]; then
|
|
253
253
|
local total_events last_event_ts
|
|
254
|
-
total_events=$(wc -l < "$EVENTS_FILE" ||
|
|
254
|
+
total_events=$(wc -l < "$EVENTS_FILE" || true)
|
|
255
|
+
total_events="${total_events:-0}"
|
|
255
256
|
last_event_ts=$(tail -1 "$EVENTS_FILE" | jq -r '.ts // "never"' 2>/dev/null || echo "never")
|
|
256
257
|
echo -e " ${CYAN}Event Store:${RESET} $EVENTS_FILE (file fallback)"
|
|
257
258
|
echo -e " ${CYAN}Total Events:${RESET} ${BOLD}${total_events}${RESET}"
|
|
@@ -290,7 +291,8 @@ cmd_clean() {
|
|
|
290
291
|
elif [[ -f "$EVENTS_FILE" ]]; then
|
|
291
292
|
info "Cleaning events older than ${ttl_days} days..."
|
|
292
293
|
local old_count tmp_file new_count removed
|
|
293
|
-
old_count=$(grep -c "ts" "$EVENTS_FILE" 2>/dev/null ||
|
|
294
|
+
old_count=$(grep -c "ts" "$EVENTS_FILE" 2>/dev/null || true)
|
|
295
|
+
old_count="${old_count:-0}"
|
|
294
296
|
tmp_file="$(mktemp)"
|
|
295
297
|
while IFS= read -r line; do
|
|
296
298
|
[[ -z "$line" ]] && continue
|
|
@@ -299,7 +301,8 @@ cmd_clean() {
|
|
|
299
301
|
[[ -n "$ts" && "$ts" > "$cutoff_iso" ]] && echo "$line" >> "$tmp_file"
|
|
300
302
|
done < "$EVENTS_FILE"
|
|
301
303
|
mv "$tmp_file" "$EVENTS_FILE"
|
|
302
|
-
new_count=$(wc -l < "$EVENTS_FILE" ||
|
|
304
|
+
new_count=$(wc -l < "$EVENTS_FILE" || true)
|
|
305
|
+
new_count="${new_count:-0}"
|
|
303
306
|
removed=$((old_count - new_count))
|
|
304
307
|
success "Removed $removed old events. Remaining: $new_count"
|
|
305
308
|
else
|
package/scripts/sw-evidence.sh
CHANGED
package/scripts/sw-feedback.sh
CHANGED
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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -176,7 +176,7 @@ show_workers() {
|
|
|
176
176
|
echo -e "${BOLD}Remote Machines:${RESET}"
|
|
177
177
|
echo ""
|
|
178
178
|
|
|
179
|
-
if jq '.machines[]?' "$MACHINES_FILE" 2>/dev/null | grep -q
|
|
179
|
+
if jq '.machines[]?' "$MACHINES_FILE" 2>/dev/null | grep -q . 2>/dev/null; then
|
|
180
180
|
jq -r '.machines[]? | "\(.name) (\(.hostname)) — \(.status) — \(.active_jobs // 0) active"' "$MACHINES_FILE" 2>/dev/null | while read -r machine; do
|
|
181
181
|
echo -e " ${machine}"
|
|
182
182
|
done
|
|
@@ -205,8 +205,10 @@ show_insights() {
|
|
|
205
205
|
|
|
206
206
|
# Fleet-wide success rate (last 30 days)
|
|
207
207
|
local total_pipelines successful_pipelines
|
|
208
|
-
total_pipelines=$(grep '"type":"pipeline.completed"' "$EVENTS_FILE" 2>/dev/null | tail -5000 | wc -l ||
|
|
209
|
-
|
|
208
|
+
total_pipelines=$(grep '"type":"pipeline.completed"' "$EVENTS_FILE" 2>/dev/null | tail -5000 | wc -l || true)
|
|
209
|
+
total_pipelines="${total_pipelines:-0}"
|
|
210
|
+
successful_pipelines=$(grep '"type":"pipeline.completed".*"status":"success"' "$EVENTS_FILE" 2>/dev/null | tail -5000 | wc -l || true)
|
|
211
|
+
successful_pipelines="${successful_pipelines:-0}"
|
|
210
212
|
|
|
211
213
|
local success_rate=0
|
|
212
214
|
if [[ "$total_pipelines" -gt 0 ]]; then
|
package/scripts/sw-fleet.sh
CHANGED
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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -454,7 +454,8 @@ cmd_status() {
|
|
|
454
454
|
# Show recent webhook events
|
|
455
455
|
if [[ -f "$WEBHOOK_LOG" ]]; then
|
|
456
456
|
local count
|
|
457
|
-
count=$(wc -l < "$WEBHOOK_LOG" 2>/dev/null ||
|
|
457
|
+
count=$(wc -l < "$WEBHOOK_LOG" 2>/dev/null || true)
|
|
458
|
+
count="${count:-0}"
|
|
458
459
|
if [[ "$count" -gt 0 ]]; then
|
|
459
460
|
echo -e "${BOLD}Recent Webhook Events (last 10):${RESET}"
|
|
460
461
|
tail -10 "$WEBHOOK_LOG" | jq '{timestamp, event_type}' -c
|
|
@@ -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="3.
|
|
9
|
+
VERSION="3.2.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
|
|
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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
package/scripts/sw-hygiene.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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -103,7 +103,8 @@ detect_dead_code() {
|
|
|
103
103
|
|
|
104
104
|
# Check if function is used in other files (count lines with this function name)
|
|
105
105
|
local usage_count
|
|
106
|
-
usage_count=$(grep -r "$func" "$REPO_DIR/scripts" --include="*.sh" 2>/dev/null | wc -l
|
|
106
|
+
usage_count=$(grep -r "$func" "$REPO_DIR/scripts" --include="*.sh" 2>/dev/null | wc -l || true)
|
|
107
|
+
usage_count="${usage_count:-0}"
|
|
107
108
|
usage_count=$(printf '%s' "$usage_count" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
108
109
|
|
|
109
110
|
# Function definition counts as 1 usage; if only 1, it's unused
|
|
@@ -417,7 +418,8 @@ scan_platform_refactor() {
|
|
|
417
418
|
sizes_file=$(mktemp)
|
|
418
419
|
find "$scripts_dir" -maxdepth 1 -name "*.sh" -type f 2>/dev/null | while read -r f; do
|
|
419
420
|
local lines
|
|
420
|
-
lines=$(wc -l < "$f" 2>/dev/null ||
|
|
421
|
+
lines=$(wc -l < "$f" 2>/dev/null || true)
|
|
422
|
+
lines="${lines:-0}"
|
|
421
423
|
printf '{"script":"%s","lines":%s}\n' "$(basename "$f")" "$lines"
|
|
422
424
|
done | jq -s 'sort_by(-.lines) | .[0:15]' 2>/dev/null > "$sizes_file"
|
|
423
425
|
local script_sizes
|
package/scripts/sw-incident.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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -133,10 +133,14 @@ analyze_root_cause() {
|
|
|
133
133
|
local config="$2"
|
|
134
134
|
|
|
135
135
|
local timeout_hits error_hits memory_hits dependency_hits
|
|
136
|
-
timeout_hits=$(echo "$failure_log" | grep -ic "timeout\|deadline\|too slow" ||
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
timeout_hits=$(echo "$failure_log" | grep -ic "timeout\|deadline\|too slow" || true)
|
|
137
|
+
timeout_hits="${timeout_hits:-0}"
|
|
138
|
+
memory_hits=$(echo "$failure_log" | grep -ic "out of memory\|OOM\|heap" || true)
|
|
139
|
+
memory_hits="${memory_hits:-0}"
|
|
140
|
+
dependency_hits=$(echo "$failure_log" | grep -ic "dependency\|import\|require\|not found" || true)
|
|
141
|
+
dependency_hits="${dependency_hits:-0}"
|
|
142
|
+
error_hits=$(echo "$failure_log" | grep -c . || true)
|
|
143
|
+
error_hits="${error_hits:-0}"
|
|
140
144
|
|
|
141
145
|
if [[ "$timeout_hits" -gt 0 ]]; then
|
|
142
146
|
echo "Performance degradation: Timeout detected (${timeout_hits} occurrences)"
|
package/scripts/sw-init.sh
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# ║ ║
|
|
9
9
|
# ║ --deploy Detect platform and generate deployed.json template ║
|
|
10
10
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
11
|
-
VERSION="3.
|
|
11
|
+
VERSION="3.2.0"
|
|
12
12
|
set -euo pipefail
|
|
13
13
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
14
14
|
trap 'rm -f "${tmp:-}"' EXIT
|
package/scripts/sw-instrument.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="3.
|
|
9
|
+
VERSION="3.2.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
12
12
|
|
|
@@ -395,7 +395,8 @@ _intelligence_fallback_analyze() {
|
|
|
395
395
|
local outcomes_file="$HOME/.shipwright/optimization/outcomes.jsonl"
|
|
396
396
|
if [[ -f "$outcomes_file" ]] && command -v jq &>/dev/null; then
|
|
397
397
|
local sample_count
|
|
398
|
-
sample_count=$(wc -l < "$outcomes_file" 2>/dev/null ||
|
|
398
|
+
sample_count=$(wc -l < "$outcomes_file" 2>/dev/null || true)
|
|
399
|
+
sample_count="${sample_count:-0}"
|
|
399
400
|
|
|
400
401
|
if [[ "$sample_count" -gt 5 ]]; then
|
|
401
402
|
# Compute average complexity from past outcomes
|
|
@@ -552,7 +553,8 @@ intelligence_compose_pipeline() {
|
|
|
552
553
|
if ! _intelligence_enabled; then
|
|
553
554
|
local fallback
|
|
554
555
|
fallback=$(_intelligence_fallback_compose "$issue_analysis")
|
|
555
|
-
echo "$fallback" | jq -c '. + {error: "intelligence_disabled"}' 2>/dev/null || echo '{"error":"intelligence_disabled","stages":[]}'
|
|
556
|
+
echo "$fallback" | jq -c '. + {status: "disabled", error: "intelligence_disabled"}' 2>/dev/null || echo '{"status":"disabled","error":"intelligence_disabled","stages":[]}'
|
|
557
|
+
[[ -z "${_INTEL_DISABLED_LOGGED:-}" ]] && { info "Intelligence disabled — using data-driven fallbacks"; _INTEL_DISABLED_LOGGED=1; }
|
|
556
558
|
return 0
|
|
557
559
|
fi
|
|
558
560
|
|
|
@@ -615,7 +617,8 @@ intelligence_predict_cost() {
|
|
|
615
617
|
if ! _intelligence_enabled; then
|
|
616
618
|
local fallback
|
|
617
619
|
fallback=$(_intelligence_fallback_cost)
|
|
618
|
-
echo "$fallback" | jq -c '. + {error: "intelligence_disabled", estimated_iterations: 0, likely_failure_stage: "unknown"}' 2>/dev/null || echo '{"error":"intelligence_disabled","estimated_cost_usd":0,"estimated_iterations":0,"likely_failure_stage":"unknown"}'
|
|
620
|
+
echo "$fallback" | jq -c '. + {status: "disabled", error: "intelligence_disabled", estimated_iterations: 0, likely_failure_stage: "unknown"}' 2>/dev/null || echo '{"status":"disabled","error":"intelligence_disabled","estimated_cost_usd":0,"estimated_iterations":0,"likely_failure_stage":"unknown"}'
|
|
621
|
+
[[ -z "${_INTEL_DISABLED_LOGGED:-}" ]] && { info "Intelligence disabled — using data-driven fallbacks"; _INTEL_DISABLED_LOGGED=1; }
|
|
619
622
|
return 0
|
|
620
623
|
fi
|
|
621
624
|
|
|
@@ -671,7 +674,8 @@ intelligence_synthesize_findings() {
|
|
|
671
674
|
local findings_json="${1:-"[]"}"
|
|
672
675
|
|
|
673
676
|
if ! _intelligence_enabled; then
|
|
674
|
-
echo '{"error":"intelligence_disabled","priority_fixes":[],"root_causes":[],"recommended_approach":""}'
|
|
677
|
+
echo '{"status":"disabled","error":"intelligence_disabled","priority_fixes":[],"root_causes":[],"recommended_approach":""}'
|
|
678
|
+
[[ -z "${_INTEL_DISABLED_LOGGED:-}" ]] && { info "Intelligence disabled — using data-driven fallbacks"; _INTEL_DISABLED_LOGGED=1; }
|
|
675
679
|
return 0
|
|
676
680
|
fi
|
|
677
681
|
|
|
@@ -720,7 +724,8 @@ intelligence_search_memory() {
|
|
|
720
724
|
local top_n="${3:-5}"
|
|
721
725
|
|
|
722
726
|
if ! _intelligence_enabled; then
|
|
723
|
-
echo '{"error":"intelligence_disabled","results":[]}'
|
|
727
|
+
echo '{"status":"disabled","error":"intelligence_disabled","results":[]}'
|
|
728
|
+
[[ -z "${_INTEL_DISABLED_LOGGED:-}" ]] && { info "Intelligence disabled — using data-driven fallbacks"; _INTEL_DISABLED_LOGGED=1; }
|
|
724
729
|
return 0
|
|
725
730
|
fi
|
|
726
731
|
|
package/scripts/sw-jira.sh
CHANGED
package/scripts/sw-launchd.sh
CHANGED
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="3.
|
|
7
|
+
VERSION="3.2.0"
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
10
10
|
|