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
@@ -5,49 +5,45 @@
5
5
  # ║ Streams tmux pane output in real-time to the dashboard or CLI. ║
6
6
  # ║ Captures output periodically, tags by agent/team, supports replay. ║
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)"
28
13
 
29
14
  # ─── Cross-platform compatibility ──────────────────────────────────────────
30
- _COMPAT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/compat.sh"
31
15
  # shellcheck source=lib/compat.sh
32
- [[ -f "$_COMPAT" ]] && source "$_COMPAT"
33
-
34
- # ─── Event logging ─────────────────────────────────────────────────────────
35
- emit_event() {
36
- local event_type="$1"
37
- shift
38
- local json_fields=""
39
- for kv in "$@"; do
40
- local key="${kv%%=*}"
41
- local value="${kv#*=}"
42
- value="${value//\"/\\\"}" # Escape quotes
43
- json_fields="${json_fields}\"${key}\": \"${value}\", "
44
- done
45
- json_fields="${json_fields%, }" # Remove trailing comma
46
- local ts
47
- ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
48
- echo "{\"timestamp\": \"${ts}\", \"type\": \"${event_type}\", ${json_fields}}" >> \
49
- "${HOME}/.shipwright/events.jsonl" 2>/dev/null || true
50
- }
16
+ [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
17
+
18
+ # Canonical helpers (colors, output, events)
19
+ # shellcheck source=lib/helpers.sh
20
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
21
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
22
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
23
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
24
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
25
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
26
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
27
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
28
+ now_epoch() { date +%s; }
29
+ fi
30
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
31
+ emit_event() {
32
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
33
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
34
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
35
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
36
+ }
37
+ fi
38
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
39
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
40
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
41
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
42
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
43
+ RED="${RED:-\033[38;2;248;113;113m}"
44
+ DIM="${DIM:-\033[2m}"
45
+ BOLD="${BOLD:-\033[1m}"
46
+ RESET="${RESET:-\033[0m}"
51
47
 
52
48
  # ─── Stream configuration ─────────────────────────────────────────────────────
53
49
  STREAM_CONFIG="${HOME}/.shipwright/stream-config.json"
@@ -6,33 +6,42 @@
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
- # ─── 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; }
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}"
36
45
 
37
46
  # ─── Constants ──────────────────────────────────────────────────────────────
38
47
  SWARM_DIR="${HOME}/.shipwright/swarm"
@@ -6,55 +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
- # ─── 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
  # ─── Structured Event Log ──────────────────────────────────────────────────
38
48
  EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
39
49
 
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
- val="${val//\"/\\\"}"
51
- json_fields="${json_fields},\"${key}\":\"${val}\""
52
- fi
53
- done
54
- mkdir -p "${HOME}/.shipwright"
55
- echo "{\"ts\":\"$(now_iso)\",\"ts_epoch\":$(now_epoch),\"type\":\"${event_type}\"${json_fields}}" >> "$EVENTS_FILE"
56
- }
57
-
58
50
  # ─── Team Configuration ─────────────────────────────────────────────────────
59
51
  TEAM_STATE_DIR="${HOME}/.shipwright/team-state"
60
52
  INTELLIGENCE_CACHE="${REPO_DIR}/.claude/intelligence-cache.json"
@@ -5,30 +5,45 @@
5
5
  # ║ Templates define reusable agent team configurations (roles, layout, ║
6
6
  # ║ focus areas) that shipwright session --template can use to scaffold teams. ║
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
12
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
24
13
 
25
14
  # ─── Cross-platform compatibility ──────────────────────────────────────────
26
15
  # shellcheck source=lib/compat.sh
27
16
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
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; }
17
+
18
+ # Canonical helpers (colors, output, events)
19
+ # shellcheck source=lib/helpers.sh
20
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
21
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
22
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
23
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
24
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
25
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
26
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
27
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
28
+ now_epoch() { date +%s; }
29
+ fi
30
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
31
+ emit_event() {
32
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
33
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
34
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
35
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
36
+ }
37
+ fi
38
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
39
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
40
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
41
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
42
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
43
+ RED="${RED:-\033[38;2;248;113;113m}"
44
+ DIM="${DIM:-\033[2m}"
45
+ BOLD="${BOLD:-\033[1m}"
46
+ RESET="${RESET:-\033[0m}"
32
47
 
33
48
  # ─── Template Discovery ─────────────────────────────────────────────────────
34
49
  REPO_TEMPLATES_DIR="$(cd "$SCRIPT_DIR/../tmux/templates" 2>/dev/null && pwd)" || REPO_TEMPLATES_DIR=""
@@ -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,39 +15,38 @@ if [[ "${1:-}" == "test" ]]; then
15
15
  exec "$SCRIPT_DIR/sw-testgen-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
-
33
- # ─── Output Helpers ─────────────────────────────────────────────────────────
34
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
35
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
36
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
37
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
38
-
39
- emit_event() {
40
- local type="$1"
41
- shift
42
- local json_data="{\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$type\""
43
- for pair in "$@"; do
44
- json_data="$json_data,\"$pair\""
45
- done
46
- json_data="$json_data}"
47
- echo "$json_data" >> "${EVENTS_FILE:-.shipwright-events.jsonl}"
48
- }
49
-
50
- 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}"
51
50
 
