shipwright-cli 2.1.2 → 2.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.
Files changed (129) hide show
  1. package/.claude/agents/devops-engineer.md +14 -12
  2. package/.claude/agents/doc-fleet-agent.md +99 -0
  3. package/.claude/agents/test-specialist.md +5 -3
  4. package/README.md +48 -27
  5. package/claude-code/CLAUDE.md.shipwright +2 -2
  6. package/config/policy.json +73 -0
  7. package/config/policy.schema.json +75 -0
  8. package/docs/AGI-PLATFORM-PLAN.md +122 -0
  9. package/docs/AGI-WHATS-NEXT.md +69 -0
  10. package/docs/KNOWN-ISSUES.md +1 -23
  11. package/docs/PLATFORM-TODO-BACKLOG.md +41 -0
  12. package/docs/PLATFORM-TODO-TRIAGE.md +56 -0
  13. package/docs/README.md +83 -0
  14. package/docs/TIPS.md +39 -2
  15. package/docs/config-policy.md +40 -0
  16. package/docs/definition-of-done.example.md +2 -0
  17. package/docs/patterns/README.md +5 -0
  18. package/docs/strategy/02-mission-and-brand.md +3 -3
  19. package/docs/strategy/README.md +4 -3
  20. package/docs/tmux-research/TMUX-AUDIT.md +2 -0
  21. package/docs/tmux-research/TMUX-RESEARCH-INDEX.md +17 -0
  22. package/package.json +3 -2
  23. package/scripts/lib/daemon-health.sh +32 -0
  24. package/scripts/lib/pipeline-quality.sh +23 -0
  25. package/scripts/lib/policy.sh +32 -0
  26. package/scripts/sw +5 -1
  27. package/scripts/sw-activity.sh +35 -46
  28. package/scripts/sw-adaptive.sh +30 -39
  29. package/scripts/sw-adversarial.sh +30 -36
  30. package/scripts/sw-architecture-enforcer.sh +30 -33
  31. package/scripts/sw-auth.sh +30 -42
  32. package/scripts/sw-autonomous.sh +60 -40
  33. package/scripts/sw-changelog.sh +29 -30
  34. package/scripts/sw-checkpoint.sh +30 -18
  35. package/scripts/sw-ci.sh +30 -42
  36. package/scripts/sw-cleanup.sh +32 -15
  37. package/scripts/sw-code-review.sh +26 -32
  38. package/scripts/sw-connect.sh +30 -19
  39. package/scripts/sw-context.sh +30 -19
  40. package/scripts/sw-cost.sh +30 -40
  41. package/scripts/sw-daemon.sh +66 -36
  42. package/scripts/sw-dashboard.sh +31 -40
  43. package/scripts/sw-db.sh +30 -20
  44. package/scripts/sw-decompose.sh +30 -38
  45. package/scripts/sw-deps.sh +30 -41
  46. package/scripts/sw-developer-simulation.sh +30 -36
  47. package/scripts/sw-discovery.sh +36 -19
  48. package/scripts/sw-doc-fleet.sh +822 -0
  49. package/scripts/sw-docs-agent.sh +30 -36
  50. package/scripts/sw-docs.sh +29 -31
  51. package/scripts/sw-doctor.sh +52 -20
  52. package/scripts/sw-dora.sh +29 -34
  53. package/scripts/sw-durable.sh +30 -20
  54. package/scripts/sw-e2e-orchestrator.sh +36 -21
  55. package/scripts/sw-eventbus.sh +30 -17
  56. package/scripts/sw-feedback.sh +30 -41
  57. package/scripts/sw-fix.sh +30 -40
  58. package/scripts/sw-fleet-discover.sh +30 -41
  59. package/scripts/sw-fleet-viz.sh +30 -20
  60. package/scripts/sw-fleet.sh +30 -40
  61. package/scripts/sw-github-app.sh +30 -41
  62. package/scripts/sw-github-checks.sh +30 -41
  63. package/scripts/sw-github-deploy.sh +30 -41
  64. package/scripts/sw-github-graphql.sh +30 -38
  65. package/scripts/sw-guild.sh +30 -37
  66. package/scripts/sw-heartbeat.sh +30 -19
  67. package/scripts/sw-hygiene.sh +134 -42
  68. package/scripts/sw-incident.sh +30 -39
  69. package/scripts/sw-init.sh +31 -14
  70. package/scripts/sw-instrument.sh +30 -41
  71. package/scripts/sw-intelligence.sh +39 -44
  72. package/scripts/sw-jira.sh +31 -41
  73. package/scripts/sw-launchd.sh +30 -17
  74. package/scripts/sw-linear.sh +31 -41
  75. package/scripts/sw-logs.sh +32 -17
  76. package/scripts/sw-loop.sh +32 -19
  77. package/scripts/sw-memory.sh +32 -43
  78. package/scripts/sw-mission-control.sh +31 -40
  79. package/scripts/sw-model-router.sh +30 -20
  80. package/scripts/sw-otel.sh +30 -20
  81. package/scripts/sw-oversight.sh +30 -36
  82. package/scripts/sw-patrol-meta.sh +31 -0
  83. package/scripts/sw-pipeline-composer.sh +30 -39
  84. package/scripts/sw-pipeline-vitals.sh +30 -44
  85. package/scripts/sw-pipeline.sh +275 -6388
  86. package/scripts/sw-pm.sh +31 -41
  87. package/scripts/sw-pr-lifecycle.sh +30 -42
  88. package/scripts/sw-predictive.sh +32 -34
  89. package/scripts/sw-prep.sh +30 -19
  90. package/scripts/sw-ps.sh +32 -17
  91. package/scripts/sw-public-dashboard.sh +30 -40
  92. package/scripts/sw-quality.sh +42 -40
  93. package/scripts/sw-reaper.sh +32 -15
  94. package/scripts/sw-recruit.sh +428 -48
  95. package/scripts/sw-regression.sh +30 -38
  96. package/scripts/sw-release-manager.sh +30 -38
  97. package/scripts/sw-release.sh +29 -31
  98. package/scripts/sw-remote.sh +31 -40
  99. package/scripts/sw-replay.sh +30 -18
  100. package/scripts/sw-retro.sh +33 -42
  101. package/scripts/sw-scale.sh +41 -24
  102. package/scripts/sw-security-audit.sh +30 -20
  103. package/scripts/sw-self-optimize.sh +33 -37
  104. package/scripts/sw-session.sh +31 -15
  105. package/scripts/sw-setup.sh +30 -16
  106. package/scripts/sw-standup.sh +30 -20
  107. package/scripts/sw-status.sh +33 -13
  108. package/scripts/sw-strategic.sh +55 -43
  109. package/scripts/sw-stream.sh +33 -37
  110. package/scripts/sw-swarm.sh +30 -21
  111. package/scripts/sw-team-stages.sh +30 -38
  112. package/scripts/sw-templates.sh +31 -16
  113. package/scripts/sw-testgen.sh +30 -31
  114. package/scripts/sw-tmux-pipeline.sh +29 -31
  115. package/scripts/sw-tmux-role-color.sh +31 -0
  116. package/scripts/sw-tmux-status.sh +31 -0
  117. package/scripts/sw-tmux.sh +31 -15
  118. package/scripts/sw-trace.sh +30 -19
  119. package/scripts/sw-tracker-github.sh +31 -0
  120. package/scripts/sw-tracker-jira.sh +31 -0
  121. package/scripts/sw-tracker-linear.sh +31 -0
  122. package/scripts/sw-tracker.sh +30 -40
  123. package/scripts/sw-triage.sh +68 -61
  124. package/scripts/sw-upgrade.sh +30 -16
  125. package/scripts/sw-ux.sh +30 -35
  126. package/scripts/sw-webhook.sh +30 -25
  127. package/scripts/sw-widgets.sh +30 -19
  128. package/scripts/sw-worktree.sh +32 -15
  129. package/tmux/templates/doc-fleet.json +43 -0
