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.
- package/.claude/agents/devops-engineer.md +14 -12
- package/.claude/agents/doc-fleet-agent.md +99 -0
- package/.claude/agents/test-specialist.md +5 -3
- package/README.md +48 -27
- package/claude-code/CLAUDE.md.shipwright +2 -2
- package/config/policy.json +73 -0
- package/config/policy.schema.json +75 -0
- package/docs/AGI-PLATFORM-PLAN.md +122 -0
- package/docs/AGI-WHATS-NEXT.md +69 -0
- package/docs/KNOWN-ISSUES.md +1 -23
- package/docs/PLATFORM-TODO-BACKLOG.md +41 -0
- package/docs/PLATFORM-TODO-TRIAGE.md +56 -0
- package/docs/README.md +83 -0
- package/docs/TIPS.md +39 -2
- package/docs/config-policy.md +40 -0
- package/docs/definition-of-done.example.md +2 -0
- package/docs/patterns/README.md +5 -0
- package/docs/strategy/02-mission-and-brand.md +3 -3
- package/docs/strategy/README.md +4 -3
- package/docs/tmux-research/TMUX-AUDIT.md +2 -0
- package/docs/tmux-research/TMUX-RESEARCH-INDEX.md +17 -0
- package/package.json +3 -2
- package/scripts/lib/daemon-health.sh +32 -0
- package/scripts/lib/pipeline-quality.sh +23 -0
- package/scripts/lib/policy.sh +32 -0
- package/scripts/sw +5 -1
- package/scripts/sw-activity.sh +35 -46
- package/scripts/sw-adaptive.sh +30 -39
- package/scripts/sw-adversarial.sh +30 -36
- package/scripts/sw-architecture-enforcer.sh +30 -33
- package/scripts/sw-auth.sh +30 -42
- package/scripts/sw-autonomous.sh +60 -40
- package/scripts/sw-changelog.sh +29 -30
- package/scripts/sw-checkpoint.sh +30 -18
- package/scripts/sw-ci.sh +30 -42
- package/scripts/sw-cleanup.sh +32 -15
- package/scripts/sw-code-review.sh +26 -32
- package/scripts/sw-connect.sh +30 -19
- package/scripts/sw-context.sh +30 -19
- package/scripts/sw-cost.sh +30 -40
- package/scripts/sw-daemon.sh +66 -36
- package/scripts/sw-dashboard.sh +31 -40
- package/scripts/sw-db.sh +30 -20
- package/scripts/sw-decompose.sh +30 -38
- package/scripts/sw-deps.sh +30 -41
- package/scripts/sw-developer-simulation.sh +30 -36
- package/scripts/sw-discovery.sh +36 -19
- package/scripts/sw-doc-fleet.sh +822 -0
- package/scripts/sw-docs-agent.sh +30 -36
- package/scripts/sw-docs.sh +29 -31
- package/scripts/sw-doctor.sh +52 -20
- package/scripts/sw-dora.sh +29 -34
- package/scripts/sw-durable.sh +30 -20
- package/scripts/sw-e2e-orchestrator.sh +36 -21
- package/scripts/sw-eventbus.sh +30 -17
- package/scripts/sw-feedback.sh +30 -41
- package/scripts/sw-fix.sh +30 -40
- package/scripts/sw-fleet-discover.sh +30 -41
- package/scripts/sw-fleet-viz.sh +30 -20
- package/scripts/sw-fleet.sh +30 -40
- package/scripts/sw-github-app.sh +30 -41
- package/scripts/sw-github-checks.sh +30 -41
- package/scripts/sw-github-deploy.sh +30 -41
- package/scripts/sw-github-graphql.sh +30 -38
- package/scripts/sw-guild.sh +30 -37
- package/scripts/sw-heartbeat.sh +30 -19
- package/scripts/sw-hygiene.sh +134 -42
- package/scripts/sw-incident.sh +30 -39
- package/scripts/sw-init.sh +31 -14
- package/scripts/sw-instrument.sh +30 -41
- package/scripts/sw-intelligence.sh +39 -44
- package/scripts/sw-jira.sh +31 -41
- package/scripts/sw-launchd.sh +30 -17
- package/scripts/sw-linear.sh +31 -41
- package/scripts/sw-logs.sh +32 -17
- package/scripts/sw-loop.sh +32 -19
- package/scripts/sw-memory.sh +32 -43
- package/scripts/sw-mission-control.sh +31 -40
- package/scripts/sw-model-router.sh +30 -20
- package/scripts/sw-otel.sh +30 -20
- package/scripts/sw-oversight.sh +30 -36
- package/scripts/sw-patrol-meta.sh +31 -0
- package/scripts/sw-pipeline-composer.sh +30 -39
- package/scripts/sw-pipeline-vitals.sh +30 -44
- package/scripts/sw-pipeline.sh +275 -6388
- package/scripts/sw-pm.sh +31 -41
- package/scripts/sw-pr-lifecycle.sh +30 -42
- package/scripts/sw-predictive.sh +32 -34
- package/scripts/sw-prep.sh +30 -19
- package/scripts/sw-ps.sh +32 -17
- package/scripts/sw-public-dashboard.sh +30 -40
- package/scripts/sw-quality.sh +42 -40
- package/scripts/sw-reaper.sh +32 -15
- package/scripts/sw-recruit.sh +428 -48
- package/scripts/sw-regression.sh +30 -38
- package/scripts/sw-release-manager.sh +30 -38
- package/scripts/sw-release.sh +29 -31
- package/scripts/sw-remote.sh +31 -40
- package/scripts/sw-replay.sh +30 -18
- package/scripts/sw-retro.sh +33 -42
- package/scripts/sw-scale.sh +41 -24
- package/scripts/sw-security-audit.sh +30 -20
- package/scripts/sw-self-optimize.sh +33 -37
- package/scripts/sw-session.sh +31 -15
- package/scripts/sw-setup.sh +30 -16
- package/scripts/sw-standup.sh +30 -20
- package/scripts/sw-status.sh +33 -13
- package/scripts/sw-strategic.sh +55 -43
- package/scripts/sw-stream.sh +33 -37
- package/scripts/sw-swarm.sh +30 -21
- package/scripts/sw-team-stages.sh +30 -38
- package/scripts/sw-templates.sh +31 -16
- package/scripts/sw-testgen.sh +30 -31
- package/scripts/sw-tmux-pipeline.sh +29 -31
- package/scripts/sw-tmux-role-color.sh +31 -0
- package/scripts/sw-tmux-status.sh +31 -0
- package/scripts/sw-tmux.sh +31 -15
- package/scripts/sw-trace.sh +30 -19
- package/scripts/sw-tracker-github.sh +31 -0
- package/scripts/sw-tracker-jira.sh +31 -0
- package/scripts/sw-tracker-linear.sh +31 -0
- package/scripts/sw-tracker.sh +30 -40
- package/scripts/sw-triage.sh +68 -61
- package/scripts/sw-upgrade.sh +30 -16
- package/scripts/sw-ux.sh +30 -35
- package/scripts/sw-webhook.sh +30 -25
- package/scripts/sw-widgets.sh +30 -19
- package/scripts/sw-worktree.sh +32 -15
- package/tmux/templates/doc-fleet.json +43 -0
package/scripts/sw-trace.sh
CHANGED
|
@@ -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.
|
|
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
|
-
#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
# ─── Data Paths ─────────────────────────────────────────────────────────────
|
|
37
48
|
EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
|
|
@@ -7,6 +7,37 @@
|
|
|
7
7
|
# It defines provider_* functions used by the tracker router.
|
|
8
8
|
# Do NOT add set -euo pipefail or a main() function here.
|
|
9
9
|
|
|
10
|
+
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
11
|
+
# Canonical helpers (colors, output, events)
|
|
12
|
+
# shellcheck source=lib/helpers.sh
|
|
13
|
+
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
|
|
14
|
+
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
|
|
15
|
+
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
|
|
16
|
+
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
|
|
17
|
+
[[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
|
|
18
|
+
[[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
|
|
19
|
+
if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
|
|
20
|
+
now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
|
|
21
|
+
now_epoch() { date +%s; }
|
|
22
|
+
fi
|
|
23
|
+
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
24
|
+
emit_event() {
|
|
25
|
+
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
26
|
+
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
27
|
+
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
28
|
+
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
29
|
+
}
|
|
30
|
+
fi
|
|
31
|
+
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
32
|
+
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
33
|
+
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
34
|
+
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
35
|
+
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
36
|
+
RED="${RED:-\033[38;2;248;113;113m}"
|
|
37
|
+
DIM="${DIM:-\033[2m}"
|
|
38
|
+
BOLD="${BOLD:-\033[1m}"
|
|
39
|
+
RESET="${RESET:-\033[0m}"
|
|
40
|
+
|
|
10
41
|
# ─── Discovery & CRUD Interface ────────────────────────────────────────────
|
|
11
42
|
# All functions output normalized JSON (or plain text where specified).
|
|
12
43
|
# Input: normalized arguments (label, state, issue_id, etc.)
|
|
@@ -7,6 +7,37 @@
|
|
|
7
7
|
# It defines provider_* functions used by the tracker router.
|
|
8
8
|
# Do NOT add set -euo pipefail or a main() function here.
|
|
9
9
|
|
|
10
|
+
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
11
|
+
# Canonical helpers (colors, output, events)
|
|
12
|
+
# shellcheck source=lib/helpers.sh
|
|
13
|
+
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
|
|
14
|
+
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
|
|
15
|
+
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
|
|
16
|
+
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
|
|
17
|
+
[[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
|
|
18
|
+
[[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
|
|
19
|
+
if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
|
|
20
|
+
now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
|
|
21
|
+
now_epoch() { date +%s; }
|
|
22
|
+
fi
|
|
23
|
+
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
24
|
+
emit_event() {
|
|
25
|
+
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
26
|
+
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
27
|
+
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
28
|
+
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
29
|
+
}
|
|
30
|
+
fi
|
|
31
|
+
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
32
|
+
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
33
|
+
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
34
|
+
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
35
|
+
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
36
|
+
RED="${RED:-\033[38;2;248;113;113m}"
|
|
37
|
+
DIM="${DIM:-\033[2m}"
|
|
38
|
+
BOLD="${BOLD:-\033[1m}"
|
|
39
|
+
RESET="${RESET:-\033[0m}"
|
|
40
|
+
|
|
10
41
|
# ─── Status Auto-Discovery ────────────────────────────────────────────────
|
|
11
42
|
# Queries Jira API for project statuses and caches the transition name mapping.
|
|
12
43
|
# Only fills in JIRA_TRANSITION_* values that are empty (config/env takes priority).
|
|
@@ -7,6 +7,37 @@
|
|
|
7
7
|
# It defines provider_* functions used by the tracker router.
|
|
8
8
|
# Do NOT add set -euo pipefail or a main() function here.
|
|
9
9
|
|
|
10
|
+
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
11
|
+
# Canonical helpers (colors, output, events)
|
|
12
|
+
# shellcheck source=lib/helpers.sh
|
|
13
|
+
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
|
|
14
|
+
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
|
|
15
|
+
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
|
|
16
|
+
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
|
|
17
|
+
[[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
|
|
18
|
+
[[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
|
|
19
|
+
if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
|
|
20
|
+
now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
|
|
21
|
+
now_epoch() { date +%s; }
|
|
22
|
+
fi
|
|
23
|
+
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
24
|
+
emit_event() {
|
|
25
|
+
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
26
|
+
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
27
|
+
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
28
|
+
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
29
|
+
}
|
|
30
|
+
fi
|
|
31
|
+
CYAN="${CYAN:-\033[38;2;0;212;255m}"
|
|
32
|
+
PURPLE="${PURPLE:-\033[38;2;124;58;237m}"
|
|
33
|
+
BLUE="${BLUE:-\033[38;2;0;102;255m}"
|
|
34
|
+
GREEN="${GREEN:-\033[38;2;74;222;128m}"
|
|
35
|
+
YELLOW="${YELLOW:-\033[38;2;250;204;21m}"
|
|
36
|
+
RED="${RED:-\033[38;2;248;113;113m}"
|
|
37
|
+
DIM="${DIM:-\033[2m}"
|
|
38
|
+
BOLD="${BOLD:-\033[1m}"
|
|
39
|
+
RESET="${RESET:-\033[0m}"
|
|
40
|
+
|
|
10
41
|
# ─── Status Auto-Discovery ────────────────────────────────────────────────
|
|
11
42
|
# Queries Linear API for workflow states and caches the mapping.
|
|
12
43
|
# Only fills in STATUS_* values that are empty (config/env takes priority).
|
package/scripts/sw-tracker.sh
CHANGED
|
@@ -6,53 +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.
|
|
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
|
-
# ─── 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; }
|
|
35
|
-
|
|
36
|
-
# ─── Structured Event Log ──────────────────────────────────────────────────
|
|
37
|
-
EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
|
|
38
16
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
mkdir -p "${HOME}/.shipwright"
|
|
54
|
-
|
|
55
|
-
}
|
|
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}"
|
|
56
46
|
|
|
57
47
|
# ─── Configuration ─────────────────────────────────────────────────────────
|
|
58
48
|
CONFIG_DIR="${HOME}/.shipwright"
|
package/scripts/sw-triage.sh
CHANGED
|
@@ -6,50 +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.
|
|
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
|
-
#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
emit_event
|
|
40
|
-
|
|
41
|
-
local
|
|
42
|
-
|
|
43
|
-
local
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
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}"
|
|
53
45
|
|
|
54
46
|
# ─── GitHub API (safe when NO_GITHUB set) ──────────────────────────────────
|
|
55
47
|
|
|
@@ -390,38 +382,53 @@ cmd_team() {
|
|
|
390
382
|
local issue="${1:-}"
|
|
391
383
|
[[ -z "$issue" ]] && { error "Usage: triage team <issue>"; exit 1; }
|
|
392
384
|
|
|
393
|
-
check_gh
|
|
394
|
-
|
|
395
385
|
info "Recommending team setup for issue ${CYAN}${issue}${RESET}..."
|
|
396
386
|
|
|
397
|
-
#
|
|
398
|
-
local
|
|
399
|
-
|
|
387
|
+
# Determine if GitHub is available (don't exit — allow offline fallback)
|
|
388
|
+
local gh_available=false
|
|
389
|
+
if [[ "${NO_GITHUB:-}" != "1" ]] && command -v gh &>/dev/null; then
|
|
390
|
+
gh_available=true
|
|
391
|
+
fi
|
|
400
392
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
393
|
+
# Get analysis (requires gh) — use defaults when offline
|
|
394
|
+
local analysis="" complexity="moderate" risk="medium" effort="m"
|
|
395
|
+
if $gh_available; then
|
|
396
|
+
analysis=$(cmd_analyze "$issue" 2>/dev/null) || true
|
|
397
|
+
if [[ -n "$analysis" ]]; then
|
|
398
|
+
complexity=$(echo "$analysis" | jq -r '.complexity // "moderate"')
|
|
399
|
+
risk=$(echo "$analysis" | jq -r '.risk // "medium"')
|
|
400
|
+
effort=$(echo "$analysis" | jq -r '.effort // "m"')
|
|
401
|
+
fi
|
|
402
|
+
else
|
|
403
|
+
warn "GitHub unavailable — using defaults for complexity/risk analysis"
|
|
404
|
+
fi
|
|
405
405
|
|
|
406
406
|
# ── Try recruit-powered team composition first ──
|
|
407
407
|
local template="" model="" max_iterations="" agents=""
|
|
408
408
|
local recruit_source="heuristic"
|
|
409
409
|
if [[ -x "${SCRIPT_DIR:-}/sw-recruit.sh" ]]; then
|
|
410
|
-
local issue_title
|
|
411
|
-
|
|
412
|
-
if
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
410
|
+
local issue_title=""
|
|
411
|
+
# Try to get title from GitHub; fall back to issue number as description
|
|
412
|
+
if $gh_available; then
|
|
413
|
+
issue_title=$(gh issue view "$issue" --json title -q '.title' 2>/dev/null || echo "")
|
|
414
|
+
fi
|
|
415
|
+
[[ -z "$issue_title" ]] && issue_title="Issue #${issue}"
|
|
416
|
+
|
|
417
|
+
local recruit_result
|
|
418
|
+
recruit_result=$(bash "$SCRIPT_DIR/sw-recruit.sh" team --json "$issue_title" 2>/dev/null) || true
|
|
419
|
+
if [[ -n "$recruit_result" ]] && echo "$recruit_result" | jq -e '.team' &>/dev/null 2>&1; then
|
|
420
|
+
model=$(echo "$recruit_result" | jq -r '.model // "sonnet"')
|
|
421
|
+
agents=$(echo "$recruit_result" | jq -r '.agents // 2')
|
|
422
|
+
template=$(echo "$recruit_result" | jq -r '.template // ""')
|
|
423
|
+
max_iterations=$(echo "$recruit_result" | jq -r '.max_iterations // ""')
|
|
424
|
+
# If recruit didn't provide template/max_iterations, derive from agent count
|
|
425
|
+
if [[ -z "$template" ]]; then
|
|
426
|
+
if [[ "$agents" -ge 4 ]]; then template="full"; max_iterations="${max_iterations:-15}";
|
|
427
|
+
elif [[ "$agents" -ge 3 ]]; then template="standard"; max_iterations="${max_iterations:-8}";
|
|
428
|
+
elif [[ "$agents" -le 1 ]]; then template="fast"; max_iterations="${max_iterations:-2}";
|
|
429
|
+
else template="standard"; max_iterations="${max_iterations:-5}"; fi
|
|
424
430
|
fi
|
|
431
|
+
recruit_source="recruit"
|
|
425
432
|
fi
|
|
426
433
|
fi
|
|
427
434
|
|
package/scripts/sw-upgrade.sh
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
3
|
# ║ sw upgrade — Detect and apply updates from the repo ║
|
|
4
4
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
5
|
-
VERSION="2.
|
|
5
|
+
VERSION="2.2.0"
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
@@ -10,24 +10,38 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
10
10
|
MANIFEST_DIR="$HOME/.shipwright"
|
|
11
11
|
MANIFEST="$MANIFEST_DIR/manifest.json"
|
|
12
12
|
|
|
13
|
-
# ─── Colors ────────────────────────────────────────────────────────────────
|
|
14
|
-
CYAN='\033[38;2;0;212;255m'
|
|
15
|
-
PURPLE='\033[38;2;124;58;237m'
|
|
16
|
-
BLUE='\033[38;2;0;102;255m'
|
|
17
|
-
GREEN='\033[38;2;74;222;128m'
|
|
18
|
-
YELLOW='\033[38;2;250;204;21m'
|
|
19
|
-
RED='\033[38;2;248;113;113m'
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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}"
|
|
31
45
|
|
|
32
46
|
# ─── Parse flags ───────────────────────────────────────────────────────────
|
|
33
47
|
APPLY=false
|
package/scripts/sw-ux.sh
CHANGED
|
@@ -6,52 +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.
|
|
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
|
_COMPAT="$SCRIPT_DIR/lib/compat.sh"
|
|
25
14
|
# shellcheck source=lib/compat.sh
|
|
26
15
|
[[ -f "$_COMPAT" ]] && source "$_COMPAT"
|
|
27
16
|
|
|
28
|
-
#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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}"
|
|
33
46
|
|
|
34
47
|
# ─── Structured Event Log ──────────────────────────────────────────────────
|
|
35
48
|
EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
|
|
36
49
|
|
|
37
|
-
emit_event() {
|
|
38
|
-
local event_type="$1"
|
|
39
|
-
shift
|
|
40
|
-
local json_fields=""
|
|
41
|
-
for kv in "$@"; do
|
|
42
|
-
local key="${kv%%=*}"
|
|
43
|
-
local val="${kv#*=}"
|
|
44
|
-
if [[ "$val" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
|
|
45
|
-
json_fields="${json_fields},\"${key}\":${val}"
|
|
46
|
-
else
|
|
47
|
-
val="${val//\"/\\\"}"
|
|
48
|
-
json_fields="${json_fields},\"${key}\":\"${val}\""
|
|
49
|
-
fi
|
|
50
|
-
done
|
|
51
|
-
mkdir -p "${HOME}/.shipwright"
|
|
52
|
-
echo "{\"ts\":\"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\",\"type\":\"${event_type}\"${json_fields}}" >> "$EVENTS_FILE" || true
|
|
53
|
-
}
|
|
54
|
-
|
|
55
50
|
# ─── UX Configuration ──────────────────────────────────────────────────────
|
|
56
51
|
UX_CONFIG_GLOBAL="${HOME}/.shipwright/ux-config.json"
|
|
57
52
|
UX_CONFIG_REPO="./.claude/ux-config.json"
|