shipwright-cli 2.1.2 → 2.2.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.
Files changed (136) 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 +150 -0
  8. package/docs/AGI-PLATFORM-PLAN.md +126 -0
  9. package/docs/AGI-WHATS-NEXT.md +72 -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/helpers.sh +30 -1
  25. package/scripts/lib/pipeline-detection.sh +278 -0
  26. package/scripts/lib/pipeline-github.sh +196 -0
  27. package/scripts/lib/pipeline-intelligence.sh +1712 -0
  28. package/scripts/lib/pipeline-quality-checks.sh +1052 -0
  29. package/scripts/lib/pipeline-quality.sh +34 -0
  30. package/scripts/lib/pipeline-stages.sh +2488 -0
  31. package/scripts/lib/pipeline-state.sh +529 -0
  32. package/scripts/lib/policy.sh +32 -0
  33. package/scripts/sw +5 -1
  34. package/scripts/sw-activity.sh +35 -46
  35. package/scripts/sw-adaptive.sh +30 -39
  36. package/scripts/sw-adversarial.sh +30 -36
  37. package/scripts/sw-architecture-enforcer.sh +30 -33
  38. package/scripts/sw-auth.sh +30 -42
  39. package/scripts/sw-autonomous.sh +60 -40
  40. package/scripts/sw-changelog.sh +29 -30
  41. package/scripts/sw-checkpoint.sh +30 -18
  42. package/scripts/sw-ci.sh +30 -42
  43. package/scripts/sw-cleanup.sh +32 -15
  44. package/scripts/sw-code-review.sh +26 -32
  45. package/scripts/sw-connect.sh +30 -19
  46. package/scripts/sw-context.sh +30 -19
  47. package/scripts/sw-cost.sh +30 -40
  48. package/scripts/sw-daemon.sh +66 -36
  49. package/scripts/sw-dashboard.sh +31 -40
  50. package/scripts/sw-db.sh +30 -20
  51. package/scripts/sw-decompose.sh +30 -38
  52. package/scripts/sw-deps.sh +30 -41
  53. package/scripts/sw-developer-simulation.sh +30 -36
  54. package/scripts/sw-discovery.sh +36 -19
  55. package/scripts/sw-doc-fleet.sh +822 -0
  56. package/scripts/sw-docs-agent.sh +30 -36
  57. package/scripts/sw-docs.sh +29 -31
  58. package/scripts/sw-doctor.sh +52 -20
  59. package/scripts/sw-dora.sh +29 -34
  60. package/scripts/sw-durable.sh +30 -20
  61. package/scripts/sw-e2e-orchestrator.sh +36 -21
  62. package/scripts/sw-eventbus.sh +30 -17
  63. package/scripts/sw-feedback.sh +30 -41
  64. package/scripts/sw-fix.sh +30 -40
  65. package/scripts/sw-fleet-discover.sh +30 -41
  66. package/scripts/sw-fleet-viz.sh +30 -20
  67. package/scripts/sw-fleet.sh +30 -40
  68. package/scripts/sw-github-app.sh +30 -41
  69. package/scripts/sw-github-checks.sh +30 -41
  70. package/scripts/sw-github-deploy.sh +30 -41
  71. package/scripts/sw-github-graphql.sh +30 -38
  72. package/scripts/sw-guild.sh +30 -37
  73. package/scripts/sw-heartbeat.sh +30 -19
  74. package/scripts/sw-hygiene.sh +134 -42
  75. package/scripts/sw-incident.sh +30 -39
  76. package/scripts/sw-init.sh +31 -14
  77. package/scripts/sw-instrument.sh +30 -41
  78. package/scripts/sw-intelligence.sh +39 -44
  79. package/scripts/sw-jira.sh +31 -41
  80. package/scripts/sw-launchd.sh +30 -17
  81. package/scripts/sw-linear.sh +31 -41
  82. package/scripts/sw-logs.sh +32 -17
  83. package/scripts/sw-loop.sh +32 -19
  84. package/scripts/sw-memory.sh +32 -43
  85. package/scripts/sw-mission-control.sh +31 -40
  86. package/scripts/sw-model-router.sh +30 -20
  87. package/scripts/sw-otel.sh +30 -20
  88. package/scripts/sw-oversight.sh +30 -36
  89. package/scripts/sw-patrol-meta.sh +31 -0
  90. package/scripts/sw-pipeline-composer.sh +30 -39
  91. package/scripts/sw-pipeline-vitals.sh +30 -44
  92. package/scripts/sw-pipeline.sh +277 -6383
  93. package/scripts/sw-pm.sh +31 -41
  94. package/scripts/sw-pr-lifecycle.sh +30 -42
  95. package/scripts/sw-predictive.sh +32 -34
  96. package/scripts/sw-prep.sh +30 -19
  97. package/scripts/sw-ps.sh +32 -17
  98. package/scripts/sw-public-dashboard.sh +30 -40
  99. package/scripts/sw-quality.sh +42 -40
  100. package/scripts/sw-reaper.sh +32 -15
  101. package/scripts/sw-recruit.sh +428 -48
  102. package/scripts/sw-regression.sh +30 -38
  103. package/scripts/sw-release-manager.sh +30 -38
  104. package/scripts/sw-release.sh +29 -31
  105. package/scripts/sw-remote.sh +31 -40
  106. package/scripts/sw-replay.sh +30 -18
  107. package/scripts/sw-retro.sh +33 -42
  108. package/scripts/sw-scale.sh +41 -24
  109. package/scripts/sw-security-audit.sh +30 -20
  110. package/scripts/sw-self-optimize.sh +33 -37
  111. package/scripts/sw-session.sh +31 -15
  112. package/scripts/sw-setup.sh +30 -16
  113. package/scripts/sw-standup.sh +30 -20
  114. package/scripts/sw-status.sh +33 -13
  115. package/scripts/sw-strategic.sh +55 -43
  116. package/scripts/sw-stream.sh +33 -37
  117. package/scripts/sw-swarm.sh +30 -21
  118. package/scripts/sw-team-stages.sh +30 -38
  119. package/scripts/sw-templates.sh +31 -16
  120. package/scripts/sw-testgen.sh +30 -31
  121. package/scripts/sw-tmux-pipeline.sh +29 -31
  122. package/scripts/sw-tmux-role-color.sh +31 -0
  123. package/scripts/sw-tmux-status.sh +31 -0
  124. package/scripts/sw-tmux.sh +31 -15
  125. package/scripts/sw-trace.sh +30 -19
  126. package/scripts/sw-tracker-github.sh +31 -0
  127. package/scripts/sw-tracker-jira.sh +31 -0
  128. package/scripts/sw-tracker-linear.sh +31 -0
  129. package/scripts/sw-tracker.sh +30 -40
  130. package/scripts/sw-triage.sh +68 -61
  131. package/scripts/sw-upgrade.sh +30 -16
  132. package/scripts/sw-ux.sh +30 -35
  133. package/scripts/sw-webhook.sh +30 -25
  134. package/scripts/sw-widgets.sh +30 -19
  135. package/scripts/sw-worktree.sh +32 -15
  136. package/tmux/templates/doc-fleet.json +43 -0