package/scripts/sw-pm.sh CHANGED
@@ -6,55 +6,45 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.1.2"
9
+ VERSION="2.2.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
12
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
13
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
14
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
15
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
16
- GREEN='\033[38;2;74;222;128m' # success
17
- YELLOW='\033[38;2;250;204;21m' # warning
18
- RED='\033[38;2;248;113;113m' # error
19
- DIM='\033[2m'
20
- BOLD='\033[1m'
21
- RESET='\033[0m'
22
-
23
12
  # ─── Cross-platform compatibility ──────────────────────────────────────────
24
13
  # shellcheck source=lib/compat.sh
25
14
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
26
-
27
- # ─── Output Helpers ─────────────────────────────────────────────────────────
28
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
29
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
30
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
31
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
32
-
33
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
34
- now_epoch() { date +%s; }
15
+ # Canonical helpers (colors, output, events)
16
+ # shellcheck source=lib/helpers.sh
17
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
18
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
19
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
20
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
21
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
22
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
23
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
24
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
25
+ now_epoch() { date +%s; }
26
+ fi
27
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
28
+ emit_event() {
29
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
30
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
31
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
32
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
33
+ }
34
+ fi
35
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
36
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
37
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
38
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
39
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
40
+ RED="${RED:-\033[38;2;248;113;113m}"
41
+ DIM="${DIM:-\033[2m}"
42
+ BOLD="${BOLD:-\033[1m}"
43
+ RESET="${RESET:-\033[0m}"
35
44
 
