shipwright-cli 2.3.0 → 2.4.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 +82 -20
- package/config/policy.json +160 -2
- package/config/policy.schema.json +162 -1
- package/dashboard/public/index.html +1 -1
- package/dashboard/src/core/api.test.ts +362 -0
- package/dashboard/src/core/router.test.ts +266 -0
- package/dashboard/src/core/state.test.ts +235 -0
- package/dashboard/src/core/ws.test.ts +216 -0
- package/dashboard/src/design/icons.test.ts +105 -0
- package/dashboard/src/design/tokens.test.ts +204 -0
- package/dashboard/tsconfig.json +1 -1
- package/dashboard/vitest.config.ts +27 -0
- package/package.json +23 -4
- package/scripts/lib/pipeline-stages.sh +59 -0
- package/scripts/sw +1 -1
- 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 +230 -13
- 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 +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 +1 -1
- 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 +1 -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-evidence.sh +664 -0
- 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 +1 -1
- package/scripts/sw-fleet.sh +1 -1
- package/scripts/sw-github-app.sh +1 -1
- 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 +244 -1
- package/scripts/sw-init.sh +1 -1
- 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 +1 -1
- package/scripts/sw-memory.sh +1 -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 +1 -1
- package/scripts/sw-pipeline-composer.sh +1 -1
- package/scripts/sw-pipeline-vitals.sh +1 -1
- package/scripts/sw-pipeline.sh +1 -1
- package/scripts/sw-pm.sh +1 -1
- package/scripts/sw-pr-lifecycle.sh +177 -5
- package/scripts/sw-predictive.sh +1 -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-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 +4 -1
- package/scripts/sw-review-rerun.sh +220 -0
- package/scripts/sw-scale.sh +1 -1
- package/scripts/sw-security-audit.sh +1 -1
- package/scripts/sw-self-optimize.sh +99 -1
- package/scripts/sw-session.sh +1 -1
- 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 +1 -1
- package/scripts/sw-stream.sh +1 -1
- package/scripts/sw-swarm.sh +1 -1
- package/scripts/sw-team-stages.sh +1 -1
- package/scripts/sw-templates.sh +1 -1
- package/scripts/sw-testgen.sh +1 -1
- package/scripts/sw-tmux-pipeline.sh +1 -1
- 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 +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 +1 -1
- package/scripts/sw-worktree.sh +1 -1
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.4.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="2.
|
|
9
|
+
VERSION="2.4.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="2.
|
|
9
|
+
VERSION="2.4.0"
|
|
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
|
@@ -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.4.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -334,6 +334,9 @@ cmd_watch() {
|
|
|
334
334
|
info "Incident $incident_id created (severity: $severity)"
|
|
335
335
|
emit_event "incident.detected" "incident_id=$incident_id" "severity=$severity"
|
|
336
336
|
|
|
337
|
+
# Create harness gap for test case tracking (Code Factory pattern)
|
|
338
|
+
create_harness_gap "$incident_id" "$severity" "$root_cause" 2>/dev/null || true
|
|
339
|
+
|
|
337
340
|
# Auto-response for P0/P1: hotfix issue, trigger pipeline, optional rollback
|
|
338
341
|
if [[ "$severity" == "P0" ]] || [[ "$severity" == "P1" ]]; then
|
|
339
342
|
local auto_rollback
|
|
@@ -556,6 +559,242 @@ cmd_stats() {
|
|
|
556
559
|
esac
|
|
557
560
|
}
|
|
558
561
|
|
|
562
|
+
# ─── Harness Gap Loop ─────────────────────────────────────────────────────
|
|
563
|
+
# Code Factory pattern: production regression → harness gap issue → test case
|
|
564
|
+
# added → SLA tracked. Every incident must produce a test case within SLA.
|
|
565
|
+
|
|
566
|
+
HARNESS_GAPS_DIR="${INCIDENTS_DIR}/harness-gaps"
|
|
567
|
+
|
|
568
|
+
load_harness_gap_policy() {
|
|
569
|
+
local policy="${REPO_DIR}/config/policy.json"
|
|
570
|
+
if [[ -f "$policy" ]]; then
|
|
571
|
+
HARNESS_GAP_ENABLED=$(jq -r '.harnessGapPolicy.enabled // false' "$policy" 2>/dev/null || echo "false")
|
|
572
|
+
HARNESS_GAP_P0_SLA=$(jq -r '.harnessGapPolicy.p0SlaHours // 24' "$policy" 2>/dev/null || echo "24")
|
|
573
|
+
HARNESS_GAP_P1_SLA=$(jq -r '.harnessGapPolicy.p1SlaHours // 72' "$policy" 2>/dev/null || echo "72")
|
|
574
|
+
HARNESS_GAP_P2_SLA=$(jq -r '.harnessGapPolicy.p2SlaHours // 168' "$policy" 2>/dev/null || echo "168")
|
|
575
|
+
HARNESS_GAP_AUTO_CREATE=$(jq -r '.harnessGapPolicy.autoCreateGapIssue // true' "$policy" 2>/dev/null || echo "true")
|
|
576
|
+
HARNESS_GAP_REQUIRE_TEST=$(jq -r '.harnessGapPolicy.requireTestCaseBeforeClose // true' "$policy" 2>/dev/null || echo "true")
|
|
577
|
+
else
|
|
578
|
+
HARNESS_GAP_ENABLED="false"
|
|
579
|
+
fi
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
create_harness_gap() {
|
|
583
|
+
local incident_id="$1"
|
|
584
|
+
local severity="$2"
|
|
585
|
+
local root_cause="$3"
|
|
586
|
+
|
|
587
|
+
mkdir -p "$HARNESS_GAPS_DIR"
|
|
588
|
+
load_harness_gap_policy
|
|
589
|
+
|
|
590
|
+
if [[ "$HARNESS_GAP_ENABLED" != "true" ]]; then
|
|
591
|
+
return 0
|
|
592
|
+
fi
|
|
593
|
+
|
|
594
|
+
local gap_id="gap-${incident_id}"
|
|
595
|
+
local gap_file="${HARNESS_GAPS_DIR}/${gap_id}.json"
|
|
596
|
+
local sla_hours
|
|
597
|
+
|
|
598
|
+
case "$severity" in
|
|
599
|
+
P0) sla_hours="$HARNESS_GAP_P0_SLA" ;;
|
|
600
|
+
P1) sla_hours="$HARNESS_GAP_P1_SLA" ;;
|
|
601
|
+
P2) sla_hours="$HARNESS_GAP_P2_SLA" ;;
|
|
602
|
+
*) sla_hours="$HARNESS_GAP_P2_SLA" ;;
|
|
603
|
+
esac
|
|
604
|
+
|
|
605
|
+
local created_at
|
|
606
|
+
created_at=$(now_iso)
|
|
607
|
+
local created_epoch
|
|
608
|
+
created_epoch=$(now_epoch)
|
|
609
|
+
local sla_deadline_epoch=$((created_epoch + sla_hours * 3600))
|
|
610
|
+
|
|
611
|
+
cat > "$gap_file" << EOF
|
|
612
|
+
{
|
|
613
|
+
"gap_id": "${gap_id}",
|
|
614
|
+
"incident_id": "${incident_id}",
|
|
615
|
+
"severity": "${severity}",
|
|
616
|
+
"root_cause": "${root_cause}",
|
|
617
|
+
"created_at": "${created_at}",
|
|
618
|
+
"created_epoch": ${created_epoch},
|
|
619
|
+
"sla_hours": ${sla_hours},
|
|
620
|
+
"sla_deadline_epoch": ${sla_deadline_epoch},
|
|
621
|
+
"status": "open",
|
|
622
|
+
"test_case_file": null,
|
|
623
|
+
"github_issue": null,
|
|
624
|
+
"resolved_at": null
|
|
625
|
+
}
|
|
626
|
+
EOF
|
|
627
|
+
|
|
628
|
+
info "Harness gap created: ${gap_id} (SLA: ${sla_hours}h)"
|
|
629
|
+
emit_event "harness_gap.created" "gap_id=${gap_id}" "incident=${incident_id}" "sla_hours=${sla_hours}"
|
|
630
|
+
|
|
631
|
+
# Auto-create GitHub issue for gap tracking
|
|
632
|
+
if [[ "$HARNESS_GAP_AUTO_CREATE" == "true" ]] && command -v gh &>/dev/null; then
|
|
633
|
+
local title="[HARNESS GAP] ${severity}: Add test case for ${root_cause}"
|
|
634
|
+
local body="## Harness Gap
|
|
635
|
+
|
|
636
|
+
**Incident:** \`${incident_id}\`
|
|
637
|
+
**Severity:** ${severity}
|
|
638
|
+
**Root Cause:** ${root_cause}
|
|
639
|
+
**SLA:** ${sla_hours} hours
|
|
640
|
+
|
|
641
|
+
## Required Action
|
|
642
|
+
Add a regression test case that covers this failure scenario.
|
|
643
|
+
|
|
644
|
+
## Acceptance Criteria
|
|
645
|
+
- [ ] Test case file created in \`scripts/\`
|
|
646
|
+
- [ ] Test reproduces the original failure condition
|
|
647
|
+
- [ ] Test passes after the fix is applied
|
|
648
|
+
- [ ] Gap record resolved via \`shipwright incident gap resolve ${gap_id} <test_file>\`
|
|
649
|
+
|
|
650
|
+
## Context
|
|
651
|
+
This gap was automatically created by the Shipwright incident commander.
|
|
652
|
+
Part of the Code Factory harness-gap loop: every production regression
|
|
653
|
+
must produce a harness test case within the SLA window.
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
*Auto-generated by Shipwright Code Factory*"
|
|
657
|
+
|
|
658
|
+
local issue_url
|
|
659
|
+
issue_url=$(gh issue create --title "$title" --body "$body" --label "harness-gap,shipwright" 2>/dev/null || echo "")
|
|
660
|
+
if [[ -n "$issue_url" ]]; then
|
|
661
|
+
local issue_num
|
|
662
|
+
issue_num=$(echo "$issue_url" | sed -n 's|.*/issues/\([0-9]*\)|\1|p')
|
|
663
|
+
jq --arg issue "$issue_num" '.github_issue = $issue' "$gap_file" > "${gap_file}.tmp" && mv "${gap_file}.tmp" "$gap_file"
|
|
664
|
+
success "Created harness gap issue: $issue_url"
|
|
665
|
+
fi
|
|
666
|
+
fi
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
resolve_harness_gap() {
|
|
670
|
+
local gap_id="$1"
|
|
671
|
+
local test_case_file="${2:-}"
|
|
672
|
+
|
|
673
|
+
local gap_file="${HARNESS_GAPS_DIR}/${gap_id}.json"
|
|
674
|
+
if [[ ! -f "$gap_file" ]]; then
|
|
675
|
+
error "Harness gap not found: ${gap_id}"
|
|
676
|
+
return 1
|
|
677
|
+
fi
|
|
678
|
+
|
|
679
|
+
load_harness_gap_policy
|
|
680
|
+
|
|
681
|
+
if [[ "$HARNESS_GAP_REQUIRE_TEST" == "true" && -z "$test_case_file" ]]; then
|
|
682
|
+
error "Test case file required to resolve gap (policy: requireTestCaseBeforeClose=true)"
|
|
683
|
+
echo "Usage: shipwright incident gap resolve ${gap_id} <test_case_file>"
|
|
684
|
+
return 1
|
|
685
|
+
fi
|
|
686
|
+
|
|
687
|
+
if [[ -n "$test_case_file" && ! -f "$test_case_file" ]]; then
|
|
688
|
+
error "Test case file not found: ${test_case_file}"
|
|
689
|
+
return 1
|
|
690
|
+
fi
|
|
691
|
+
|
|
692
|
+
local resolved_at
|
|
693
|
+
resolved_at=$(now_iso)
|
|
694
|
+
jq --arg resolved_at "$resolved_at" --arg test_file "${test_case_file:-null}" \
|
|
695
|
+
'.status = "resolved" | .resolved_at = $resolved_at | .test_case_file = $test_file' \
|
|
696
|
+
"$gap_file" > "${gap_file}.tmp" && mv "${gap_file}.tmp" "$gap_file"
|
|
697
|
+
|
|
698
|
+
success "Harness gap resolved: ${gap_id}"
|
|
699
|
+
emit_event "harness_gap.resolved" "gap_id=${gap_id}" "test_file=${test_case_file:-none}"
|
|
700
|
+
|
|
701
|
+
# Close the GitHub issue if it exists
|
|
702
|
+
local github_issue
|
|
703
|
+
github_issue=$(jq -r '.github_issue // empty' "$gap_file" 2>/dev/null)
|
|
704
|
+
if [[ -n "$github_issue" ]] && command -v gh &>/dev/null; then
|
|
705
|
+
gh issue close "$github_issue" --comment "Harness gap resolved. Test case: \`${test_case_file:-none}\`" 2>/dev/null || true
|
|
706
|
+
fi
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
cmd_gap() {
|
|
710
|
+
local subcmd="${1:-list}"
|
|
711
|
+
shift || true
|
|
712
|
+
|
|
713
|
+
mkdir -p "$HARNESS_GAPS_DIR"
|
|
714
|
+
|
|
715
|
+
case "$subcmd" in
|
|
716
|
+
create)
|
|
717
|
+
create_harness_gap "$@"
|
|
718
|
+
;;
|
|
719
|
+
resolve)
|
|
720
|
+
resolve_harness_gap "$@"
|
|
721
|
+
;;
|
|
722
|
+
list)
|
|
723
|
+
local current_epoch
|
|
724
|
+
current_epoch=$(now_epoch)
|
|
725
|
+
echo -e "${BOLD}Harness Gaps${RESET}"
|
|
726
|
+
echo -e "${DIM}────────────────────────────────────────────────────────────────${RESET}"
|
|
727
|
+
|
|
728
|
+
local gap_files
|
|
729
|
+
gap_files=$(find "$HARNESS_GAPS_DIR" -name 'gap-*.json' -type f 2>/dev/null || true)
|
|
730
|
+
|
|
731
|
+
if [[ -z "$gap_files" ]]; then
|
|
732
|
+
info "No harness gaps recorded"
|
|
733
|
+
return 0
|
|
734
|
+
fi
|
|
735
|
+
|
|
736
|
+
while IFS= read -r gf; do
|
|
737
|
+
[[ -z "$gf" ]] && continue
|
|
738
|
+
local gid sev status sla_deadline
|
|
739
|
+
gid=$(jq -r '.gap_id // "unknown"' "$gf" 2>/dev/null)
|
|
740
|
+
sev=$(jq -r '.severity // "P3"' "$gf" 2>/dev/null)
|
|
741
|
+
status=$(jq -r '.status // "open"' "$gf" 2>/dev/null)
|
|
742
|
+
sla_deadline=$(jq -r '.sla_deadline_epoch // 0' "$gf" 2>/dev/null)
|
|
743
|
+
|
|
744
|
+
local sla_remaining=""
|
|
745
|
+
if [[ "$status" == "open" ]]; then
|
|
746
|
+
local remaining=$((sla_deadline - current_epoch))
|
|
747
|
+
if [[ "$remaining" -lt 0 ]]; then
|
|
748
|
+
sla_remaining="${RED}OVERDUE${RESET}"
|
|
749
|
+
else
|
|
750
|
+
sla_remaining="$(format_duration "$remaining") remaining"
|
|
751
|
+
fi
|
|
752
|
+
else
|
|
753
|
+
sla_remaining="${GREEN}resolved${RESET}"
|
|
754
|
+
fi
|
|
755
|
+
|
|
756
|
+
printf " %-20s %-4s %-8s %b\n" "$gid" "$sev" "$status" "$sla_remaining"
|
|
757
|
+
done <<< "$gap_files"
|
|
758
|
+
;;
|
|
759
|
+
sla)
|
|
760
|
+
# Show SLA compliance metrics
|
|
761
|
+
load_harness_gap_policy
|
|
762
|
+
local current_epoch
|
|
763
|
+
current_epoch=$(now_epoch)
|
|
764
|
+
local total=0 resolved=0 overdue=0 within_sla=0
|
|
765
|
+
|
|
766
|
+
local gap_files
|
|
767
|
+
gap_files=$(find "$HARNESS_GAPS_DIR" -name 'gap-*.json' -type f 2>/dev/null || true)
|
|
768
|
+
|
|
769
|
+
while IFS= read -r gf; do
|
|
770
|
+
[[ -z "$gf" ]] && continue
|
|
771
|
+
((total++))
|
|
772
|
+
local status sla_deadline
|
|
773
|
+
status=$(jq -r '.status // "open"' "$gf" 2>/dev/null)
|
|
774
|
+
sla_deadline=$(jq -r '.sla_deadline_epoch // 0' "$gf" 2>/dev/null)
|
|
775
|
+
|
|
776
|
+
if [[ "$status" == "resolved" ]]; then
|
|
777
|
+
((resolved++))
|
|
778
|
+
((within_sla++))
|
|
779
|
+
elif [[ "$current_epoch" -gt "$sla_deadline" ]]; then
|
|
780
|
+
((overdue++))
|
|
781
|
+
fi
|
|
782
|
+
done <<< "$gap_files"
|
|
783
|
+
|
|
784
|
+
echo -e "${BOLD}Harness Gap SLA Compliance${RESET}"
|
|
785
|
+
echo -e "${DIM}────────────────────────────────────────────────────────────────${RESET}"
|
|
786
|
+
echo "Total gaps: $total"
|
|
787
|
+
echo "Resolved: $resolved"
|
|
788
|
+
echo "Overdue: $overdue"
|
|
789
|
+
echo "SLA compliance: $( [[ $total -gt 0 ]] && echo "$((within_sla * 100 / total))%" || echo "N/A" )"
|
|
790
|
+
;;
|
|
791
|
+
*)
|
|
792
|
+
echo "Usage: shipwright incident gap <create|resolve|list|sla>"
|
|
793
|
+
return 1
|
|
794
|
+
;;
|
|
795
|
+
esac
|
|
796
|
+
}
|
|
797
|
+
|
|
559
798
|
# ─── Stop Command ──────────────────────────────────────────────────────────
|
|
560
799
|
|
|
561
800
|
cmd_stop() {
|
|
@@ -589,6 +828,7 @@ show_help() {
|
|
|
589
828
|
echo -e " ${CYAN}show${RESET} <incident-id> Show details for an incident"
|
|
590
829
|
echo -e " ${CYAN}report${RESET} <incident-id> Generate post-mortem report"
|
|
591
830
|
echo -e " ${CYAN}stats${RESET} [format] Show incident statistics (table|json)"
|
|
831
|
+
echo -e " ${CYAN}gap${RESET} <cmd> Harness gap loop (list|create|resolve|sla)"
|
|
592
832
|
echo -e " ${CYAN}config${RESET} <cmd> Configure incident response (show|set)"
|
|
593
833
|
echo -e " ${CYAN}help${RESET} Show this help"
|
|
594
834
|
echo ""
|
|
@@ -627,6 +867,9 @@ main() {
|
|
|
627
867
|
stats)
|
|
628
868
|
cmd_stats "$@"
|
|
629
869
|
;;
|
|
870
|
+
gap)
|
|
871
|
+
cmd_gap "$@"
|
|
872
|
+
;;
|
|
630
873
|
config)
|
|
631
874
|
error "config command not yet implemented"
|
|
632
875
|
return 1
|
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="2.
|
|
11
|
+
VERSION="2.4.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
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="2.
|
|
7
|
+
VERSION="2.4.0"
|
|
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
package/scripts/sw-memory.sh
CHANGED
package/scripts/sw-otel.sh
CHANGED
package/scripts/sw-oversight.sh
CHANGED
package/scripts/sw-pipeline.sh
CHANGED
|
@@ -11,7 +11,7 @@ unset CLAUDECODE 2>/dev/null || true
|
|
|
11
11
|
# Ignore SIGHUP so tmux attach/detach doesn't kill long-running plan/design/review stages
|
|
12
12
|
trap '' HUP
|
|
13
13
|
|
|
14
|
-
VERSION="2.
|
|
14
|
+
VERSION="2.4.0"
|
|
15
15
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
16
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
17
17
|
|
package/scripts/sw-pm.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.4.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|