@@ -7,43 +7,42 @@
7
7
  set -euo pipefail
8
8
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
9
9
 
10
- VERSION="2.1.2"
10
+ VERSION="2.2.1"
11
11
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
12
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
13
13
 
14
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
15
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
16
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
17
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
18
- GREEN='\033[38;2;74;222;128m' # success
19
- YELLOW='\033[38;2;250;204;21m' # warning
20
- RED='\033[38;2;248;113;113m' # error
21
- DIM='\033[2m'
22
- BOLD='\033[1m'
23
- RESET='\033[0m'
24
-
25
14
  # ─── Cross-platform compatibility ──────────────────────────────────────────
26
15
  [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
27
16
 
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 event_type="$1"; shift
36
- local events_file="${HOME}/.shipwright/events.jsonl"
37
- 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"
38
32
  local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
39
- while [[ $# -gt 0 ]]; do
40
- local key="${1%%=*}" val="${1#*=}"
41
- payload="${payload},\"${key}\":\"${val}\""
42
- shift
43
- done
44
- payload="${payload}}"
45
- echo "$payload" >> "$events_file"
46
- }
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}"
47
46
 
48
47
  # ─── Commit Parsing ──────────────────────────────────────────────────────────
49
48
 
@@ -8,30 +8,42 @@
8
8
  set -euo pipefail
9
9
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
10
10
 
11
- VERSION="2.1.2"
11
+ VERSION="2.2.1"
12
12
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
13
 
14
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
15
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
16
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
17
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
18
- GREEN='\033[38;2;74;222;128m' # success
19
- YELLOW='\033[38;2;250;204;21m' # warning
20
- RED='\033[38;2;248;113;113m' # error
21
- DIM='\033[2m'
22
- BOLD='\033[1m'
23
- RESET='\033[0m'
24
-
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
- # ─── 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
17
 
34
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
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}"
35
47
 
36
48
  # ─── Checkpoint Directory ───────────────────────────────────────────────────