36
45
  # ─── PM History Storage ──────────────────────────────────────────────────────
37
46
  PM_HISTORY="${HOME}/.shipwright/pm-history.json"
38
47
 
39
- emit_event() {
40
- local event_type="$1"
41
- shift
42
- local json_fields=""
43
- for kv in "$@"; do
44
- local key="${kv%%=*}"
45
- local val="${kv#*=}"
46
- if [[ "$val" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
47
- json_fields="${json_fields},\"${key}\":${val}"
48
- else
49
- val="${val//\"/\\\"}"
50
- json_fields="${json_fields},\"${key}\":\"${val}\""
51
- fi
52
- done
53
- mkdir -p "${HOME}/.shipwright"
54
- local events_file="${HOME}/.shipwright/events.jsonl"
55
- echo "{\"ts\":\"$(now_iso)\",\"ts_epoch\":$(now_epoch),\"type\":\"${event_type}\"${json_fields}}" >> "$events_file"
56
- }
57
-
58
48
  # ─── Ensure PM history file exists ───────────────────────────────────────────
59
49
  ensure_pm_history() {
60
50
  mkdir -p "${HOME}/.shipwright"
@@ -329,7 +319,7 @@ recommend_team() {
329
319
 
330
320
  # Add security specialist if needed
331
321
  if [[ "$is_security" == "true" ]]; then
332
- roles="${roles},security"
322
+ roles="${roles},security-auditor"
333
323
  estimated_agents=$((estimated_agents + 1))
334
324
  confidence=$((confidence - 10))
335
325
  risk_factors="${risk_factors}; security-sensitive changes"
@@ -6,55 +6,43 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.1.2"
9
+ VERSION="2.2.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
13
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
14
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
15
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
16
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
17
- GREEN='\033[38;2;74;222;128m' # success
18
- YELLOW='\033[38;2;250;204;21m' # warning
19
- RED='\033[38;2;248;113;113m' # error
20
- DIM='\033[2m'
21
- BOLD='\033[1m'
22
- RESET='\033[0m'
23
-
24
13
  # ─── Cross-platform compatibility ──────────────────────────────────────────
25
14
  # shellcheck source=lib/compat.sh
26
15
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
27
16
 
28
- # ─── Output Helpers ─────────────────────────────────────────────────────────
29
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
30
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
31
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
32
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
33
-
34
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
35
- now_epoch() { date +%s; }
36
-
37
- # ─── Structured Event Log ──────────────────────────────────────────────────
38
- EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
39
-
40
- emit_event() {
41
- local event_type="$1"
42
- shift
43
- local json_fields=""
44
- for kv in "$@"; do
45
- local key="${kv%%=*}"
46
- local val="${kv#*=}"
47
- if [[ "$val" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
48
- json_fields="${json_fields},\"${key}\":${val}"
49
- else
50
- local escaped_val
51
- escaped_val=$(printf '%s' "$val" | jq -Rs '.' 2>/dev/null || printf '"%s"' "${val//\"/\\\"}")
52
- json_fields="${json_fields},\"${key}\":${escaped_val}"
53
- fi
54
- done
55
- mkdir -p "${HOME}/.shipwright"
56
- echo "{\"ts\":\"$(now_iso)\",\"ts_epoch\":$(now_epoch),\"type\":\"${event_type}\"${json_fields}}" >> "$EVENTS_FILE"
57
- }
17
+ # Canonical helpers (colors, output, events)
18
+ # shellcheck source=lib/helpers.sh
19
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
20
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
21
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
22
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
23
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
24
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
25
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
26
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
27
+ now_epoch() { date +%s; }
28
+ fi
29
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
+ emit_event() {
31
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
32
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
35
+ }
36
+ fi
37
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
38
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
39
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
40
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
41
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
42
+ RED="${RED:-\033[38;2;248;113;113m}"
43
+ DIM="${DIM:-\033[2m}"
44
+ BOLD="${BOLD:-\033[1m}"
45
+ RESET="${RESET:-\033[0m}"
58
46
 
59
47
  # ─── Configuration Helpers ──────────────────────────────────────────────────
60
48
 
@@ -6,51 +6,47 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.1.2"
9
+ VERSION="2.2.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
13
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
14
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
15
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
16
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
17
- GREEN='\033[38;2;74;222;128m' # success
18
- YELLOW='\033[38;2;250;204;21m' # warning
19
- RED='\033[38;2;248;113;113m' # error
20
- DIM='\033[2m'
21
- BOLD='\033[1m'
22
- RESET='\033[0m'
23
-
24
13
  # ─── Cross-platform compatibility ──────────────────────────────────────────
25
14
  # shellcheck source=lib/compat.sh
26
15
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
27
16
 
28
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
29
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
30
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
31
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
32
-
33
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
34
- now_epoch() { date +%s; }
17
+ # Canonical helpers (colors, output, events)
18
+ # shellcheck source=lib/helpers.sh
19
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
20
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
21
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
22
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
23
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
24
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
25
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
26
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
27
+ now_epoch() { date +%s; }
28
+ fi
29
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
+ emit_event() {
31
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
32
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
35
+ }
36
+ fi
37
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
38
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
39
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
40
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
41
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
42
+ RED="${RED:-\033[38;2;248;113;113m}"
43
+ DIM="${DIM:-\033[2m}"
44
+ BOLD="${BOLD:-\033[1m}"
45
+ RESET="${RESET:-\033[0m}"
35
46
 
36
47
  # ─── Structured Event Log ──────────────────────────────────────────────────
37
48
  EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
38
49
 
39
- emit_event() {
40
- local event_type="$1"; shift
41
- local json_fields=""
42
- for kv in "$@"; do
43
- local key="${kv%%=*}"; local val="${kv#*=}"
44
- if [[ "$val" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
45
- json_fields="${json_fields},\"${key}\":${val}"
46
- else
47
- val="${val//\"/\\\"}"; json_fields="${json_fields},\"${key}\":\"${val}\""
48
- fi
49
- done
50
- mkdir -p "${HOME}/.shipwright"
51
- echo "{\"ts\":\"$(now_iso)\",\"ts_epoch\":$(now_epoch),\"type\":\"${event_type}\"${json_fields}}" >> "$EVENTS_FILE"
52
- }
53
-
54
50
  # ─── Intelligence Engine (optional) ────────────────────────────────────────
55
51
  INTELLIGENCE_AVAILABLE=false
56
52
  if [[ -f "$SCRIPT_DIR/sw-intelligence.sh" ]]; then
@@ -172,6 +168,8 @@ _predictive_record_anomaly() {
172
168
  --argjson baseline "$baseline" \
173
169
  '{ts: $ts, ts_epoch: $epoch, stage: $stage, metric: $metric, severity: $severity, value: $value, baseline: $baseline, confirmed: null}')
174
170
  echo "$record" >> "$tracking_file"
171
+ # Rotate anomaly tracking to prevent unbounded growth
172
+ type rotate_jsonl &>/dev/null 2>&1 && rotate_jsonl "$tracking_file" 5000
175
173
  }
176
174
 
177
175
  # predictive_confirm_anomaly <stage> <metric_name> <was_real_failure>
@@ -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.1.2"
9
+ VERSION="2.2.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
 
12
12
  # ─── Handle subcommands ───────────────────────────────────────────────────────
@@ -15,27 +15,38 @@ if [[ "${1:-}" == "test" ]]; then
15
15
  exec "$SCRIPT_DIR/sw-prep-test.sh" "$@"
16
16
  fi
17
17
 
18
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
19
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
20
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
21
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
22
- GREEN='\033[38;2;74;222;128m' # success
23
- YELLOW='\033[38;2;250;204;21m' # warning
24
- RED='\033[38;2;248;113;113m' # error
25
- DIM='\033[2m'
26
- BOLD='\033[1m'
27
- RESET='\033[0m'
28
-
29
18
  # ─── Cross-platform compatibility ──────────────────────────────────────────
30
19
  # shellcheck source=lib/compat.sh
31
20
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
32
- # ─── Output Helpers ─────────────────────────────────────────────────────────
33
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
34
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
35
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
36
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
37
-
38
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
21
+ # Canonical helpers (colors, output, events)
22
+ # shellcheck source=lib/helpers.sh
23
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
24
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
25
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
26
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
27
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
28
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
29
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
30
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
31
+ now_epoch() { date +%s; }
32
+ fi
33
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
34
+ emit_event() {
35
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
36
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
37
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
38
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
39
+ }
40
+ fi
41
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
42
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
43
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
44
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
45
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
46
+ RED="${RED:-\033[38;2;248;113;113m}"
47
+ DIM="${DIM:-\033[2m}"
48
+ BOLD="${BOLD:-\033[1m}"
49
+ RESET="${RESET:-\033[0m}"
39
50
 
40
51
  # ─── Defaults ───────────────────────────────────────────────────────────────
41
52
  FORCE=false
package/scripts/sw-ps.sh CHANGED
@@ -5,26 +5,41 @@
5
5
  # ║ Displays a table of agents running in claude-* tmux windows with ║
6
6
  # ║ PID, status, idle time, and pane references. ║
7
7
  # ╚═══════════════════════════════════════════════════════════════════════════╝
8
- VERSION="2.1.2"
8
+ VERSION="2.2.0"
9
9
  set -euo pipefail
10
10
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
11
11
 
12
- # ─── Colors ──────────────────────────────────────────────────────────────────
13
- CYAN='\033[38;2;0;212;255m'
14
- PURPLE='\033[38;2;124;58;237m'
15
- BLUE='\033[38;2;0;102;255m'
16
- GREEN='\033[38;2;74;222;128m'
17
- YELLOW='\033[38;2;250;204;21m'
18
- RED='\033[38;2;248;113;113m'
19
- DIM='\033[2m'
20
- BOLD='\033[1m'
21
- RESET='\033[0m'
22
-
23
- # ─── Helpers ─────────────────────────────────────────────────────────────────
24
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
25
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
26
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
27
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
12
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+
14
+ # Canonical helpers (colors, output, events)
15
+ # shellcheck source=lib/helpers.sh
16
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
17
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
18
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
19
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
20
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
21
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
22
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
23
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
24
+ now_epoch() { date +%s; }
25
+ fi
26
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
27
+ emit_event() {
28
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
29
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
30
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
31
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
32
+ }
33
+ fi
34
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
35
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
36
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
37
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
38
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
39
+ RED="${RED:-\033[38;2;248;113;113m}"
40
+ DIM="${DIM:-\033[2m}"
41
+ BOLD="${BOLD:-\033[1m}"
42
+ RESET="${RESET:-\033[0m}"
28
43
 
29
44
  # ─── Format idle time ───────────────────────────────────────────────────────
30
45
  format_idle() {
@@ -6,58 +6,48 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.1.2"
9
+ VERSION="2.2.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
13
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
14
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
15
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
16
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
17
- GREEN='\033[38;2;74;222;128m' # success
18
- YELLOW='\033[38;2;250;204;21m' # warning
19
- RED='\033[38;2;248;113;113m' # error
20
- DIM='\033[2m'
21
- BOLD='\033[1m'
22
- RESET='\033[0m'
23
-
24
13
  # ─── Cross-platform compatibility ──────────────────────────────────────────
25
14
  # shellcheck source=lib/compat.sh
26
15
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
27
16
 
28
- # ─── Output Helpers ─────────────────────────────────────────────────────────
29
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
30
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
31
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
32
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
33
-
34
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
35
- now_epoch() { date +%s; }
17
+ # Canonical helpers (colors, output, events)
18
+ # shellcheck source=lib/helpers.sh
19
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
20
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
21
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
22
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
23
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
24
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
25
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
26
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
27
+ now_epoch() { date +%s; }
28
+ fi
29
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
30
+ emit_event() {
31
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
32
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
33
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
34
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
35
+ }
36
+ fi
37
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
38
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
39
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
40
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
41
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
42
+ RED="${RED:-\033[38;2;248;113;113m}"
43
+ DIM="${DIM:-\033[2m}"
44
+ BOLD="${BOLD:-\033[1m}"
45
+ RESET="${RESET:-\033[0m}"
36
46
 
37
47
  # ─── Paths ──────────────────────────────────────────────────────────────────
38
48
  PUB_DASH_DIR="${HOME}/.shipwright/public-dashboard"
39
49
  SHARE_LINKS_FILE="${PUB_DASH_DIR}/share-links.json"
40
50
  SHARE_CONFIG_FILE="${PUB_DASH_DIR}/config.json"
41
- EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
42
-
43
- # ─── Structured Event Log ──────────────────────────────────────────────────
44
- emit_event() {
45
- local event_type="$1"
46
- shift
47
- local json_fields=""
48
- for kv in "$@"; do
49
- local key="${kv%%=*}"
50
- local val="${kv#*=}"
51
- if [[ "$val" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
52
- json_fields="${json_fields},\"${key}\":${val}"
53
- else
54
- val="${val//\"/\\\"}"
55
- json_fields="${json_fields},\"${key}\":\"${val}\""
56
- fi
57
- done
58
- mkdir -p "${HOME}/.shipwright"
59
- echo "{\"ts\":\"$(now_iso)\",\"ts_epoch\":$(now_epoch),\"type\":\"${event_type}\"${json_fields}}" >> "$EVENTS_FILE"
60
- }
61
51
 
62
52
  # ─── Initialization ──────────────────────────────────────────────────────────
63
53
  ensure_dirs() {
@@ -6,53 +6,55 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="2.1.2"
9
+ VERSION="2.2.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
13
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
14
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
15
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
16
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
17
- GREEN='\033[38;2;74;222;128m' # success
18
- YELLOW='\033[38;2;250;204;21m' # warning
19
- RED='\033[38;2;248;113;113m' # error
20
- DIM='\033[2m'
21
- BOLD='\033[1m'
22
- RESET='\033[0m'
23
-
24
13
  # ─── Cross-platform compatibility ──────────────────────────────────────────
25
14
  # shellcheck source=lib/compat.sh
26
15
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
27
-
28
- # ─── Helpers ─────────────────────────────────────────────────────────────────
29
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
30
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
31
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
32
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
33
-
34
- emit_event() {
35
- local type="$1"
36
- shift
37
- local entry="{\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$type\""
38
- while [[ $# -gt 0 ]]; do
39
- entry="$entry,\"${1%%=*}\":\"${1#*=}\""
40
- shift
41
- done
42
- entry="$entry}"
43
- mkdir -p "$HOME/.shipwright"
44
- echo "$entry" >> "$HOME/.shipwright/events.jsonl"
45
- }
46
-
47
- # ─── Config ──────────────────────────────────────────────────────────────────
16
+ # Canonical helpers (colors, output, events)
17
+ # shellcheck source=lib/helpers.sh
18
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
19
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
20
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
21
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
22
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
23
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
24
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
25
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
26
+ now_epoch() { date +%s; }
27
+ fi
28
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
29
+ emit_event() {
30
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
31
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
32
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
33
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
34
+ }
35
+ fi
36
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
37
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
38
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
39
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
40
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
41
+ RED="${RED:-\033[38;2;248;113;113m}"
42
+ DIM="${DIM:-\033[2m}"
43
+ BOLD="${BOLD:-\033[1m}"
44
+ RESET="${RESET:-\033[0m}"
45
+ # Policy + quality thresholds (lib/pipeline-quality.sh sets QUALITY_* from config/policy.json)
46
+ [[ -f "$SCRIPT_DIR/lib/pipeline-quality.sh" ]] && source "$SCRIPT_DIR/lib/pipeline-quality.sh"
47
+
48
+ # ─── Config (from policy via pipeline-quality.sh when present) ─────────────────
48
49
  ARTIFACTS_DIR="${ARTIFACTS_DIR:-./.claude/pipeline-artifacts}"
49
- COVERAGE_THRESHOLD="${COVERAGE_THRESHOLD:-70}"
50
- QUALITY_THRESHOLD="${QUALITY_THRESHOLD:-70}"
51
- TEST_PASS_WEIGHT=0.30
52
- COVERAGE_WEIGHT=0.20
53
- SECURITY_WEIGHT=0.20
54
- ARCHITECTURE_WEIGHT=0.15
55
- CORRECTNESS_WEIGHT=0.15
50
+ COVERAGE_THRESHOLD="${QUALITY_COVERAGE_THRESHOLD:-70}"
51
+ QUALITY_THRESHOLD="${QUALITY_GATE_SCORE_THRESHOLD:-70}"
52
+ # Audit weights from policy (via pipeline-quality.sh) — expressed as decimals
53
+ TEST_PASS_WEIGHT=$(awk -v w="${QUALITY_WEIGHT_TEST_PASS:-30}" 'BEGIN{printf "%.2f", w/100}')
54
+ COVERAGE_WEIGHT=$(awk -v w="${QUALITY_WEIGHT_COVERAGE:-20}" 'BEGIN{printf "%.2f", w/100}')
55
+ SECURITY_WEIGHT=$(awk -v w="${QUALITY_WEIGHT_SECURITY:-20}" 'BEGIN{printf "%.2f", w/100}')
56
+ ARCHITECTURE_WEIGHT=$(awk -v w="${QUALITY_WEIGHT_ARCHITECTURE:-15}" 'BEGIN{printf "%.2f", w/100}')
57
+ CORRECTNESS_WEIGHT=$(awk -v w="${QUALITY_WEIGHT_CORRECTNESS:-15}" 'BEGIN{printf "%.2f", w/100}')
56
58
 
57
59
  # ─── Validate subcommand ────────────────────────────────────────────────────
58
60
  validate_quality() {