shipwright-cli 2.0.0 → 2.1.1
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 +160 -72
- package/completions/_shipwright +59 -7
- package/completions/shipwright.bash +24 -4
- package/completions/shipwright.fish +80 -2
- package/dashboard/server.ts +208 -0
- package/docs/tmux-research/TMUX-ARCHITECTURE.md +567 -0
- package/docs/tmux-research/TMUX-AUDIT.md +925 -0
- package/docs/tmux-research/TMUX-BEST-PRACTICES-2025-2026.md +829 -0
- package/docs/tmux-research/TMUX-QUICK-REFERENCE.md +543 -0
- package/docs/tmux-research/TMUX-RESEARCH-INDEX.md +438 -0
- package/package.json +2 -2
- package/scripts/lib/helpers.sh +7 -0
- package/scripts/sw +116 -2
- package/scripts/sw-activity.sh +1 -1
- package/scripts/sw-adaptive.sh +1 -1
- 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 +128 -38
- package/scripts/sw-changelog.sh +1 -1
- package/scripts/sw-checkpoint.sh +1 -1
- package/scripts/sw-ci.sh +1 -1
- package/scripts/sw-cleanup.sh +1 -1
- package/scripts/sw-code-review.sh +62 -1
- package/scripts/sw-connect.sh +1 -1
- package/scripts/sw-context.sh +1 -1
- package/scripts/sw-cost.sh +44 -3
- package/scripts/sw-daemon.sh +155 -27
- package/scripts/sw-dashboard.sh +1 -1
- package/scripts/sw-db.sh +958 -118
- 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 +1 -1
- package/scripts/sw-docs-agent.sh +1 -1
- package/scripts/sw-docs.sh +1 -1
- package/scripts/sw-doctor.sh +49 -1
- package/scripts/sw-dora.sh +1 -1
- package/scripts/sw-durable.sh +1 -1
- package/scripts/sw-e2e-orchestrator.sh +1 -1
- package/scripts/sw-eventbus.sh +1 -1
- package/scripts/sw-feedback.sh +23 -15
- package/scripts/sw-fix.sh +1 -1
- package/scripts/sw-fleet-discover.sh +1 -1
- package/scripts/sw-fleet-viz.sh +1 -1
- package/scripts/sw-fleet.sh +1 -1
- package/scripts/sw-github-app.sh +1 -1
- package/scripts/sw-github-checks.sh +4 -4
- 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 +1 -1
- package/scripts/sw-incident.sh +45 -6
- package/scripts/sw-init.sh +150 -24
- package/scripts/sw-instrument.sh +1 -1
- package/scripts/sw-intelligence.sh +1 -1
- 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 +204 -19
- package/scripts/sw-memory.sh +18 -1
- package/scripts/sw-mission-control.sh +1 -1
- package/scripts/sw-model-router.sh +1 -1
- package/scripts/sw-otel.sh +1 -1
- package/scripts/sw-oversight.sh +76 -1
- package/scripts/sw-pipeline-composer.sh +1 -1
- package/scripts/sw-pipeline-vitals.sh +1 -1
- package/scripts/sw-pipeline.sh +302 -18
- package/scripts/sw-pm.sh +70 -5
- package/scripts/sw-pr-lifecycle.sh +1 -1
- package/scripts/sw-predictive.sh +8 -1
- package/scripts/sw-prep.sh +1 -1
- package/scripts/sw-ps.sh +1 -1
- package/scripts/sw-public-dashboard.sh +1 -1
- package/scripts/sw-quality.sh +1 -1
- package/scripts/sw-reaper.sh +1 -1
- package/scripts/sw-recruit.sh +1853 -178
- 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-scale.sh +1 -1
- package/scripts/sw-security-audit.sh +1 -1
- package/scripts/sw-self-optimize.sh +1 -1
- package/scripts/sw-session.sh +1 -1
- package/scripts/sw-setup.sh +263 -127
- package/scripts/sw-standup.sh +1 -1
- package/scripts/sw-status.sh +44 -2
- package/scripts/sw-strategic.sh +189 -41
- package/scripts/sw-stream.sh +1 -1
- package/scripts/sw-swarm.sh +42 -5
- package/scripts/sw-team-stages.sh +1 -1
- package/scripts/sw-templates.sh +4 -4
- package/scripts/sw-testgen.sh +66 -15
- package/scripts/sw-tmux-pipeline.sh +1 -1
- package/scripts/sw-tmux-role-color.sh +58 -0
- package/scripts/sw-tmux-status.sh +128 -0
- package/scripts/sw-tmux.sh +1 -1
- package/scripts/sw-trace.sh +1 -1
- package/scripts/sw-tracker.sh +1 -1
- package/scripts/sw-triage.sh +61 -37
- package/scripts/sw-upgrade.sh +1 -1
- package/scripts/sw-ux.sh +30 -2
- package/scripts/sw-webhook.sh +1 -1
- package/scripts/sw-widgets.sh +1 -1
- package/scripts/sw-worktree.sh +1 -1
- package/tmux/shipwright-overlay.conf +35 -17
- package/tmux/tmux.conf +26 -21
package/scripts/sw-testgen.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="1.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Handle subcommands ───────────────────────────────────────────────────────
|
|
@@ -208,8 +208,12 @@ EOF
|
|
|
208
208
|
done
|
|
209
209
|
echo ""
|
|
210
210
|
|
|
211
|
-
# Generate test template
|
|
211
|
+
# Generate test template; use Claude for real assertions when available
|
|
212
212
|
local test_template_file="$TESTGEN_DIR/generated-tests.sh"
|
|
213
|
+
local use_claude="false"
|
|
214
|
+
command -v claude &>/dev/null && use_claude="true"
|
|
215
|
+
[[ "${TESTGEN_USE_CLAUDE:-true}" == "false" ]] && use_claude="false"
|
|
216
|
+
|
|
213
217
|
{
|
|
214
218
|
echo "#!/usr/bin/env bash"
|
|
215
219
|
echo "# Generated tests for $target_script"
|
|
@@ -217,24 +221,71 @@ EOF
|
|
|
217
221
|
echo "trap 'echo \"ERROR: \$BASH_SOURCE:\$LINENO exited with status \$?\" >&2' ERR"
|
|
218
222
|
echo ""
|
|
219
223
|
echo "SCRIPT_DIR=\"\$(cd \"\$(dirname \"\${BASH_SOURCE[0]}\")\" && pwd)\""
|
|
224
|
+
echo "REPO_DIR=\"\$(cd \"\$SCRIPT_DIR/..\" && pwd)\""
|
|
225
|
+
echo ""
|
|
226
|
+
echo "# Helpers: assert equal (or contains) so tests fail when behavior is wrong"
|
|
227
|
+
echo "assert_equal() { local e=\"\$1\" a=\"\$2\"; if [[ \"\$a\" != \"\$e\" ]]; then echo \"Expected: \$e\"; echo \"Actual: \$a\"; exit 1; fi; }"
|
|
228
|
+
echo "assert_contains() { local sub=\"\$1\" full=\"\$2\"; if [[ \"\$full\" != *\"\$sub\"* ]]; then echo \"Expected to contain: \$sub\"; echo \"In: \$full\"; exit 1; fi; }"
|
|
220
229
|
echo ""
|
|
221
|
-
echo "# Test counters"
|
|
222
230
|
echo "PASS=0"
|
|
223
231
|
echo "FAIL=0"
|
|
224
232
|
echo ""
|
|
233
|
+
} > "$test_template_file"
|
|
225
234
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
+
local func_count=0
|
|
236
|
+
while IFS= read -r func; do
|
|
237
|
+
[[ -z "$func" ]] && continue
|
|
238
|
+
func_count=$((func_count + 1))
|
|
239
|
+
{
|
|
240
|
+
if [[ "$use_claude" == "true" ]]; then
|
|
241
|
+
local func_snippet
|
|
242
|
+
func_snippet=$(awk "/^${func}\(\\)/,/^[a-zA-Z_][a-zA-Z0-9_]*\(\)|^$/" "$target_script" 2>/dev/null | head -40 || true)
|
|
243
|
+
local prompt_file
|
|
244
|
+
prompt_file=$(mktemp "${TMPDIR:-/tmp}/sw-testgen-prompt.XXXXXX")
|
|
245
|
+
{
|
|
246
|
+
echo "Generate a bash test function for the following shell function. Use real assertions (assert_equal, assert_contains, or test exit code). Test happy path and at least one edge or error case. Output only the bash function body."
|
|
247
|
+
echo "Function name: ${func}"
|
|
248
|
+
echo "Function body:"
|
|
249
|
+
echo "$func_snippet"
|
|
250
|
+
} > "$prompt_file"
|
|
251
|
+
local claude_out
|
|
252
|
+
# Read prompt through pipe to avoid shell expansion of $vars in function body
|
|
253
|
+
claude_out=$(cat "$prompt_file" | claude -p --max-turns 2 2>/dev/null || true)
|
|
254
|
+
rm -f "$prompt_file"
|
|
255
|
+
if [[ -n "$claude_out" ]]; then
|
|
256
|
+
local code_block
|
|
257
|
+
code_block=$(echo "$claude_out" | sed -n '/^test_'"${func}"'()/,/^}/p' || echo "$claude_out" | sed -n '/^test_/,/^}/p' || true)
|
|
258
|
+
[[ -z "$code_block" ]] && code_block="$claude_out"
|
|
259
|
+
if echo "$code_block" | grep -qE 'assert_equal|assert_contains|\[\[.*\]\]|exit 1'; then
|
|
260
|
+
echo "test_${func}() {"
|
|
261
|
+
echo "$code_block" | sed 's/^test_'"${func}"'()//' | sed 's/^{//' | sed 's/^}//' | head -50
|
|
262
|
+
echo " ((PASS++))"
|
|
263
|
+
echo "}"
|
|
264
|
+
else
|
|
265
|
+
echo "test_${func}() {"
|
|
266
|
+
echo " # Claude-generated; review assertions"
|
|
267
|
+
echo "$code_block" | head -30 | sed 's/^/ /'
|
|
268
|
+
echo " ((PASS++))"
|
|
269
|
+
echo "}"
|
|
270
|
+
fi
|
|
271
|
+
else
|
|
272
|
+
echo "test_${func}() { # TODO: Claude unavailable"
|
|
273
|
+
echo " ((PASS++))"
|
|
274
|
+
echo "}"
|
|
275
|
+
fi
|
|
276
|
+
else
|
|
277
|
+
echo "test_${func}() {"
|
|
278
|
+
echo " # TODO: Implement test for $func"
|
|
279
|
+
echo " ((PASS++))"
|
|
280
|
+
echo "}"
|
|
281
|
+
fi
|
|
235
282
|
echo ""
|
|
236
|
-
|
|
283
|
+
} >> "$test_template_file"
|
|
284
|
+
done << EOF
|
|
285
|
+
$untested_functions
|
|
286
|
+
EOF
|
|
237
287
|
|
|
288
|
+
{
|
|
238
289
|
echo "# Run all tests"
|
|
239
290
|
echo "$untested_functions" | while IFS= read -r func; do
|
|
240
291
|
[[ -z "$func" ]] && continue
|
|
@@ -242,11 +293,11 @@ EOF
|
|
|
242
293
|
done
|
|
243
294
|
echo ""
|
|
244
295
|
echo "echo \"Results: \$PASS passed, \$FAIL failed\""
|
|
245
|
-
}
|
|
296
|
+
} >> "$test_template_file"
|
|
246
297
|
|
|
247
298
|
chmod +x "$test_template_file"
|
|
248
299
|
success "Generated test template: $test_template_file"
|
|
249
|
-
info "
|
|
300
|
+
[[ "$use_claude" == "true" ]] && info "Used Claude for assertions; review and run tests to validate"
|
|
250
301
|
}
|
|
251
302
|
|
|
252
303
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
# ║ sw-tmux-role-color.sh — Set pane border color by agent role ║
|
|
4
|
+
# ║ ║
|
|
5
|
+
# ║ Called from a tmux hook (after-select-pane) or manually. ║
|
|
6
|
+
# ║ Reads #{pane_title} and sets the active border color to match the ║
|
|
7
|
+
# ║ agent's role. Falls back to cyan (#00d4ff) for unknown roles. ║
|
|
8
|
+
# ║ ║
|
|
9
|
+
# ║ Role → Color mapping: ║
|
|
10
|
+
# ║ leader/pm → #00d4ff (cyan) — command & control ║
|
|
11
|
+
# ║ builder/dev → #0066ff (blue) — implementation ║
|
|
12
|
+
# ║ reviewer → #f97316 (orange) — scrutiny ║
|
|
13
|
+
# ║ tester → #facc15 (yellow) — validation ║
|
|
14
|
+
# ║ security → #ef4444 (red) — vigilance ║
|
|
15
|
+
# ║ docs/writer → #a78bfa (violet) — documentation ║
|
|
16
|
+
# ║ optimizer → #4ade80 (green) — performance ║
|
|
17
|
+
# ║ researcher → #7c3aed (purple) — exploration ║
|
|
18
|
+
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
# Get the active pane's title
|
|
22
|
+
PANE_TITLE="$(tmux display-message -p '#{pane_title}' 2>/dev/null || echo "")"
|
|
23
|
+
|
|
24
|
+
# Normalize to lowercase for matching
|
|
25
|
+
TITLE_LOWER="$(echo "$PANE_TITLE" | tr '[:upper:]' '[:lower:]')"
|
|
26
|
+
|
|
27
|
+
# Map role keywords to colors
|
|
28
|
+
COLOR="#00d4ff" # default: cyan
|
|
29
|
+
|
|
30
|
+
case "$TITLE_LOWER" in
|
|
31
|
+
*leader*|*lead*|*pm*|*manager*|*orchestrat*)
|
|
32
|
+
COLOR="#00d4ff" # cyan — command & control
|
|
33
|
+
;;
|
|
34
|
+
*build*|*dev*|*implement*|*code*|*engineer*)
|
|
35
|
+
COLOR="#0066ff" # blue — implementation
|
|
36
|
+
;;
|
|
37
|
+
*review*|*audit*|*inspect*|*oversight*)
|
|
38
|
+
COLOR="#f97316" # orange — scrutiny
|
|
39
|
+
;;
|
|
40
|
+
*test*|*qa*|*validat*|*verify*)
|
|
41
|
+
COLOR="#facc15" # yellow — validation
|
|
42
|
+
;;
|
|
43
|
+
*secur*|*vuln*|*threat*|*pentest*)
|
|
44
|
+
COLOR="#ef4444" # red — vigilance
|
|
45
|
+
;;
|
|
46
|
+
*doc*|*writ*|*readme*|*changelog*)
|
|
47
|
+
COLOR="#a78bfa" # violet — documentation
|
|
48
|
+
;;
|
|
49
|
+
*optim*|*perf*|*speed*|*deploy*)
|
|
50
|
+
COLOR="#4ade80" # green — performance/deploy
|
|
51
|
+
;;
|
|
52
|
+
*research*|*explor*|*investigat*|*analyz*)
|
|
53
|
+
COLOR="#7c3aed" # purple — exploration
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
|
|
57
|
+
# Set the active pane border color
|
|
58
|
+
tmux set -g pane-active-border-style "fg=${COLOR},bg=#1a1a2e" 2>/dev/null || true
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
# ║ sw-tmux-status.sh — Status bar widgets for tmux ║
|
|
4
|
+
# ║ ║
|
|
5
|
+
# ║ Called by tmux via #() in status-right. Must be FAST (<100ms). ║
|
|
6
|
+
# ║ Reads pipeline state from .claude/pipeline-state.md and heartbeats ║
|
|
7
|
+
# ║ from ~/.shipwright/heartbeats/. Outputs styled tmux format strings. ║
|
|
8
|
+
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# ─── Stage colors (match Shipwright brand palette) ────────────────────────
|
|
12
|
+
# Each pipeline stage gets a distinct color for instant visual recognition
|
|
13
|
+
stage_color() {
|
|
14
|
+
case "${1:-}" in
|
|
15
|
+
intake) echo "#71717a" ;; # muted — gathering
|
|
16
|
+
plan) echo "#7c3aed" ;; # purple — thinking
|
|
17
|
+
design) echo "#7c3aed" ;; # purple — thinking
|
|
18
|
+
build) echo "#0066ff" ;; # blue — working
|
|
19
|
+
test) echo "#facc15" ;; # yellow — validating
|
|
20
|
+
review) echo "#f97316" ;; # orange — scrutinizing
|
|
21
|
+
compound_quality) echo "#f97316" ;; # orange — scrutinizing
|
|
22
|
+
pr) echo "#00d4ff" ;; # cyan — shipping
|
|
23
|
+
merge) echo "#00d4ff" ;; # cyan — shipping
|
|
24
|
+
deploy) echo "#4ade80" ;; # green — deploying
|
|
25
|
+
validate) echo "#4ade80" ;; # green — verifying
|
|
26
|
+
monitor) echo "#4ade80" ;; # green — watching
|
|
27
|
+
*) echo "#71717a" ;; # muted fallback
|
|
28
|
+
esac
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# ─── Stage icons ──────────────────────────────────────────────────────────
|
|
32
|
+
stage_icon() {
|
|
33
|
+
case "${1:-}" in
|
|
34
|
+
intake) echo "◇" ;;
|
|
35
|
+
plan) echo "◆" ;;
|
|
36
|
+
design) echo "△" ;;
|
|
37
|
+
build) echo "⚙" ;;
|
|
38
|
+
test) echo "⚡" ;;
|
|
39
|
+
review) echo "◎" ;;
|
|
40
|
+
compound_quality) echo "◎" ;;
|
|
41
|
+
pr) echo "↑" ;;
|
|
42
|
+
merge) echo "⊕" ;;
|
|
43
|
+
deploy) echo "▲" ;;
|
|
44
|
+
validate) echo "✦" ;;
|
|
45
|
+
monitor) echo "◉" ;;
|
|
46
|
+
*) echo "·" ;;
|
|
47
|
+
esac
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# ─── Pipeline stage widget ────────────────────────────────────────────────
|
|
51
|
+
# Reads current pipeline stage from state file, outputs tmux format string
|
|
52
|
+
pipeline_widget() {
|
|
53
|
+
local state_file=".claude/pipeline-state.md"
|
|
54
|
+
|
|
55
|
+
# Try current directory, then walk up to find repo root
|
|
56
|
+
if [[ ! -f "$state_file" ]]; then
|
|
57
|
+
local dir
|
|
58
|
+
dir="$(pwd)"
|
|
59
|
+
while [[ "$dir" != "/" ]]; do
|
|
60
|
+
if [[ -f "$dir/$state_file" ]]; then
|
|
61
|
+
state_file="$dir/$state_file"
|
|
62
|
+
break
|
|
63
|
+
fi
|
|
64
|
+
dir="$(dirname "$dir")"
|
|
65
|
+
done
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
[[ -f "$state_file" ]] || return 0
|
|
69
|
+
|
|
70
|
+
# Extract current stage — look for "Stage:" or "## Stage:" pattern
|
|
71
|
+
local stage=""
|
|
72
|
+
stage="$(grep -iE '^\*?\*?(current )?stage:?\*?\*?' "$state_file" 2>/dev/null | head -1 | sed 's/.*: *//' | tr -d '*' | tr '[:upper:]' '[:lower:]' | tr -d ' ')" || true
|
|
73
|
+
|
|
74
|
+
[[ -n "$stage" ]] || return 0
|
|
75
|
+
|
|
76
|
+
local color icon
|
|
77
|
+
color="$(stage_color "$stage")"
|
|
78
|
+
icon="$(stage_icon "$stage")"
|
|
79
|
+
local label
|
|
80
|
+
label="$(echo "$stage" | tr '[:lower:]' '[:upper:]')"
|
|
81
|
+
|
|
82
|
+
# Output: colored badge with icon
|
|
83
|
+
echo "#[fg=#1e1e32,bg=${color},bold] ${icon} ${label} #[fg=${color},bg=#1a1a2e]"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# ─── Agent count widget ──────────────────────────────────────────────────
|
|
87
|
+
# Shows number of active agents from heartbeat files
|
|
88
|
+
agent_widget() {
|
|
89
|
+
local hb_dir="${HOME}/.shipwright/heartbeats"
|
|
90
|
+
[[ -d "$hb_dir" ]] || return 0
|
|
91
|
+
|
|
92
|
+
local now count=0
|
|
93
|
+
now="$(date +%s)"
|
|
94
|
+
|
|
95
|
+
for hb in "$hb_dir"/*.json; do
|
|
96
|
+
[[ -f "$hb" ]] || continue
|
|
97
|
+
# Heartbeat is alive if updated within last 60 seconds
|
|
98
|
+
local mtime
|
|
99
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
100
|
+
mtime="$(stat -f %m "$hb" 2>/dev/null || echo 0)"
|
|
101
|
+
else
|
|
102
|
+
mtime="$(stat -c %Y "$hb" 2>/dev/null || echo 0)"
|
|
103
|
+
fi
|
|
104
|
+
if (( now - mtime < 60 )); then
|
|
105
|
+
count=$((count + 1))
|
|
106
|
+
fi
|
|
107
|
+
done
|
|
108
|
+
|
|
109
|
+
if [[ $count -gt 0 ]]; then
|
|
110
|
+
echo "#[fg=#1e1e32,bg=#7c3aed,bold] λ${count} #[fg=#7c3aed,bg=#1a1a2e]"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# ─── Dispatch ─────────────────────────────────────────────────────────────
|
|
115
|
+
case "${1:-pipeline}" in
|
|
116
|
+
pipeline) pipeline_widget ;;
|
|
117
|
+
agents) agent_widget ;;
|
|
118
|
+
all)
|
|
119
|
+
# Combine both widgets
|
|
120
|
+
local p a
|
|
121
|
+
p="$(pipeline_widget)"
|
|
122
|
+
a="$(agent_widget)"
|
|
123
|
+
echo "${a}${p}"
|
|
124
|
+
;;
|
|
125
|
+
*)
|
|
126
|
+
echo ""
|
|
127
|
+
;;
|
|
128
|
+
esac
|
package/scripts/sw-tmux.sh
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# ║ shipwright tmux fix — Auto-fix common issues ║
|
|
12
12
|
# ║ shipwright tmux reload — Reload tmux config ║
|
|
13
13
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
14
|
-
VERSION="2.
|
|
14
|
+
VERSION="2.1.1"
|
|
15
15
|
set -euo pipefail
|
|
16
16
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
17
17
|
|
package/scripts/sw-trace.sh
CHANGED
package/scripts/sw-tracker.sh
CHANGED
package/scripts/sw-triage.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="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -403,40 +403,63 @@ cmd_team() {
|
|
|
403
403
|
risk=$(echo "$analysis" | jq -r '.risk')
|
|
404
404
|
effort=$(echo "$analysis" | jq -r '.effort')
|
|
405
405
|
|
|
406
|
-
#
|
|
407
|
-
local template model max_iterations agents
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
406
|
+
# ── Try recruit-powered team composition first ──
|
|
407
|
+
local template="" model="" max_iterations="" agents=""
|
|
408
|
+
local recruit_source="heuristic"
|
|
409
|
+
if [[ -x "${SCRIPT_DIR:-}/sw-recruit.sh" ]]; then
|
|
410
|
+
local issue_title
|
|
411
|
+
issue_title=$(gh issue view "$issue" --json title -q '.title' 2>/dev/null || echo "")
|
|
412
|
+
if [[ -n "$issue_title" ]]; then
|
|
413
|
+
local recruit_result
|
|
414
|
+
recruit_result=$(bash "$SCRIPT_DIR/sw-recruit.sh" team --json "$issue_title" 2>/dev/null) || true
|
|
415
|
+
if [[ -n "$recruit_result" ]] && echo "$recruit_result" | jq -e '.team' &>/dev/null 2>&1; then
|
|
416
|
+
model=$(echo "$recruit_result" | jq -r '.model // "sonnet"')
|
|
417
|
+
agents=$(echo "$recruit_result" | jq -r '.agents // 2')
|
|
418
|
+
# Map agent count to template
|
|
419
|
+
if [[ "$agents" -ge 4 ]]; then template="full"; max_iterations=15;
|
|
420
|
+
elif [[ "$agents" -ge 3 ]]; then template="standard"; max_iterations=8;
|
|
421
|
+
elif [[ "$agents" -le 1 ]]; then template="fast"; max_iterations=2;
|
|
422
|
+
else template="standard"; max_iterations=5; fi
|
|
423
|
+
recruit_source="recruit"
|
|
424
|
+
fi
|
|
425
|
+
fi
|
|
426
|
+
fi
|
|
427
|
+
|
|
428
|
+
# ── Fallback: hardcoded complexity/risk mapping ──
|
|
429
|
+
if [[ -z "$template" ]]; then
|
|
430
|
+
case "${complexity}-${risk}" in
|
|
431
|
+
trivial-low|simple-low)
|
|
432
|
+
template="fast"
|
|
433
|
+
model="haiku"
|
|
434
|
+
max_iterations=2
|
|
435
|
+
agents=1
|
|
436
|
+
;;
|
|
437
|
+
simple-*|moderate-low)
|
|
438
|
+
template="standard"
|
|
439
|
+
model="sonnet"
|
|
440
|
+
max_iterations=5
|
|
441
|
+
agents=2
|
|
442
|
+
;;
|
|
443
|
+
moderate-*|complex-low)
|
|
444
|
+
template="standard"
|
|
445
|
+
model="sonnet"
|
|
446
|
+
max_iterations=8
|
|
447
|
+
agents=3
|
|
448
|
+
;;
|
|
449
|
+
complex-*|epic-*)
|
|
450
|
+
template="full"
|
|
451
|
+
model="opus"
|
|
452
|
+
max_iterations=15
|
|
453
|
+
agents=4
|
|
454
|
+
;;
|
|
455
|
+
*)
|
|
456
|
+
template="standard"
|
|
457
|
+
model="sonnet"
|
|
458
|
+
max_iterations=5
|
|
459
|
+
agents=2
|
|
460
|
+
;;
|
|
461
|
+
esac
|
|
462
|
+
fi
|
|
440
463
|
|
|
441
464
|
cat << EOF
|
|
442
465
|
{
|
|
@@ -448,12 +471,13 @@ cmd_team() {
|
|
|
448
471
|
"pipeline_template": "$template",
|
|
449
472
|
"model": "$model",
|
|
450
473
|
"max_iterations": $max_iterations,
|
|
451
|
-
"agents": $agents
|
|
474
|
+
"agents": $agents,
|
|
475
|
+
"source": "$recruit_source"
|
|
452
476
|
}
|
|
453
477
|
}
|
|
454
478
|
EOF
|
|
455
479
|
|
|
456
|
-
emit_event "triage_team_recommended" "issue=$issue" "template=$template" "agents=$agents"
|
|
480
|
+
emit_event "triage_team_recommended" "issue=$issue" "template=$template" "agents=$agents" "source=$recruit_source"
|
|
457
481
|
}
|
|
458
482
|
|
|
459
483
|
# ─── Subcommand: batch ────────────────────────────────────────────────────
|
package/scripts/sw-upgrade.sh
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
3
|
# ║ sw upgrade — Detect and apply updates from the repo ║
|
|
4
4
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
5
|
-
VERSION="2.
|
|
5
|
+
VERSION="2.1.1"
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
package/scripts/sw-ux.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="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
|
@@ -58,7 +58,7 @@ UX_CONFIG_REPO="./.claude/ux-config.json"
|
|
|
58
58
|
|
|
59
59
|
# Detect accessibility modes
|
|
60
60
|
should_disable_colors() {
|
|
61
|
-
[[ -n "${NO_COLOR:-}" ]] || [[ -n "${CLICOLOR_FORCE:-}" && "$CLICOLOR_FORCE" == "0" ]]
|
|
61
|
+
[[ -n "${NO_COLOR:-}" ]] || [[ "${FORCE_COLOR:-}" == "0" ]] || [[ -n "${CLICOLOR_FORCE:-}" && "$CLICOLOR_FORCE" == "0" ]]
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
has_reduced_motion() {
|
|
@@ -408,11 +408,36 @@ set_reduced_motion() {
|
|
|
408
408
|
enable_screen_reader_mode() {
|
|
409
409
|
# Disable colors and animations for screen reader compatibility
|
|
410
410
|
export NO_COLOR=1
|
|
411
|
+
export FORCE_COLOR=0
|
|
411
412
|
export PREFERS_REDUCED_MOTION=1
|
|
413
|
+
|
|
414
|
+
# Propagate to tmux global environment so new panes inherit
|
|
415
|
+
if [[ -n "${TMUX:-}" ]]; then
|
|
416
|
+
tmux set-environment -g NO_COLOR 1
|
|
417
|
+
tmux set-environment -g FORCE_COLOR 0
|
|
418
|
+
tmux set-environment -g PREFERS_REDUCED_MOTION 1
|
|
419
|
+
fi
|
|
420
|
+
|
|
412
421
|
success "Screen reader mode enabled (colors and animations disabled)"
|
|
413
422
|
emit_event "ux_accessibility" "feature=screen_reader"
|
|
414
423
|
}
|
|
415
424
|
|
|
425
|
+
disable_screen_reader_mode() {
|
|
426
|
+
unset NO_COLOR
|
|
427
|
+
unset FORCE_COLOR
|
|
428
|
+
unset PREFERS_REDUCED_MOTION
|
|
429
|
+
|
|
430
|
+
# Remove from tmux global environment
|
|
431
|
+
if [[ -n "${TMUX:-}" ]]; then
|
|
432
|
+
tmux set-environment -g -u NO_COLOR 2>/dev/null || true
|
|
433
|
+
tmux set-environment -g -u FORCE_COLOR 2>/dev/null || true
|
|
434
|
+
tmux set-environment -g -u PREFERS_REDUCED_MOTION 2>/dev/null || true
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
success "Screen reader mode disabled (colors and animations restored)"
|
|
438
|
+
emit_event "ux_accessibility" "feature=screen_reader_disabled"
|
|
439
|
+
}
|
|
440
|
+
|
|
416
441
|
# ─── Formatting Helpers ───────────────────────────────────────────────────
|
|
417
442
|
format_diff_line() {
|
|
418
443
|
local line="$1"
|
|
@@ -648,6 +673,9 @@ main() {
|
|
|
648
673
|
--screen-reader)
|
|
649
674
|
enable_screen_reader_mode
|
|
650
675
|
;;
|
|
676
|
+
--no-screen-reader)
|
|
677
|
+
disable_screen_reader_mode
|
|
678
|
+
;;
|
|
651
679
|
*)
|
|
652
680
|
error "Unknown accessibility option: $1"
|
|
653
681
|
exit 1
|
package/scripts/sw-webhook.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="2.
|
|
9
|
+
VERSION="2.1.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
|
package/scripts/sw-widgets.sh
CHANGED
package/scripts/sw-worktree.sh
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# ║ Each agent gets its own worktree so parallel agents don't clobber ║
|
|
6
6
|
# ║ each other's files. Worktrees live in .worktrees/ relative to root. ║
|
|
7
7
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
8
|
-
VERSION="2.
|
|
8
|
+
VERSION="2.1.1"
|
|
9
9
|
set -euo pipefail
|
|
10
10
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
11
11
|
|