37
49
  CHECKPOINT_DIR=".claude/pipeline-artifacts/checkpoints"
package/scripts/sw-ci.sh CHANGED
@@ -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.1"
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
  # ─── Generate Workflow YAML from Pipeline Template ──────────────────────────
60
48
 
@@ -5,24 +5,41 @@
5
5
  # ║ Default: dry-run (shows what would be cleaned). ║
6
6
  # ║ Use --force to actually kill sessions and remove files. ║
7
7
  # ╚═══════════════════════════════════════════════════════════════════════════╝
8
- VERSION="2.1.2"
8
+ VERSION="2.2.1"
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
- GREEN='\033[38;2;74;222;128m'
16
- YELLOW='\033[38;2;250;204;21m'
17
- RED='\033[38;2;248;113;113m'
18
- DIM='\033[2m'
19
- BOLD='\033[1m'
20
- RESET='\033[0m'
21
-
22
- info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
23
- success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
24
- warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
25
- 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}"
26
43
 
27
44
  # ─── Parse Args ──────────────────────────────────────────────────────────────
28
45
 
@@ -6,44 +6,38 @@
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.1"
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"; shift
36
- local entry="{\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$type\""
37
- while [[ $# -gt 0 ]]; do
38
- local key="${1%%=*}"; local val="${1#*=}"
39
- val="${val//\"/\\\"}"
40
- entry="$entry,\"${key}\":\"${val}\""
41
- shift
42
- done
43
- entry="$entry}"
44
- mkdir -p "$HOME/.shipwright"
45
- echo "$entry" >> "$HOME/.shipwright/events.jsonl"
46
- }
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 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}"
47
41
 
48
42
  # ─── Configuration ───────────────────────────────────────────────────────
49
43
  REVIEW_CONFIG="${REPO_DIR}/.claude/code-review.json"
@@ -8,29 +8,42 @@
8
8
  set -euo pipefail
9
9
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
10
10
 
11
- VERSION="2.1.2"
11
+ VERSION="2.2.1"
12
12
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
13
 
14
- # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
15
- CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
16
- PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
17
- BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
18
- GREEN='\033[38;2;74;222;128m' # success
19
- YELLOW='\033[38;2;250;204;21m' # warning
20
- RED='\033[38;2;248;113;113m' # error
21
- DIM='\033[2m'
22
- BOLD='\033[1m'
23
- RESET='\033[0m'
24
-
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
17
 
29
- # ─── Output Helpers ─────────────────────────────────────────────────────────
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; }
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}"
34
47
 
35
48
  # ─── Constants ──────────────────────────────────────────────────────────────
36
49
  SHIPWRIGHT_DIR="$HOME/.shipwright"
@@ -43,8 +56,6 @@ CONNECT_LOG="$SHIPWRIGHT_DIR/connect.log"
43
56
  DEFAULT_URL="http://localhost:8767"
44
57
  HEARTBEAT_INTERVAL=10
45
58
 
46
- now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
47
-
48
59
  ensure_dir() {
49
60
  mkdir -p "$SHIPWRIGHT_DIR"
50
61
  }
@@ -6,32 +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.1"
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"; }
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
  # ─── Paths ────────────────────────────────────────────────────────────────
37
48
  ARTIFACTS_DIR="${REPO_DIR}/.claude/pipeline-artifacts"
@@ -6,32 +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.1"
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
- # ─── 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
16
 
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
  format_duration() {
37
48
  local secs="$1"
@@ -44,27 +55,6 @@ format_duration() {
44
55
  fi
45
56
  }
46
57
 
47
- # ─── Structured Event Log ──────────────────────────────────────────────────
48
- EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
49
-
50
- emit_event() {
51
- local event_type="$1"
52
- shift
53
- local json_fields=""
54
- for kv in "$@"; do
55
- local key="${kv%%=*}"
56
- local val="${kv#*=}"
57
- if [[ "$val" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
58
- json_fields="${json_fields},\"${key}\":${val}"
59
- else
60
- val="${val//\"/\\\"}"
61
- json_fields="${json_fields},\"${key}\":\"${val}\""
62
- fi
63
- done
64
- mkdir -p "${HOME}/.shipwright"
65
- echo "{\"ts\":\"$(now_iso)\",\"ts_epoch\":$(now_epoch),\"type\":\"${event_type}\"${json_fields}}" >> "$EVENTS_FILE"
66
- }
67
-
68
58
  # ─── Cost Storage ──────────────────────────────────────────────────────────
69
59
  COST_DIR="${HOME}/.shipwright"
70
60
  COST_FILE="${COST_DIR}/costs.json"