shipwright-cli 2.2.2 → 2.3.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 +12 -11
- package/dashboard/public/index.html +224 -8
- package/dashboard/public/styles.css +1078 -4
- package/dashboard/server.ts +1100 -15
- package/dashboard/src/canvas/interactions.ts +74 -0
- package/dashboard/src/canvas/layout.ts +85 -0
- package/dashboard/src/canvas/overlays.ts +117 -0
- package/dashboard/src/canvas/particles.ts +105 -0
- package/dashboard/src/canvas/renderer.ts +191 -0
- package/dashboard/src/components/charts/bar.ts +54 -0
- package/dashboard/src/components/charts/donut.ts +25 -0
- package/dashboard/src/components/charts/pipeline-rail.ts +105 -0
- package/dashboard/src/components/charts/sparkline.ts +82 -0
- package/dashboard/src/components/header.ts +616 -0
- package/dashboard/src/components/modal.ts +413 -0
- package/dashboard/src/components/terminal.ts +144 -0
- package/dashboard/src/core/api.test.ts +362 -0
- package/dashboard/src/core/api.ts +381 -0
- package/dashboard/src/core/helpers.ts +118 -0
- package/dashboard/src/core/router.test.ts +266 -0
- package/dashboard/src/core/router.ts +190 -0
- package/dashboard/src/core/sse.ts +38 -0
- package/dashboard/src/core/state.test.ts +235 -0
- package/dashboard/src/core/state.ts +150 -0
- package/dashboard/src/core/ws.test.ts +216 -0
- package/dashboard/src/core/ws.ts +143 -0
- package/dashboard/src/design/icons.test.ts +105 -0
- package/dashboard/src/design/icons.ts +131 -0
- package/dashboard/src/design/tokens.test.ts +204 -0
- package/dashboard/src/design/tokens.ts +160 -0
- package/dashboard/src/main.ts +68 -0
- package/dashboard/src/types/api.ts +337 -0
- package/dashboard/src/views/activity.ts +185 -0
- package/dashboard/src/views/agent-cockpit.ts +236 -0
- package/dashboard/src/views/agents.ts +72 -0
- package/dashboard/src/views/fleet-map.ts +299 -0
- package/dashboard/src/views/insights.ts +298 -0
- package/dashboard/src/views/machines.ts +162 -0
- package/dashboard/src/views/metrics.ts +420 -0
- package/dashboard/src/views/overview.ts +409 -0
- package/dashboard/src/views/pipeline-theater.ts +219 -0
- package/dashboard/src/views/pipelines.ts +595 -0
- package/dashboard/src/views/team.ts +362 -0
- package/dashboard/src/views/timeline.ts +389 -0
- package/dashboard/tsconfig.json +21 -0
- package/dashboard/vitest.config.ts +27 -0
- package/docs/AGI-WHATS-NEXT.md +15 -15
- package/package.json +16 -2
- package/scripts/lib/helpers.sh +30 -0
- package/scripts/lib/pipeline-quality-checks.sh +1 -1
- package/scripts/lib/pipeline-stages.sh +59 -0
- package/scripts/sw +86 -167
- 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 +14 -6
- package/scripts/sw-autonomous.sh +230 -13
- package/scripts/sw-changelog.sh +2 -2
- 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 +1 -1
- package/scripts/sw-connect.sh +1 -1
- package/scripts/sw-context.sh +1 -1
- package/scripts/sw-cost.sh +1 -1
- package/scripts/sw-daemon.sh +2 -2
- package/scripts/sw-dashboard.sh +1 -1
- package/scripts/sw-db.sh +1 -1
- 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-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 +8 -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 +1 -1
- package/scripts/sw-fix.sh +6 -5
- 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 +5 -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 +1 -1
- package/scripts/sw-incident.sh +1 -1
- package/scripts/sw-init.sh +112 -9
- package/scripts/sw-instrument.sh +6 -1
- package/scripts/sw-intelligence.sh +5 -1
- package/scripts/sw-jira.sh +1 -1
- package/scripts/sw-launchd.sh +1 -1
- package/scripts/sw-linear.sh +20 -9
- package/scripts/sw-logs.sh +1 -1
- package/scripts/sw-loop.sh +2 -1
- package/scripts/sw-memory.sh +10 -1
- package/scripts/sw-mission-control.sh +1 -1
- package/scripts/sw-model-router.sh +4 -1
- package/scripts/sw-otel.sh +1 -1
- package/scripts/sw-oversight.sh +1 -1
- package/scripts/sw-pipeline-composer.sh +3 -1
- package/scripts/sw-pipeline-vitals.sh +4 -6
- package/scripts/sw-pipeline.sh +4 -1
- package/scripts/sw-pm.sh +5 -2
- package/scripts/sw-pr-lifecycle.sh +1 -1
- package/scripts/sw-predictive.sh +4 -1
- package/scripts/sw-prep.sh +3 -2
- package/scripts/sw-ps.sh +1 -1
- package/scripts/sw-public-dashboard.sh +10 -4
- package/scripts/sw-quality.sh +1 -1
- package/scripts/sw-reaper.sh +1 -1
- package/scripts/sw-recruit.sh +16 -0
- package/scripts/sw-regression.sh +2 -1
- package/scripts/sw-release-manager.sh +1 -1
- package/scripts/sw-release.sh +7 -5
- package/scripts/sw-remote.sh +1 -1
- package/scripts/sw-replay.sh +1 -1
- package/scripts/sw-retro.sh +4 -1
- package/scripts/sw-scale.sh +4 -1
- package/scripts/sw-security-audit.sh +1 -1
- package/scripts/sw-self-optimize.sh +113 -1
- package/scripts/sw-session.sh +1 -1
- package/scripts/sw-setup.sh +1 -1
- package/scripts/sw-standup.sh +2 -1
- package/scripts/sw-status.sh +1 -1
- package/scripts/sw-strategic.sh +2 -1
- package/scripts/sw-stream.sh +1 -1
- package/scripts/sw-swarm.sh +6 -1
- package/scripts/sw-team-stages.sh +1 -1
- package/scripts/sw-templates.sh +1 -1
- package/scripts/sw-testgen.sh +3 -2
- package/scripts/sw-tmux-pipeline.sh +2 -1
- package/scripts/sw-tmux.sh +1 -1
- package/scripts/sw-trace.sh +1 -1
- package/scripts/sw-tracker-jira.sh +1 -0
- package/scripts/sw-tracker-linear.sh +1 -0
- package/scripts/sw-tracker.sh +1 -1
- package/scripts/sw-triage.sh +198 -11
- package/scripts/sw-upgrade.sh +1 -1
- package/scripts/sw-ux.sh +1 -1
- package/scripts/sw-webhook.sh +1 -1
- package/scripts/sw-widgets.sh +2 -2
- package/scripts/sw-worktree.sh +1 -1
- package/dashboard/public/app.js +0 -4422
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="2.
|
|
9
|
+
VERSION="2.3.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -227,7 +227,7 @@ fix_start() {
|
|
|
227
227
|
# Validate repos exist
|
|
228
228
|
for repo in "${REPOS[@]}"; do
|
|
229
229
|
local expanded
|
|
230
|
-
expanded
|
|
230
|
+
expanded="${repo/#\~/$HOME}"
|
|
231
231
|
if [[ ! -d "$expanded" ]]; then
|
|
232
232
|
error "Repo directory not found: $expanded"
|
|
233
233
|
exit 1
|
|
@@ -267,7 +267,7 @@ fix_start() {
|
|
|
267
267
|
info "Dry run — would execute:"
|
|
268
268
|
for repo in "${REPOS[@]}"; do
|
|
269
269
|
local expanded
|
|
270
|
-
expanded
|
|
270
|
+
expanded="${repo/#\~/$HOME}"
|
|
271
271
|
local rname
|
|
272
272
|
rname=$(basename "$expanded")
|
|
273
273
|
echo -e " ${DIM}cd $expanded && git checkout -b $branch_name${RESET}"
|
|
@@ -281,7 +281,7 @@ fix_start() {
|
|
|
281
281
|
local repos_json="[]"
|
|
282
282
|
for repo in "${REPOS[@]}"; do
|
|
283
283
|
local expanded
|
|
284
|
-
expanded
|
|
284
|
+
expanded="${repo/#\~/$HOME}"
|
|
285
285
|
local rname
|
|
286
286
|
rname=$(basename "$expanded")
|
|
287
287
|
repos_json=$(echo "$repos_json" | jq --arg name "$rname" --arg path "$expanded" \
|
|
@@ -291,6 +291,7 @@ fix_start() {
|
|
|
291
291
|
# Atomic write initial state
|
|
292
292
|
local tmp_state
|
|
293
293
|
tmp_state=$(mktemp)
|
|
294
|
+
trap 'rm -f "$tmp_state"' RETURN
|
|
294
295
|
jq -n \
|
|
295
296
|
--arg goal "$GOAL" \
|
|
296
297
|
--arg branch "$branch_name" \
|
|
@@ -311,7 +312,7 @@ fix_start() {
|
|
|
311
312
|
|
|
312
313
|
for repo in "${REPOS[@]}"; do
|
|
313
314
|
local expanded
|
|
314
|
-
expanded
|
|
315
|
+
expanded="${repo/#\~/$HOME}"
|
|
315
316
|
local rname
|
|
316
317
|
rname=$(basename "$expanded")
|
|
317
318
|
|
package/scripts/sw-fleet-viz.sh
CHANGED
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="2.
|
|
9
|
+
VERSION="2.3.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -90,6 +90,7 @@ cmd_setup() {
|
|
|
90
90
|
# Create config atomically
|
|
91
91
|
local tmp_config
|
|
92
92
|
tmp_config=$(mktemp)
|
|
93
|
+
trap "rm -f '$tmp_config'" RETURN
|
|
93
94
|
jq -n \
|
|
94
95
|
--arg app_id "$app_id" \
|
|
95
96
|
--arg key_path "$key_path" \
|
|
@@ -194,6 +195,7 @@ _cache_token() {
|
|
|
194
195
|
|
|
195
196
|
local tmp_tokens
|
|
196
197
|
tmp_tokens=$(mktemp)
|
|
198
|
+
trap "rm -f '$tmp_tokens'" RETURN
|
|
197
199
|
|
|
198
200
|
if [[ -f "$TOKENS_FILE" ]]; then
|
|
199
201
|
jq ".tokens += [{\"installation_id\":$installation_id,\"token\":\"$token\",\"expires_at\":\"$expires_at\"}]" \
|
|
@@ -399,9 +401,10 @@ cmd_manifest() {
|
|
|
399
401
|
manifest=$(jq -n \
|
|
400
402
|
--arg name "$app_name" \
|
|
401
403
|
--arg webhook_url "$webhook_url" \
|
|
404
|
+
--arg github_url "$(_sw_github_url)" \
|
|
402
405
|
'{
|
|
403
406
|
name: $name,
|
|
404
|
-
url:
|
|
407
|
+
url: $github_url,
|
|
405
408
|
hook_attributes: {
|
|
406
409
|
url: $webhook_url
|
|
407
410
|
},
|
|
@@ -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.3.1"
|
|
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="2.
|
|
9
|
+
VERSION="2.3.1"
|
|
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="2.
|
|
9
|
+
VERSION="2.3.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
package/scripts/sw-hygiene.sh
CHANGED
package/scripts/sw-incident.sh
CHANGED
package/scripts/sw-init.sh
CHANGED
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
# ║ ║
|
|
9
9
|
# ║ --deploy Detect platform and generate deployed.json template ║
|
|
10
10
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
11
|
-
VERSION="2.
|
|
11
|
+
VERSION="2.3.1"
|
|
12
12
|
set -euo pipefail
|
|
13
13
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
14
|
+
trap 'rm -f "${tmp:-}"' EXIT
|
|
14
15
|
|
|
15
16
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
17
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
@@ -305,6 +306,59 @@ if [[ $_verify_fail -eq 0 ]]; then
|
|
|
305
306
|
success "Verified: tmux config, overlay, TPM, and plugins all deployed"
|
|
306
307
|
fi
|
|
307
308
|
|
|
309
|
+
# ─── CLI Bootstrap (symlinks + PATH) ─────────────────────────────────────────
|
|
310
|
+
# Install sw/shipwright/cct symlinks so the CLI works from anywhere
|
|
311
|
+
BIN_DIR="$HOME/.local/bin"
|
|
312
|
+
mkdir -p "$BIN_DIR"
|
|
313
|
+
|
|
314
|
+
SW_SRC="$SCRIPT_DIR/sw"
|
|
315
|
+
if [[ -f "$SW_SRC" ]]; then
|
|
316
|
+
_cli_changed=false
|
|
317
|
+
for _cmd in sw shipwright cct; do
|
|
318
|
+
_dest="$BIN_DIR/$_cmd"
|
|
319
|
+
if [[ -L "$_dest" ]] && [[ "$(readlink "$_dest")" == "$SW_SRC" ]]; then
|
|
320
|
+
continue
|
|
321
|
+
fi
|
|
322
|
+
ln -sf "$SW_SRC" "$_dest"
|
|
323
|
+
_cli_changed=true
|
|
324
|
+
done
|
|
325
|
+
if [[ "$_cli_changed" == "true" ]]; then
|
|
326
|
+
success "CLI symlinks: sw, shipwright, cct → $BIN_DIR"
|
|
327
|
+
else
|
|
328
|
+
success "CLI symlinks already correct"
|
|
329
|
+
fi
|
|
330
|
+
fi
|
|
331
|
+
|
|
332
|
+
# Ensure ~/.local/bin is in PATH via shell profile
|
|
333
|
+
if ! echo "$PATH" | tr ':' '\n' | grep -qxF "$BIN_DIR"; then
|
|
334
|
+
_login_shell="$(basename "${SHELL:-/bin/zsh}")"
|
|
335
|
+
case "$_login_shell" in
|
|
336
|
+
zsh) _rc="$HOME/.zshrc" ;;
|
|
337
|
+
bash)
|
|
338
|
+
if [[ -f "$HOME/.bash_profile" ]]; then _rc="$HOME/.bash_profile"
|
|
339
|
+
else _rc="$HOME/.bashrc"; fi
|
|
340
|
+
;;
|
|
341
|
+
*) _rc="$HOME/.profile" ;;
|
|
342
|
+
esac
|
|
343
|
+
|
|
344
|
+
_marker="# Added by Shipwright"
|
|
345
|
+
_line='export PATH="$HOME/.local/bin:$PATH"'
|
|
346
|
+
|
|
347
|
+
if [[ -f "$_rc" ]] && grep -qF "$_marker" "$_rc" 2>/dev/null; then
|
|
348
|
+
info "PATH already configured in $_rc"
|
|
349
|
+
else
|
|
350
|
+
if [[ -f "$_rc" ]]; then
|
|
351
|
+
printf '\n%s\n%s\n' "$_marker" "$_line" >> "$_rc"
|
|
352
|
+
else
|
|
353
|
+
printf '%s\n%s\n' "$_marker" "$_line" > "$_rc"
|
|
354
|
+
fi
|
|
355
|
+
success "Added ~/.local/bin to PATH in $_rc"
|
|
356
|
+
fi
|
|
357
|
+
export PATH="$BIN_DIR:$PATH"
|
|
358
|
+
else
|
|
359
|
+
success "~/.local/bin already in PATH"
|
|
360
|
+
fi
|
|
361
|
+
|
|
308
362
|
# ─── Team Templates ──────────────────────────────────────────────────────────
|
|
309
363
|
SHIPWRIGHT_DIR="$HOME/.shipwright"
|
|
310
364
|
TEMPLATES_SRC="$REPO_DIR/tmux/templates"
|
|
@@ -338,18 +392,17 @@ fi
|
|
|
338
392
|
|
|
339
393
|
# ─── Shell Completions ────────────────────────────────────────────────────────
|
|
340
394
|
# Detect shell type and install completions to the correct location
|
|
395
|
+
# Detect the user's login shell (not the script's running shell).
|
|
396
|
+
# This script runs in bash, so $BASH_VERSION is always set — check $SHELL first.
|
|
341
397
|
SHELL_TYPE=""
|
|
342
|
-
if [[
|
|
398
|
+
if [[ "${SHELL:-}" == *"zsh"* ]]; then
|
|
399
|
+
SHELL_TYPE="zsh"
|
|
400
|
+
elif [[ "${SHELL:-}" == *"bash"* ]]; then
|
|
401
|
+
SHELL_TYPE="bash"
|
|
402
|
+
elif [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
343
403
|
SHELL_TYPE="zsh"
|
|
344
404
|
elif [[ -n "${BASH_VERSION:-}" ]]; then
|
|
345
405
|
SHELL_TYPE="bash"
|
|
346
|
-
else
|
|
347
|
-
# Try to detect from $SHELL env var
|
|
348
|
-
if [[ "$SHELL" == *"zsh"* ]]; then
|
|
349
|
-
SHELL_TYPE="zsh"
|
|
350
|
-
elif [[ "$SHELL" == *"bash"* ]]; then
|
|
351
|
-
SHELL_TYPE="bash"
|
|
352
|
-
fi
|
|
353
406
|
fi
|
|
354
407
|
|
|
355
408
|
COMPLETIONS_SRC="$REPO_DIR/completions"
|
|
@@ -375,6 +428,10 @@ elif [[ "$SHELL_TYPE" == "zsh" ]]; then
|
|
|
375
428
|
} >> "$HOME/.zshrc"
|
|
376
429
|
info "Added ~/.zsh/completions to fpath in ~/.zshrc"
|
|
377
430
|
fi
|
|
431
|
+
# Ensure compinit is present (needed for completions to work)
|
|
432
|
+
if ! grep -q "compinit" "$HOME/.zshrc" 2>/dev/null; then
|
|
433
|
+
echo "autoload -Uz compinit && compinit" >> "$HOME/.zshrc"
|
|
434
|
+
fi
|
|
378
435
|
else
|
|
379
436
|
# Create minimal .zshrc with fpath
|
|
380
437
|
{
|
|
@@ -585,6 +642,22 @@ if [[ "$SKIP_CLAUDE_MD" == "false" && -f "$CLAUDE_MD_SRC" ]]; then
|
|
|
585
642
|
fi
|
|
586
643
|
fi
|
|
587
644
|
|
|
645
|
+
# ─── GitHub CLI Authentication ────────────────────────────────────────────────
|
|
646
|
+
# gh auth is required for daemon, pipeline, PR creation, and issue management
|
|
647
|
+
if command -v gh &>/dev/null; then
|
|
648
|
+
if gh auth status &>/dev/null 2>&1; then
|
|
649
|
+
success "GitHub CLI authenticated"
|
|
650
|
+
else
|
|
651
|
+
warn "GitHub CLI installed but not authenticated"
|
|
652
|
+
echo -e " ${DIM}Required for: daemon, pipeline, PR creation, issue management${RESET}"
|
|
653
|
+
echo -e " ${DIM}Run: ${RESET}${BOLD}gh auth login${RESET}"
|
|
654
|
+
fi
|
|
655
|
+
else
|
|
656
|
+
warn "GitHub CLI (gh) not installed"
|
|
657
|
+
echo -e " ${DIM}Required for: daemon, pipeline, PR creation, issue management${RESET}"
|
|
658
|
+
echo -e " ${DIM}Install: ${RESET}${BOLD}brew install gh && gh auth login${RESET}"
|
|
659
|
+
fi
|
|
660
|
+
|
|
588
661
|
# ─── Reload tmux if inside a session ──────────────────────────────────────────
|
|
589
662
|
if [[ -n "${TMUX:-}" ]]; then
|
|
590
663
|
if tmux source-file "$HOME/.tmux.conf" 2>/dev/null; then
|
|
@@ -595,6 +668,36 @@ if [[ -n "${TMUX:-}" ]]; then
|
|
|
595
668
|
fi
|
|
596
669
|
fi
|
|
597
670
|
|
|
671
|
+
# ─── Bun (required for dashboard) ──────────────────────────────────────────
|
|
672
|
+
if command -v bun &>/dev/null || [[ -x "$HOME/.bun/bin/bun" ]]; then
|
|
673
|
+
_bun_cmd="bun"
|
|
674
|
+
[[ -x "$HOME/.bun/bin/bun" ]] && _bun_cmd="$HOME/.bun/bin/bun"
|
|
675
|
+
success "Bun $($_bun_cmd --version 2>/dev/null || echo "installed") — dashboard ready"
|
|
676
|
+
else
|
|
677
|
+
info "Installing Bun (required for ${BOLD}shipwright dashboard${RESET})..."
|
|
678
|
+
if curl -fsSL https://bun.sh/install | bash 2>/dev/null; then
|
|
679
|
+
export PATH="$HOME/.bun/bin:$PATH"
|
|
680
|
+
success "Bun installed — dashboard ready"
|
|
681
|
+
else
|
|
682
|
+
warn "Could not install Bun automatically"
|
|
683
|
+
echo -e " ${DIM}Install manually: curl -fsSL https://bun.sh/install | bash${RESET}"
|
|
684
|
+
echo -e " ${DIM}The dashboard requires Bun to run: shipwright dashboard${RESET}"
|
|
685
|
+
fi
|
|
686
|
+
fi
|
|
687
|
+
|
|
688
|
+
# ─── Dashboard Files ──────────────────────────────────────────────────────
|
|
689
|
+
# Copy dashboard files to the install location for non-source installs
|
|
690
|
+
DASHBOARD_SRC="$REPO_DIR/dashboard"
|
|
691
|
+
DASHBOARD_DEST="$HOME/.local/share/shipwright/dashboard"
|
|
692
|
+
if [[ -f "$DASHBOARD_SRC/server.ts" ]]; then
|
|
693
|
+
mkdir -p "$DASHBOARD_DEST/public"
|
|
694
|
+
cp "$DASHBOARD_SRC/server.ts" "$DASHBOARD_DEST/server.ts"
|
|
695
|
+
for _f in "$DASHBOARD_SRC/public"/*; do
|
|
696
|
+
[[ -f "$_f" ]] && cp "$_f" "$DASHBOARD_DEST/public/$(basename "$_f")"
|
|
697
|
+
done
|
|
698
|
+
success "Dashboard files installed → ~/.local/share/shipwright/dashboard/"
|
|
699
|
+
fi
|
|
700
|
+
|
|
598
701
|
# ─── Validation ───────────────────────────────────────────────────────────────
|
|
599
702
|
echo ""
|
|
600
703
|
echo -e "${CYAN}${BOLD}Running doctor...${RESET}"
|
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="2.
|
|
9
|
+
VERSION="2.3.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -200,6 +200,7 @@ cmd_start() {
|
|
|
200
200
|
local run_file="${INSTRUMENT_ACTIVE}/${run_id}.json"
|
|
201
201
|
local tmp_file
|
|
202
202
|
tmp_file="$(mktemp "${INSTRUMENT_ACTIVE}/.tmp.XXXXXX")"
|
|
203
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
203
204
|
|
|
204
205
|
# Get repo info if not provided
|
|
205
206
|
if [[ "$repo" == "." ]]; then
|
|
@@ -266,6 +267,7 @@ cmd_record() {
|
|
|
266
267
|
|
|
267
268
|
local tmp_file
|
|
268
269
|
tmp_file="$(mktemp "${INSTRUMENT_ACTIVE}/.tmp.XXXXXX")"
|
|
270
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
269
271
|
|
|
270
272
|
# Parse value as number if it's numeric
|
|
271
273
|
local value_json
|
|
@@ -328,6 +330,7 @@ cmd_stage_start() {
|
|
|
328
330
|
|
|
329
331
|
local tmp_file
|
|
330
332
|
tmp_file="$(mktemp "${INSTRUMENT_ACTIVE}/.tmp.XXXXXX")"
|
|
333
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
331
334
|
|
|
332
335
|
jq \
|
|
333
336
|
--arg stage "$stage" \
|
|
@@ -373,6 +376,7 @@ cmd_stage_end() {
|
|
|
373
376
|
|
|
374
377
|
local tmp_file
|
|
375
378
|
tmp_file="$(mktemp "${INSTRUMENT_ACTIVE}/.tmp.XXXXXX")"
|
|
379
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
376
380
|
|
|
377
381
|
jq \
|
|
378
382
|
--arg stage "$stage" \
|
|
@@ -422,6 +426,7 @@ cmd_finish() {
|
|
|
422
426
|
|
|
423
427
|
local tmp_file
|
|
424
428
|
tmp_file="$(mktemp "${INSTRUMENT_ACTIVE}/.tmp.XXXXXX")"
|
|
429
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
425
430
|
|
|
426
431
|
# Update run record with finish data
|
|
427
432
|
jq \
|
|
@@ -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.3.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
12
12
|
|
|
@@ -75,6 +75,7 @@ _intelligence_track_cache_access() {
|
|
|
75
75
|
|
|
76
76
|
local tmp_file
|
|
77
77
|
tmp_file=$(mktemp "${TMPDIR:-/tmp}/sw-cache-stats.XXXXXX")
|
|
78
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
78
79
|
if [[ "$hit_or_miss" == "hit" ]]; then
|
|
79
80
|
jq '.hits += 1 | .total += 1' "$CACHE_STATS_FILE" > "$tmp_file" && mv "$tmp_file" "$CACHE_STATS_FILE" || rm -f "$tmp_file"
|
|
80
81
|
else
|
|
@@ -118,6 +119,7 @@ _intelligence_adjust_cache_ttl() {
|
|
|
118
119
|
if [[ "$new_ttl" != "$current_ttl" ]]; then
|
|
119
120
|
local tmp_file
|
|
120
121
|
tmp_file=$(mktemp "${TMPDIR:-/tmp}/sw-cache-ttl.XXXXXX")
|
|
122
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
121
123
|
jq -n \
|
|
122
124
|
--argjson ttl "$new_ttl" \
|
|
123
125
|
--argjson miss_rate "$miss_rate" \
|
|
@@ -134,6 +136,7 @@ _intelligence_adjust_cache_ttl() {
|
|
|
134
136
|
# Reset stats for next window
|
|
135
137
|
local tmp_reset
|
|
136
138
|
tmp_reset=$(mktemp "${TMPDIR:-/tmp}/sw-cache-reset.XXXXXX")
|
|
139
|
+
trap "rm -f '$tmp_reset'" RETURN
|
|
137
140
|
echo '{"hits":0,"misses":0,"total":0}' > "$tmp_reset" && mv "$tmp_reset" "$CACHE_STATS_FILE" || rm -f "$tmp_reset"
|
|
138
141
|
}
|
|
139
142
|
|
|
@@ -212,6 +215,7 @@ _intelligence_cache_set() {
|
|
|
212
215
|
|
|
213
216
|
local tmp_file
|
|
214
217
|
tmp_file=$(mktemp "${TMPDIR:-/tmp}/sw-intel-cache.XXXXXX")
|
|
218
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
215
219
|
jq --arg h "$hash" \
|
|
216
220
|
--argjson result "$result" \
|
|
217
221
|
--argjson ts "$now" \
|
package/scripts/sw-jira.sh
CHANGED
package/scripts/sw-launchd.sh
CHANGED
package/scripts/sw-linear.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.3.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -48,12 +48,14 @@ RESET="${RESET:-\033[0m}"
|
|
|
48
48
|
CONFIG_DIR="${HOME}/.shipwright"
|
|
49
49
|
LINEAR_CONFIG="${CONFIG_DIR}/linear-config.json"
|
|
50
50
|
|
|
51
|
-
# Linear Status IDs
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
# Linear Status IDs — loaded from config, with env var overrides
|
|
52
|
+
# Configure via: shipwright tracker init --provider linear
|
|
53
|
+
# Or set env vars: LINEAR_STATUS_BACKLOG, LINEAR_STATUS_TODO, etc.
|
|
54
|
+
STATUS_BACKLOG="${LINEAR_STATUS_BACKLOG:-}"
|
|
55
|
+
STATUS_TODO="${LINEAR_STATUS_TODO:-}"
|
|
56
|
+
STATUS_IN_PROGRESS="${LINEAR_STATUS_IN_PROGRESS:-}"
|
|
57
|
+
STATUS_IN_REVIEW="${LINEAR_STATUS_IN_REVIEW:-}"
|
|
58
|
+
STATUS_DONE="${LINEAR_STATUS_DONE:-}"
|
|
57
59
|
|
|
58
60
|
LINEAR_API="https://api.linear.app/graphql"
|
|
59
61
|
|
|
@@ -65,8 +67,17 @@ load_config() {
|
|
|
65
67
|
fi
|
|
66
68
|
|
|
67
69
|
LINEAR_API_KEY="${LINEAR_API_KEY:-}"
|
|
68
|
-
LINEAR_TEAM_ID="${LINEAR_TEAM_ID
|
|
69
|
-
LINEAR_PROJECT_ID="${LINEAR_PROJECT_ID
|
|
70
|
+
LINEAR_TEAM_ID="${LINEAR_TEAM_ID:-$(jq -r '.team_id // empty' "$LINEAR_CONFIG" 2>/dev/null || true)}"
|
|
71
|
+
LINEAR_PROJECT_ID="${LINEAR_PROJECT_ID:-$(jq -r '.project_id // empty' "$LINEAR_CONFIG" 2>/dev/null || true)}"
|
|
72
|
+
|
|
73
|
+
# Load status IDs from config if not set via env
|
|
74
|
+
if [[ -f "$LINEAR_CONFIG" ]]; then
|
|
75
|
+
STATUS_BACKLOG="${STATUS_BACKLOG:-$(jq -r '.status_ids.backlog // empty' "$LINEAR_CONFIG" 2>/dev/null || true)}"
|
|
76
|
+
STATUS_TODO="${STATUS_TODO:-$(jq -r '.status_ids.todo // empty' "$LINEAR_CONFIG" 2>/dev/null || true)}"
|
|
77
|
+
STATUS_IN_PROGRESS="${STATUS_IN_PROGRESS:-$(jq -r '.status_ids.in_progress // empty' "$LINEAR_CONFIG" 2>/dev/null || true)}"
|
|
78
|
+
STATUS_IN_REVIEW="${STATUS_IN_REVIEW:-$(jq -r '.status_ids.in_review // empty' "$LINEAR_CONFIG" 2>/dev/null || true)}"
|
|
79
|
+
STATUS_DONE="${STATUS_DONE:-$(jq -r '.status_ids.done // empty' "$LINEAR_CONFIG" 2>/dev/null || true)}"
|
|
80
|
+
fi
|
|
70
81
|
}
|
|
71
82
|
|
|
72
83
|
check_api_key() {
|
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="2.
|
|
7
|
+
VERSION="2.3.1"
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
10
10
|
|
package/scripts/sw-loop.sh
CHANGED
|
@@ -71,7 +71,7 @@ MAX_RESTARTS=0
|
|
|
71
71
|
SESSION_RESTART=false
|
|
72
72
|
RESTART_COUNT=0
|
|
73
73
|
REPO_OVERRIDE=""
|
|
74
|
-
VERSION="2.
|
|
74
|
+
VERSION="2.3.1"
|
|
75
75
|
|
|
76
76
|
# ─── Token Tracking ─────────────────────────────────────────────────────────
|
|
77
77
|
LOOP_INPUT_TOKENS=0
|
|
@@ -531,6 +531,7 @@ write_loop_tokens() {
|
|
|
531
531
|
fi
|
|
532
532
|
local tmp_file
|
|
533
533
|
tmp_file=$(mktemp "${token_file}.XXXXXX" 2>/dev/null || mktemp)
|
|
534
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
534
535
|
cat > "$tmp_file" <<TOKJSON
|
|
535
536
|
{"input_tokens":${LOOP_INPUT_TOKENS},"output_tokens":${LOOP_OUTPUT_TOKENS},"cost_usd":${cost_usd},"iterations":${ITERATION:-0}}
|
|
536
537
|
TOKJSON
|
package/scripts/sw-memory.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.3.1"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
12
12
|
|
|
@@ -150,6 +150,7 @@ memory_capture_pipeline() {
|
|
|
150
150
|
# Record review patterns to global memory for cross-repo learning
|
|
151
151
|
local tmp_global
|
|
152
152
|
tmp_global=$(mktemp)
|
|
153
|
+
trap "rm -f '$tmp_global'" RETURN
|
|
153
154
|
jq --arg repo "$repo" \
|
|
154
155
|
--arg ts "$captured_at" \
|
|
155
156
|
--argjson bugs "${bug_count:-0}" \
|
|
@@ -211,6 +212,7 @@ memory_capture_failure() {
|
|
|
211
212
|
fi
|
|
212
213
|
local tmp_file
|
|
213
214
|
tmp_file=$(mktemp "${failures_file}.tmp.XXXXXX")
|
|
215
|
+
trap "rm -f '$tmp_file'" EXIT
|
|
214
216
|
|
|
215
217
|
if [[ "$existing_idx" != "-1" && "$existing_idx" != "null" ]]; then
|
|
216
218
|
# Update existing entry
|
|
@@ -277,6 +279,7 @@ memory_record_fix_outcome() {
|
|
|
277
279
|
fi
|
|
278
280
|
local tmp_file
|
|
279
281
|
tmp_file=$(mktemp "${failures_file}.tmp.XXXXXX")
|
|
282
|
+
trap "rm -f '$tmp_file'" EXIT
|
|
280
283
|
|
|
281
284
|
jq --argjson idx "$match_idx" \
|
|
282
285
|
--argjson app "$applied_inc" \
|
|
@@ -442,6 +445,7 @@ _memory_aggregate_global() {
|
|
|
442
445
|
# Add to global, cap at 100 entries
|
|
443
446
|
local tmp_global
|
|
444
447
|
tmp_global=$(mktemp "${global_file}.tmp.XXXXXX")
|
|
448
|
+
trap "rm -f '$tmp_global'" RETURN
|
|
445
449
|
jq --arg p "$pattern" \
|
|
446
450
|
--arg ts "$(now_iso)" \
|
|
447
451
|
--arg cat "general" \
|
|
@@ -593,6 +597,7 @@ Return JSON only, no markdown fences, no explanation."
|
|
|
593
597
|
# Update the most recent failure entry with root_cause, fix, category
|
|
594
598
|
local tmp_file
|
|
595
599
|
tmp_file=$(mktemp)
|
|
600
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
596
601
|
jq --arg rc "$root_cause" \
|
|
597
602
|
--arg fix "$fix" \
|
|
598
603
|
--arg cat "$category" \
|
|
@@ -622,6 +627,7 @@ memory_capture_pattern() {
|
|
|
622
627
|
|
|
623
628
|
local tmp_file
|
|
624
629
|
tmp_file=$(mktemp)
|
|
630
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
625
631
|
|
|
626
632
|
case "$pattern_type" in
|
|
627
633
|
project)
|
|
@@ -1112,6 +1118,7 @@ memory_update_metrics() {
|
|
|
1112
1118
|
# Update baseline using atomic write
|
|
1113
1119
|
local tmp_file
|
|
1114
1120
|
tmp_file=$(mktemp)
|
|
1121
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
1115
1122
|
jq --arg m "$metric_name" \
|
|
1116
1123
|
--argjson v "$value" \
|
|
1117
1124
|
--arg ts "$(now_iso)" \
|
|
@@ -1135,6 +1142,7 @@ memory_capture_decision() {
|
|
|
1135
1142
|
|
|
1136
1143
|
local tmp_file
|
|
1137
1144
|
tmp_file=$(mktemp)
|
|
1145
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
1138
1146
|
jq --arg type "$dec_type" \
|
|
1139
1147
|
--arg summary "$summary" \
|
|
1140
1148
|
--arg detail "$detail" \
|
|
@@ -1454,6 +1462,7 @@ memory_import() {
|
|
|
1454
1462
|
# Extract and write each section
|
|
1455
1463
|
local tmp_file
|
|
1456
1464
|
tmp_file=$(mktemp)
|
|
1465
|
+
trap "rm -f '$tmp_file'" RETURN
|
|
1457
1466
|
|
|
1458
1467
|
jq '.patterns // {}' "$import_file" > "$tmp_file" && mv "$tmp_file" "$mem_dir/patterns.json"
|
|
1459
1468
|
jq '.failures // {"failures":[]}' "$import_file" > "$tmp_file" && mv "$tmp_file" "$mem_dir/failures.json"
|