52
51
  # ─── Configuration ───────────────────────────────────────────────────────────
53
52
  PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
@@ -6,45 +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
- # ─── Helpers ─────────────────────────────────────────────────────────────────
29
-
30
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
31
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
32
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
33
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
34
-
35
- emit_event() {
36
- local event_type="$1"; shift
37
- local events_file="${HOME}/.shipwright/events.jsonl"
38
- mkdir -p "$(dirname "$events_file")"
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"
39
32
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
40
- while [[ $# -gt 0 ]]; do
41
- local key="${1%%=*}" val="${1#*=}"
42
- payload="${payload},\"${key}\":\"${val}\""
43
- shift
44
- done
45
- payload="${payload}}"
46
- echo "$payload" >> "$events_file"
47
- }
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}"
48
46
 
49
47
  # Get daemon session name
50
48
  get_daemon_session() {
@@ -18,6 +18,37 @@
18
18
  # ╚═══════════════════════════════════════════════════════════════════════════╝
19
19
  set -euo pipefail
20
20
 
21
+ SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
22
+ # Canonical helpers (colors, output, events)
23
+ # shellcheck source=lib/helpers.sh
24
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
25
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
26
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
27
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
28
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
29
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
30
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
31
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
32
+ now_epoch() { date +%s; }
33
+ fi
34
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
35
+ emit_event() {
36
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
37
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
38
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
39
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
40
+ }
41
+ fi
42
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
43
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
44
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
45
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
46
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
47
+ RED="${RED:-\033[38;2;248;113;113m}"
48
+ DIM="${DIM:-\033[2m}"
49
+ BOLD="${BOLD:-\033[1m}"
50
+ RESET="${RESET:-\033[0m}"
51
+
21
52
  # Get the active pane's title
22
53
  PANE_TITLE="$(tmux display-message -p '#{pane_title}' 2>/dev/null || echo "")"
23
54
 
@@ -8,6 +8,37 @@
8
8
  # ╚═══════════════════════════════════════════════════════════════════════════╝
9
9
  set -euo pipefail
10
10
 
11
+ SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
12
+ # Canonical helpers (colors, output, events)
13
+ # shellcheck source=lib/helpers.sh
14
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
15
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
16
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
17
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
18
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
19
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
20
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
21
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
22
+ now_epoch() { date +%s; }
23
+ fi
24
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
25
+ emit_event() {
26
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
27
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
28
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
29
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
30
+ }
31
+ fi
32
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
33
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
34
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
35
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
36
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
37
+ RED="${RED:-\033[38;2;248;113;113m}"
38
+ DIM="${DIM:-\033[2m}"
39
+ BOLD="${BOLD:-\033[1m}"
40
+ RESET="${RESET:-\033[0m}"
41
+
11
42
  # ─── Stage colors (match Shipwright brand palette) ────────────────────────
12
43
  # Each pipeline stage gets a distinct color for instant visual recognition
13
44
  stage_color() {
@@ -11,30 +11,46 @@
11
11
  # ║ shipwright tmux fix — Auto-fix common issues ║
12
12
  # ║ shipwright tmux reload — Reload tmux config ║
13
13
  # ╚═══════════════════════════════════════════════════════════════════════════╝
14
- VERSION="2.1.2"
14
+ VERSION="2.2.0"
15
15
  set -euo pipefail
16
16
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
17
17
 
18
18
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19
19
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
20
20
 
21
- # ─── Colors ──────────────────────────────────────────────────────────────────
22
- CYAN='\033[38;2;0;212;255m'
23
- PURPLE='\033[38;2;124;58;237m'
24
- GREEN='\033[38;2;74;222;128m'
25
- YELLOW='\033[38;2;250;204;21m'
26
- RED='\033[38;2;248;113;113m'
27
- DIM='\033[2m'
28
- BOLD='\033[1m'
29
- RESET='\033[0m'
30
-
31
21
  # ─── Cross-platform compatibility ──────────────────────────────────────────
32
22
  # shellcheck source=lib/compat.sh
33
23
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
34
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
35
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
36
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
37
- error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
24
+
25
+ # Canonical helpers (colors, output, events)
26
+ # shellcheck source=lib/helpers.sh
27
+ [[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
28
+ # Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
29
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
30
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
31
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
32
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
33
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
34
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
35
+ now_epoch() { date +%s; }
36
+ fi
37
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
38
+ emit_event() {
39
+ local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
40
+ local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
41
+ while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
42
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
43
+ }
44
+ fi
45
+ CYAN="${CYAN:-\033[38;2;0;212;255m}"
46
+ PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
47
+ BLUE="${BLUE:-\033[38;2;0;102;255m}"
48
+ GREEN="${GREEN:-\033[38;2;74;222;128m}"
49
+ YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
50
+ RED="${RED:-\033[38;2;248;113;113m}"
51
+ DIM="${DIM:-\033[2m}"
52
+ BOLD="${BOLD:-\033[1m}"
53
+ RESET="${RESET:-\033[0m}"
38
54
 
39
55
  PASS=0
40
56
  WARN=0