shipwright-cli 3.2.0 → 3.3.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/code-reviewer.md +2 -0
- package/.claude/agents/devops-engineer.md +2 -0
- package/.claude/agents/doc-fleet-agent.md +2 -0
- package/.claude/agents/pipeline-agent.md +2 -0
- package/.claude/agents/shell-script-specialist.md +2 -0
- package/.claude/agents/test-specialist.md +2 -0
- package/.claude/hooks/agent-crash-capture.sh +32 -0
- package/.claude/hooks/post-tool-use.sh +3 -2
- package/.claude/hooks/pre-tool-use.sh +35 -3
- package/README.md +4 -4
- package/claude-code/hooks/config-change.sh +18 -0
- package/claude-code/hooks/instructions-reloaded.sh +7 -0
- package/claude-code/hooks/worktree-create.sh +25 -0
- package/claude-code/hooks/worktree-remove.sh +20 -0
- package/config/code-constitution.json +130 -0
- package/dashboard/middleware/auth.ts +134 -0
- package/dashboard/middleware/constants.ts +21 -0
- package/dashboard/public/index.html +2 -6
- package/dashboard/public/styles.css +100 -97
- package/dashboard/routes/auth.ts +38 -0
- package/dashboard/server.ts +66 -25
- package/dashboard/services/config.ts +26 -0
- package/dashboard/services/db.ts +118 -0
- package/dashboard/src/canvas/pixel-agent.ts +298 -0
- package/dashboard/src/canvas/pixel-sprites.ts +440 -0
- package/dashboard/src/canvas/shipyard-effects.ts +367 -0
- package/dashboard/src/canvas/shipyard-scene.ts +616 -0
- package/dashboard/src/canvas/submarine-layout.ts +267 -0
- package/dashboard/src/components/header.ts +8 -7
- package/dashboard/src/core/router.ts +1 -0
- package/dashboard/src/design/submarine-theme.ts +253 -0
- package/dashboard/src/main.ts +2 -0
- package/dashboard/src/types/api.ts +2 -1
- package/dashboard/src/views/activity.ts +2 -1
- package/dashboard/src/views/shipyard.ts +39 -0
- package/dashboard/types/index.ts +166 -0
- package/docs/plans/2026-02-28-compound-audit-and-shipyard-design.md +186 -0
- package/docs/plans/2026-02-28-skipper-shipwright-implementation-plan.md +1182 -0
- package/docs/plans/2026-02-28-skipper-shipwright-integration-design.md +531 -0
- package/docs/plans/2026-03-01-ai-powered-skill-injection-design.md +298 -0
- package/docs/plans/2026-03-01-ai-powered-skill-injection-plan.md +1109 -0
- package/docs/plans/2026-03-01-capabilities-cleanup-plan.md +658 -0
- package/docs/plans/2026-03-01-clean-architecture-plan.md +924 -0
- package/docs/plans/2026-03-01-compound-audit-cascade-design.md +191 -0
- package/docs/plans/2026-03-01-compound-audit-cascade-plan.md +921 -0
- package/docs/plans/2026-03-01-deep-integration-plan.md +851 -0
- package/docs/plans/2026-03-01-pipeline-audit-trail-design.md +145 -0
- package/docs/plans/2026-03-01-pipeline-audit-trail-plan.md +770 -0
- package/docs/plans/2026-03-01-refined-depths-brand-design.md +382 -0
- package/docs/plans/2026-03-01-refined-depths-implementation.md +599 -0
- package/docs/plans/2026-03-01-skipper-kernel-integration-design.md +203 -0
- package/docs/plans/2026-03-01-unified-platform-design.md +272 -0
- package/docs/plans/2026-03-07-claude-code-feature-integration-design.md +189 -0
- package/docs/plans/2026-03-07-claude-code-feature-integration-plan.md +1165 -0
- package/docs/research/BACKLOG_QUICK_REFERENCE.md +352 -0
- package/docs/research/CUTTING_EDGE_RESEARCH_2026.md +546 -0
- package/docs/research/RESEARCH_INDEX.md +439 -0
- package/docs/research/RESEARCH_SOURCES.md +440 -0
- package/docs/research/RESEARCH_SUMMARY.txt +275 -0
- package/docs/superpowers/specs/2026-03-10-pipeline-quality-revolution-design.md +341 -0
- package/package.json +2 -2
- package/scripts/lib/adaptive-model.sh +427 -0
- package/scripts/lib/adaptive-timeout.sh +316 -0
- package/scripts/lib/audit-trail.sh +309 -0
- package/scripts/lib/auto-recovery.sh +471 -0
- package/scripts/lib/bandit-selector.sh +431 -0
- package/scripts/lib/bootstrap.sh +104 -2
- package/scripts/lib/causal-graph.sh +455 -0
- package/scripts/lib/compat.sh +126 -0
- package/scripts/lib/compound-audit.sh +337 -0
- package/scripts/lib/constitutional.sh +454 -0
- package/scripts/lib/context-budget.sh +359 -0
- package/scripts/lib/convergence.sh +594 -0
- package/scripts/lib/cost-optimizer.sh +634 -0
- package/scripts/lib/daemon-adaptive.sh +10 -0
- package/scripts/lib/daemon-dispatch.sh +106 -17
- package/scripts/lib/daemon-failure.sh +34 -4
- package/scripts/lib/daemon-patrol.sh +23 -2
- package/scripts/lib/daemon-poll-github.sh +361 -0
- package/scripts/lib/daemon-poll-health.sh +299 -0
- package/scripts/lib/daemon-poll.sh +27 -611
- package/scripts/lib/daemon-state.sh +112 -66
- package/scripts/lib/daemon-triage.sh +10 -0
- package/scripts/lib/dod-scorecard.sh +442 -0
- package/scripts/lib/error-actionability.sh +300 -0
- package/scripts/lib/formal-spec.sh +461 -0
- package/scripts/lib/helpers.sh +177 -4
- package/scripts/lib/intent-analysis.sh +409 -0
- package/scripts/lib/loop-convergence.sh +350 -0
- package/scripts/lib/loop-iteration.sh +682 -0
- package/scripts/lib/loop-progress.sh +48 -0
- package/scripts/lib/loop-restart.sh +185 -0
- package/scripts/lib/memory-effectiveness.sh +506 -0
- package/scripts/lib/mutation-executor.sh +352 -0
- package/scripts/lib/outcome-feedback.sh +521 -0
- package/scripts/lib/pipeline-cli.sh +336 -0
- package/scripts/lib/pipeline-commands.sh +1216 -0
- package/scripts/lib/pipeline-detection.sh +100 -2
- package/scripts/lib/pipeline-execution.sh +897 -0
- package/scripts/lib/pipeline-github.sh +28 -3
- package/scripts/lib/pipeline-intelligence-compound.sh +431 -0
- package/scripts/lib/pipeline-intelligence-scoring.sh +407 -0
- package/scripts/lib/pipeline-intelligence-skip.sh +181 -0
- package/scripts/lib/pipeline-intelligence.sh +100 -1136
- package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
- package/scripts/lib/pipeline-quality-checks.sh +17 -715
- package/scripts/lib/pipeline-quality-gates.sh +563 -0
- package/scripts/lib/pipeline-stages-build.sh +730 -0
- package/scripts/lib/pipeline-stages-delivery.sh +965 -0
- package/scripts/lib/pipeline-stages-intake.sh +1133 -0
- package/scripts/lib/pipeline-stages-monitor.sh +407 -0
- package/scripts/lib/pipeline-stages-review.sh +1022 -0
- package/scripts/lib/pipeline-stages.sh +59 -2929
- package/scripts/lib/pipeline-state.sh +36 -5
- package/scripts/lib/pipeline-util.sh +487 -0
- package/scripts/lib/policy-learner.sh +438 -0
- package/scripts/lib/process-reward.sh +493 -0
- package/scripts/lib/project-detect.sh +649 -0
- package/scripts/lib/quality-profile.sh +334 -0
- package/scripts/lib/recruit-commands.sh +885 -0
- package/scripts/lib/recruit-learning.sh +739 -0
- package/scripts/lib/recruit-roles.sh +648 -0
- package/scripts/lib/reward-aggregator.sh +458 -0
- package/scripts/lib/rl-optimizer.sh +362 -0
- package/scripts/lib/root-cause.sh +427 -0
- package/scripts/lib/scope-enforcement.sh +445 -0
- package/scripts/lib/session-restart.sh +493 -0
- package/scripts/lib/skill-memory.sh +300 -0
- package/scripts/lib/skill-registry.sh +775 -0
- package/scripts/lib/spec-driven.sh +476 -0
- package/scripts/lib/test-helpers.sh +18 -7
- package/scripts/lib/test-holdout.sh +429 -0
- package/scripts/lib/test-optimizer.sh +511 -0
- package/scripts/shipwright-file-suggest.sh +45 -0
- package/scripts/skills/adversarial-quality.md +61 -0
- package/scripts/skills/api-design.md +44 -0
- package/scripts/skills/architecture-design.md +50 -0
- package/scripts/skills/brainstorming.md +43 -0
- package/scripts/skills/data-pipeline.md +44 -0
- package/scripts/skills/deploy-safety.md +64 -0
- package/scripts/skills/documentation.md +38 -0
- package/scripts/skills/frontend-design.md +45 -0
- package/scripts/skills/generated/.gitkeep +0 -0
- package/scripts/skills/generated/_refinements/.gitkeep +0 -0
- package/scripts/skills/generated/_refinements/adversarial-quality.patch.md +3 -0
- package/scripts/skills/generated/_refinements/architecture-design.patch.md +3 -0
- package/scripts/skills/generated/_refinements/brainstorming.patch.md +3 -0
- package/scripts/skills/generated/cli-version-management.md +29 -0
- package/scripts/skills/generated/collection-system-validation.md +99 -0
- package/scripts/skills/generated/large-scale-c-refactoring-coordination.md +97 -0
- package/scripts/skills/generated/pattern-matching-similarity-scoring.md +195 -0
- package/scripts/skills/generated/test-parallelization-detection.md +65 -0
- package/scripts/skills/observability.md +79 -0
- package/scripts/skills/performance.md +48 -0
- package/scripts/skills/pr-quality.md +49 -0
- package/scripts/skills/product-thinking.md +43 -0
- package/scripts/skills/security-audit.md +49 -0
- package/scripts/skills/systematic-debugging.md +40 -0
- package/scripts/skills/testing-strategy.md +47 -0
- package/scripts/skills/two-stage-review.md +52 -0
- package/scripts/skills/validation-thoroughness.md +55 -0
- package/scripts/sw +9 -3
- package/scripts/sw-activity.sh +9 -2
- package/scripts/sw-adaptive.sh +2 -1
- package/scripts/sw-adversarial.sh +2 -1
- package/scripts/sw-architecture-enforcer.sh +3 -1
- package/scripts/sw-auth.sh +12 -2
- package/scripts/sw-autonomous.sh +5 -1
- package/scripts/sw-changelog.sh +4 -1
- package/scripts/sw-checkpoint.sh +2 -1
- package/scripts/sw-ci.sh +5 -1
- package/scripts/sw-cleanup.sh +4 -26
- package/scripts/sw-code-review.sh +10 -4
- package/scripts/sw-connect.sh +2 -1
- package/scripts/sw-context.sh +2 -1
- package/scripts/sw-cost.sh +48 -3
- package/scripts/sw-daemon.sh +66 -9
- package/scripts/sw-dashboard.sh +3 -1
- package/scripts/sw-db.sh +59 -16
- package/scripts/sw-decide.sh +8 -2
- package/scripts/sw-decompose.sh +360 -17
- package/scripts/sw-deps.sh +4 -1
- package/scripts/sw-developer-simulation.sh +4 -1
- package/scripts/sw-discovery.sh +325 -2
- package/scripts/sw-doc-fleet.sh +4 -1
- package/scripts/sw-docs-agent.sh +3 -1
- package/scripts/sw-docs.sh +2 -1
- package/scripts/sw-doctor.sh +453 -2
- package/scripts/sw-dora.sh +4 -1
- package/scripts/sw-durable.sh +4 -3
- package/scripts/sw-e2e-orchestrator.sh +17 -16
- package/scripts/sw-eventbus.sh +7 -1
- package/scripts/sw-evidence.sh +364 -12
- package/scripts/sw-feedback.sh +550 -9
- package/scripts/sw-fix.sh +20 -1
- package/scripts/sw-fleet-discover.sh +6 -2
- package/scripts/sw-fleet-viz.sh +4 -1
- package/scripts/sw-fleet.sh +5 -1
- package/scripts/sw-github-app.sh +16 -3
- package/scripts/sw-github-checks.sh +3 -2
- package/scripts/sw-github-deploy.sh +3 -2
- package/scripts/sw-github-graphql.sh +18 -7
- package/scripts/sw-guild.sh +5 -1
- package/scripts/sw-heartbeat.sh +5 -30
- package/scripts/sw-hello.sh +67 -0
- package/scripts/sw-hygiene.sh +6 -1
- package/scripts/sw-incident.sh +265 -1
- package/scripts/sw-init.sh +18 -2
- package/scripts/sw-instrument.sh +10 -2
- package/scripts/sw-intelligence.sh +42 -6
- package/scripts/sw-jira.sh +5 -1
- package/scripts/sw-launchd.sh +2 -1
- package/scripts/sw-linear.sh +4 -1
- package/scripts/sw-logs.sh +4 -1
- package/scripts/sw-loop.sh +432 -1128
- package/scripts/sw-memory.sh +356 -2
- package/scripts/sw-mission-control.sh +6 -1
- package/scripts/sw-model-router.sh +481 -26
- package/scripts/sw-otel.sh +13 -4
- package/scripts/sw-oversight.sh +14 -5
- package/scripts/sw-patrol-meta.sh +334 -0
- package/scripts/sw-pipeline-composer.sh +5 -1
- package/scripts/sw-pipeline-vitals.sh +2 -1
- package/scripts/sw-pipeline.sh +53 -2664
- package/scripts/sw-pm.sh +12 -5
- package/scripts/sw-pr-lifecycle.sh +2 -1
- package/scripts/sw-predictive.sh +7 -1
- package/scripts/sw-prep.sh +185 -2
- package/scripts/sw-ps.sh +5 -25
- package/scripts/sw-public-dashboard.sh +15 -3
- package/scripts/sw-quality.sh +2 -1
- package/scripts/sw-reaper.sh +8 -25
- package/scripts/sw-recruit.sh +156 -2303
- package/scripts/sw-regression.sh +19 -12
- package/scripts/sw-release-manager.sh +3 -1
- package/scripts/sw-release.sh +4 -1
- package/scripts/sw-remote.sh +3 -1
- package/scripts/sw-replay.sh +7 -1
- package/scripts/sw-retro.sh +158 -1
- package/scripts/sw-review-rerun.sh +3 -1
- package/scripts/sw-scale.sh +10 -3
- package/scripts/sw-security-audit.sh +6 -1
- package/scripts/sw-self-optimize.sh +6 -3
- package/scripts/sw-session.sh +9 -3
- package/scripts/sw-setup.sh +3 -1
- package/scripts/sw-stall-detector.sh +406 -0
- package/scripts/sw-standup.sh +15 -7
- package/scripts/sw-status.sh +3 -1
- package/scripts/sw-strategic.sh +4 -1
- package/scripts/sw-stream.sh +7 -1
- package/scripts/sw-swarm.sh +18 -6
- package/scripts/sw-team-stages.sh +13 -6
- package/scripts/sw-templates.sh +5 -29
- package/scripts/sw-testgen.sh +7 -1
- package/scripts/sw-tmux-pipeline.sh +4 -1
- package/scripts/sw-tmux-role-color.sh +2 -0
- package/scripts/sw-tmux-status.sh +1 -1
- package/scripts/sw-tmux.sh +3 -1
- package/scripts/sw-trace.sh +3 -1
- package/scripts/sw-tracker-github.sh +3 -0
- package/scripts/sw-tracker-jira.sh +3 -0
- package/scripts/sw-tracker-linear.sh +3 -0
- package/scripts/sw-tracker.sh +3 -1
- package/scripts/sw-triage.sh +2 -1
- package/scripts/sw-upgrade.sh +3 -1
- package/scripts/sw-ux.sh +5 -2
- package/scripts/sw-webhook.sh +3 -1
- package/scripts/sw-widgets.sh +3 -1
- package/scripts/sw-worktree.sh +15 -3
- package/scripts/test-skill-injection.sh +1233 -0
- package/templates/pipelines/autonomous.json +27 -3
- package/templates/pipelines/cost-aware.json +34 -8
- package/templates/pipelines/deployed.json +12 -0
- package/templates/pipelines/enterprise.json +12 -0
- package/templates/pipelines/fast.json +6 -0
- package/templates/pipelines/full.json +27 -3
- package/templates/pipelines/hotfix.json +6 -0
- package/templates/pipelines/standard.json +12 -0
- package/templates/pipelines/tdd.json +12 -0
package/scripts/sw-pm.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="3.
|
|
9
|
+
VERSION="3.3.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -26,18 +26,20 @@ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
|
|
|
26
26
|
fi
|
|
27
27
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
28
28
|
emit_event() {
|
|
29
|
-
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
29
|
+
local event_type="$1"; shift; mkdir -p "${PM_STATE_DIR:=${HOME}/.shipwright}"
|
|
30
|
+
# shellcheck disable=SC2155
|
|
30
31
|
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
31
32
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
32
|
-
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
33
|
+
echo "${payload}}" >> "${PM_STATE_DIR:=${HOME}/.shipwright}/events.jsonl"
|
|
33
34
|
}
|
|
34
35
|
fi
|
|
35
36
|
# ─── PM History Storage ──────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
+
PM_STATE_DIR="${PM_STATE_DIR:-${HOME}/.shipwright}"
|
|
38
|
+
PM_HISTORY="${PM_STATE_DIR}/pm-history.json"
|
|
37
39
|
|
|
38
40
|
# ─── Ensure PM history file exists ───────────────────────────────────────────
|
|
39
41
|
ensure_pm_history() {
|
|
40
|
-
mkdir -p "${
|
|
42
|
+
mkdir -p "${PM_STATE_DIR}"
|
|
41
43
|
if [[ ! -f "$PM_HISTORY" ]]; then
|
|
42
44
|
echo '{"decisions":[],"outcomes":[]}' > "$PM_HISTORY"
|
|
43
45
|
fi
|
|
@@ -495,6 +497,7 @@ cmd_recommend() {
|
|
|
495
497
|
|
|
496
498
|
# Combine into comprehensive recommendation
|
|
497
499
|
local recommendation
|
|
500
|
+
# shellcheck disable=SC2046
|
|
498
501
|
recommendation=$(jq -n \
|
|
499
502
|
--argjson analysis "$analysis" \
|
|
500
503
|
--argjson team "$team_rec" \
|
|
@@ -513,6 +516,7 @@ cmd_recommend() {
|
|
|
513
516
|
ensure_pm_history
|
|
514
517
|
local tmp_hist
|
|
515
518
|
tmp_hist=$(mktemp)
|
|
519
|
+
# shellcheck disable=SC2064
|
|
516
520
|
trap "rm -f '$tmp_hist'" RETURN
|
|
517
521
|
jq --argjson rec "$recommendation" '.decisions += [$rec]' "$PM_HISTORY" > "$tmp_hist" && mv "$tmp_hist" "$PM_HISTORY"
|
|
518
522
|
emit_event "pm.recommend" "issue=${issue_num}"
|
|
@@ -541,6 +545,7 @@ cmd_recommend() {
|
|
|
541
545
|
ensure_pm_history
|
|
542
546
|
local tmp_hist
|
|
543
547
|
tmp_hist=$(mktemp)
|
|
548
|
+
# shellcheck disable=SC2064
|
|
544
549
|
trap "rm -f '$tmp_hist'" RETURN
|
|
545
550
|
jq --argjson rec "$recommendation" '.decisions += [$rec]' "$PM_HISTORY" > "$tmp_hist" && mv "$tmp_hist" "$PM_HISTORY"
|
|
546
551
|
|
|
@@ -605,6 +610,7 @@ cmd_learn() {
|
|
|
605
610
|
# Save to history
|
|
606
611
|
local tmp_hist
|
|
607
612
|
tmp_hist=$(mktemp)
|
|
613
|
+
# shellcheck disable=SC2064
|
|
608
614
|
trap "rm -f '$tmp_hist'" RETURN
|
|
609
615
|
jq --argjson outcome "$outcome_record" '.outcomes += [$outcome]' "$PM_HISTORY" > "$tmp_hist" && mv "$tmp_hist" "$PM_HISTORY"
|
|
610
616
|
|
|
@@ -630,6 +636,7 @@ cmd_history() {
|
|
|
630
636
|
local total_decisions success_count fail_count
|
|
631
637
|
total_decisions=$(jq '.outcomes | length' "$PM_HISTORY")
|
|
632
638
|
success_count=$(jq '[.outcomes[] | select(.outcome == "success")] | length' "$PM_HISTORY")
|
|
639
|
+
# shellcheck disable=SC2034
|
|
633
640
|
fail_count=$(jq '[.outcomes[] | select(.outcome == "failure")] | length' "$PM_HISTORY")
|
|
634
641
|
|
|
635
642
|
if [[ "$total_decisions" -gt 0 ]]; then
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# shellcheck disable=SC2034
|
|
10
|
+
VERSION="3.3.0"
|
|
10
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
12
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
13
|
|
package/scripts/sw-predictive.sh
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# shellcheck disable=SC2034
|
|
10
|
+
VERSION="3.3.0"
|
|
10
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
12
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
13
|
|
|
@@ -31,12 +32,14 @@ fi
|
|
|
31
32
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
32
33
|
emit_event() {
|
|
33
34
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
35
|
+
# shellcheck disable=SC2155
|
|
34
36
|
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
35
37
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
36
38
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
37
39
|
}
|
|
38
40
|
fi
|
|
39
41
|
# ─── Structured Event Log ──────────────────────────────────────────────────
|
|
42
|
+
# shellcheck disable=SC2034
|
|
40
43
|
EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
|
|
41
44
|
|
|
42
45
|
# ─── Intelligence Engine (optional) ────────────────────────────────────────
|
|
@@ -180,6 +183,7 @@ predictive_confirm_anomaly() {
|
|
|
180
183
|
# Find the most recent unconfirmed anomaly for this stage+metric
|
|
181
184
|
local tmp_file
|
|
182
185
|
tmp_file=$(mktemp "${TMPDIR:-/tmp}/sw-anomaly-confirm.XXXXXX")
|
|
186
|
+
# shellcheck disable=SC2064
|
|
183
187
|
trap "rm -f '$tmp_file'" RETURN
|
|
184
188
|
local found=false
|
|
185
189
|
|
|
@@ -276,6 +280,7 @@ _predictive_update_alarm_rates() {
|
|
|
276
280
|
# Atomic write
|
|
277
281
|
local tmp_file
|
|
278
282
|
tmp_file=$(mktemp "${TMPDIR:-/tmp}/sw-anomaly-thresh.XXXXXX")
|
|
283
|
+
# shellcheck disable=SC2064
|
|
279
284
|
trap "rm -f '$tmp_file'" RETURN
|
|
280
285
|
jq --arg m "$metric_name" \
|
|
281
286
|
--argjson crit "$new_critical" \
|
|
@@ -757,6 +762,7 @@ predict_update_baseline() {
|
|
|
757
762
|
# Atomic write
|
|
758
763
|
local tmp_file
|
|
759
764
|
tmp_file=$(mktemp)
|
|
765
|
+
# shellcheck disable=SC2064
|
|
760
766
|
trap "rm -f '$tmp_file'" RETURN
|
|
761
767
|
jq --arg key "$key" \
|
|
762
768
|
--argjson val "$new_value" \
|
package/scripts/sw-prep.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="3.
|
|
9
|
+
VERSION="3.3.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
|
|
12
12
|
# ─── Handle subcommands ───────────────────────────────────────────────────────
|
|
@@ -33,7 +33,8 @@ fi
|
|
|
33
33
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
34
34
|
emit_event() {
|
|
35
35
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
36
|
-
local payload
|
|
36
|
+
local payload
|
|
37
|
+
payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
37
38
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
38
39
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
39
40
|
}
|
|
@@ -43,6 +44,7 @@ FORCE=false
|
|
|
43
44
|
CHECK_ONLY=false
|
|
44
45
|
UPDATE_MODE=false
|
|
45
46
|
WITH_CLAUDE=false
|
|
47
|
+
INTERACTIVE=false
|
|
46
48
|
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
47
49
|
|
|
48
50
|
# Detection results
|
|
@@ -99,6 +101,7 @@ show_help() {
|
|
|
99
101
|
echo -e " ${CYAN}--force${RESET} Overwrite existing files"
|
|
100
102
|
echo -e " ${CYAN}--check${RESET} Audit existing prep (dry run)"
|
|
101
103
|
echo -e " ${CYAN}--update${RESET} Refresh auto-generated sections only"
|
|
104
|
+
echo -e " ${CYAN}--interactive${RESET} Interactive quality profile dialogue"
|
|
102
105
|
echo -e " ${CYAN}--with-claude${RESET} Deep analysis using Claude Code (slower, richer)"
|
|
103
106
|
echo -e " ${CYAN}--help, -h${RESET} Show this help message"
|
|
104
107
|
echo ""
|
|
@@ -129,6 +132,7 @@ for arg in "$@"; do
|
|
|
129
132
|
--force) FORCE=true ;;
|
|
130
133
|
--check) CHECK_ONLY=true ;;
|
|
131
134
|
--update) UPDATE_MODE=true ;;
|
|
135
|
+
--interactive) INTERACTIVE=true ;;
|
|
132
136
|
--with-claude) WITH_CLAUDE=true ;;
|
|
133
137
|
--help|-h) show_help; exit 0 ;;
|
|
134
138
|
*)
|
|
@@ -459,6 +463,7 @@ prep_scan_structure() {
|
|
|
459
463
|
for d in docs doc documentation wiki; do
|
|
460
464
|
[[ -d "$root/$d" ]] && ddirs+=("$d")
|
|
461
465
|
done
|
|
466
|
+
# shellcheck disable=SC2034
|
|
462
467
|
DOC_DIRS="${ddirs[*]:-}"
|
|
463
468
|
|
|
464
469
|
# Config files
|
|
@@ -499,6 +504,7 @@ prep_scan_structure() {
|
|
|
499
504
|
-not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | wc -l | tr -d ' ')
|
|
500
505
|
|
|
501
506
|
# Total lines (approximation from source files)
|
|
507
|
+
# shellcheck disable=SC2227,SC2261
|
|
502
508
|
TOTAL_LINES=$(find "$root" \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \
|
|
503
509
|
-o -name "*.py" -o -name "*.rb" -o -name "*.go" -o -name "*.rs" -o -name "*.java" \) \
|
|
504
510
|
-not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/vendor/*" \
|
|
@@ -572,6 +578,7 @@ prep_extract_patterns() {
|
|
|
572
578
|
|
|
573
579
|
# ── Middleware ──
|
|
574
580
|
if grep -rq "app\.use(" "$root/src" "$root/app" "$root/lib" 2>/dev/null; then
|
|
581
|
+
# shellcheck disable=SC2034
|
|
575
582
|
HAS_MIDDLEWARE=true
|
|
576
583
|
fi
|
|
577
584
|
|
|
@@ -767,8 +774,11 @@ ${style_samples}"
|
|
|
767
774
|
DB_PATTERNS="$smart_val"
|
|
768
775
|
fi
|
|
769
776
|
|
|
777
|
+
# shellcheck disable=SC2034
|
|
770
778
|
SEMICOLONS=$(echo "$analysis" | grep "^SEMICOLONS:" | sed 's/^SEMICOLONS:[[:space:]]*//' | head -1)
|
|
779
|
+
# shellcheck disable=SC2034
|
|
771
780
|
QUOTE_STYLE=$(echo "$analysis" | grep "^QUOTE_STYLE:" | sed 's/^QUOTE_STYLE:[[:space:]]*//' | head -1)
|
|
781
|
+
# shellcheck disable=SC2034
|
|
772
782
|
INDENT_STYLE=$(echo "$analysis" | grep "^INDENT:" | sed 's/^INDENT:[[:space:]]*//' | head -1)
|
|
773
783
|
|
|
774
784
|
success "Smart detection: ${ARCHITECTURE_PATTERN:-unknown} architecture${FRAMEWORK:+, ${FRAMEWORK}}"
|
|
@@ -818,6 +828,7 @@ prep_learn_patterns() {
|
|
|
818
828
|
# Write patterns file atomically
|
|
819
829
|
local tmp_patterns
|
|
820
830
|
tmp_patterns=$(mktemp)
|
|
831
|
+
# shellcheck disable=SC2064
|
|
821
832
|
trap "rm -f '$tmp_patterns'" RETURN
|
|
822
833
|
jq -n \
|
|
823
834
|
--arg ts "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
|
|
@@ -947,6 +958,24 @@ prep_generate_settings() {
|
|
|
947
958
|
success "Generated .claude/settings.json"
|
|
948
959
|
}
|
|
949
960
|
|
|
961
|
+
# ─── prep_generate_managed_mcp ────────────────────────────────────────────────
|
|
962
|
+
|
|
963
|
+
prep_generate_managed_mcp() {
|
|
964
|
+
local filepath="$PROJECT_ROOT/.claude/managed-mcp.json"
|
|
965
|
+
if ! should_write "$filepath"; then return; fi
|
|
966
|
+
|
|
967
|
+
info "Generating .claude/managed-mcp.json..."
|
|
968
|
+
|
|
969
|
+
jq -n '{
|
|
970
|
+
"allowedMcpServers": ["*"],
|
|
971
|
+
"deniedMcpServers": [],
|
|
972
|
+
"note": "Configure MCP server access policies for pipeline agents"
|
|
973
|
+
}' > "$filepath"
|
|
974
|
+
|
|
975
|
+
track_file "$filepath"
|
|
976
|
+
success "Generated .claude/managed-mcp.json"
|
|
977
|
+
}
|
|
978
|
+
|
|
950
979
|
# ─── prep_generate_hooks ────────────────────────────────────────────────────
|
|
951
980
|
|
|
952
981
|
prep_generate_hooks() {
|
|
@@ -1572,6 +1601,156 @@ prep_check() {
|
|
|
1572
1601
|
echo ""
|
|
1573
1602
|
}
|
|
1574
1603
|
|
|
1604
|
+
# ─── generate_quality_profile — Interactive quality profile dialogue ────────
|
|
1605
|
+
|
|
1606
|
+
generate_quality_profile() {
|
|
1607
|
+
local profile_path="$PROJECT_ROOT/.claude/quality-profile.json"
|
|
1608
|
+
|
|
1609
|
+
# Load quality-profile library
|
|
1610
|
+
if [[ -f "$SCRIPT_DIR/lib/quality-profile.sh" ]]; then
|
|
1611
|
+
source "$SCRIPT_DIR/lib/quality-profile.sh"
|
|
1612
|
+
else
|
|
1613
|
+
warn "quality-profile.sh library not found"
|
|
1614
|
+
return 1
|
|
1615
|
+
fi
|
|
1616
|
+
|
|
1617
|
+
info "Generating quality profile..."
|
|
1618
|
+
|
|
1619
|
+
# Start with inferred values
|
|
1620
|
+
local inferred
|
|
1621
|
+
inferred=$(qp_infer_from_repo)
|
|
1622
|
+
|
|
1623
|
+
# Generate base profile
|
|
1624
|
+
local base_profile
|
|
1625
|
+
base_profile=$(generate_default_profile)
|
|
1626
|
+
|
|
1627
|
+
# In interactive mode, ask refinement questions
|
|
1628
|
+
if $INTERACTIVE; then
|
|
1629
|
+
echo ""
|
|
1630
|
+
echo -e "${CYAN}${BOLD}Quality Profile Setup${RESET}"
|
|
1631
|
+
echo -e "${DIM}Answer these questions to calibrate quality standards:${RESET}"
|
|
1632
|
+
echo ""
|
|
1633
|
+
|
|
1634
|
+
# Q1: Max PR size
|
|
1635
|
+
local max_pr_lines
|
|
1636
|
+
read -p "Max PR size in lines (default 500): " max_pr_lines
|
|
1637
|
+
max_pr_lines="${max_pr_lines:-500}"
|
|
1638
|
+
|
|
1639
|
+
# Q2: Max files per PR
|
|
1640
|
+
local max_files
|
|
1641
|
+
read -p "Max files per PR (default 15): " max_files
|
|
1642
|
+
max_files="${max_files:-15}"
|
|
1643
|
+
|
|
1644
|
+
# Q3: Test philosophy
|
|
1645
|
+
echo ""
|
|
1646
|
+
echo -e "${DIM}Test philosophy:${RESET}"
|
|
1647
|
+
echo " 1. test_after (default)"
|
|
1648
|
+
echo " 2. tdd"
|
|
1649
|
+
echo " 3. coverage_target"
|
|
1650
|
+
echo " 4. manual"
|
|
1651
|
+
read -p "Choose [1-4]: " test_choice
|
|
1652
|
+
|
|
1653
|
+
local philosophy="test_after"
|
|
1654
|
+
case "$test_choice" in
|
|
1655
|
+
2) philosophy="tdd" ;;
|
|
1656
|
+
3) philosophy="coverage_target" ;;
|
|
1657
|
+
4) philosophy="manual" ;;
|
|
1658
|
+
esac
|
|
1659
|
+
|
|
1660
|
+
# Q4: Architecture pattern
|
|
1661
|
+
echo ""
|
|
1662
|
+
echo -e "${DIM}Architecture pattern:${RESET}"
|
|
1663
|
+
echo " 1. monolith (default)"
|
|
1664
|
+
echo " 2. modular_monolith"
|
|
1665
|
+
echo " 3. microservices"
|
|
1666
|
+
echo " 4. serverless"
|
|
1667
|
+
echo " 5. library"
|
|
1668
|
+
read -p "Choose [1-5]: " arch_choice
|
|
1669
|
+
|
|
1670
|
+
local arch_pattern="monolith"
|
|
1671
|
+
case "$arch_choice" in
|
|
1672
|
+
2) arch_pattern="modular_monolith" ;;
|
|
1673
|
+
3) arch_pattern="microservices" ;;
|
|
1674
|
+
4) arch_pattern="serverless" ;;
|
|
1675
|
+
5) arch_pattern="library" ;;
|
|
1676
|
+
esac
|
|
1677
|
+
|
|
1678
|
+
# Q5: Never ship rules
|
|
1679
|
+
echo ""
|
|
1680
|
+
read -p "Critical rules to never ship (comma-separated, or press Enter to skip): " never_ship
|
|
1681
|
+
|
|
1682
|
+
# Q6: Focus areas for code review
|
|
1683
|
+
echo ""
|
|
1684
|
+
read -p "Focus areas for review (comma-separated, e.g., 'performance,security'): " focus_areas
|
|
1685
|
+
|
|
1686
|
+
# Q7: Deployment strategy
|
|
1687
|
+
echo ""
|
|
1688
|
+
echo -e "${DIM}Deployment strategy:${RESET}"
|
|
1689
|
+
echo " 1. direct (default)"
|
|
1690
|
+
echo " 2. preview_then_production"
|
|
1691
|
+
echo " 3. staged_rollout"
|
|
1692
|
+
read -p "Choose [1-3]: " deploy_choice
|
|
1693
|
+
|
|
1694
|
+
local deploy_strategy="direct"
|
|
1695
|
+
case "$deploy_choice" in
|
|
1696
|
+
2) deploy_strategy="preview_then_production" ;;
|
|
1697
|
+
3) deploy_strategy="staged_rollout" ;;
|
|
1698
|
+
esac
|
|
1699
|
+
|
|
1700
|
+
# Build the updated profile
|
|
1701
|
+
local never_ship_array="[]"
|
|
1702
|
+
if [[ -n "$never_ship" ]]; then
|
|
1703
|
+
never_ship_array=$(echo "$never_ship" | jq -R 'split(",") | map(ltrimstr(" ") | rtrimstr(" "))')
|
|
1704
|
+
fi
|
|
1705
|
+
|
|
1706
|
+
local focus_areas_array="[]"
|
|
1707
|
+
if [[ -n "$focus_areas" ]]; then
|
|
1708
|
+
focus_areas_array=$(echo "$focus_areas" | jq -R 'split(",") | map(ltrimstr(" ") | rtrimstr(" "))')
|
|
1709
|
+
fi
|
|
1710
|
+
|
|
1711
|
+
# Merge updates into base profile
|
|
1712
|
+
base_profile=$(echo "$base_profile" | jq \
|
|
1713
|
+
--arg max_pr "$max_pr_lines" \
|
|
1714
|
+
--arg max_f "$max_files" \
|
|
1715
|
+
--arg phil "$philosophy" \
|
|
1716
|
+
--arg arch "$arch_pattern" \
|
|
1717
|
+
--arg deploy "$deploy_strategy" \
|
|
1718
|
+
--argjson never_ship "$never_ship_array" \
|
|
1719
|
+
--argjson focus "$focus_areas_array" \
|
|
1720
|
+
'.quality.max_pr_lines = ($max_pr | tonumber) |
|
|
1721
|
+
.quality.max_files_per_pr = ($max_f | tonumber) |
|
|
1722
|
+
.quality.never_ship = $never_ship |
|
|
1723
|
+
.testing.philosophy = $phil |
|
|
1724
|
+
.architecture.pattern = $arch |
|
|
1725
|
+
.deployment.strategy = $deploy |
|
|
1726
|
+
.review.focus_areas = $focus'
|
|
1727
|
+
)
|
|
1728
|
+
else
|
|
1729
|
+
# Non-interactive: apply inferred values
|
|
1730
|
+
local test_cmd focus_areas arch_pattern
|
|
1731
|
+
test_cmd=$(echo "$inferred" | jq -r '.test_cmd')
|
|
1732
|
+
arch_pattern=$(echo "$inferred" | jq -r '.framework')
|
|
1733
|
+
|
|
1734
|
+
# Merge inferred test command and architecture
|
|
1735
|
+
if [[ -n "$test_cmd" && "$test_cmd" != "null" && "$test_cmd" != "" ]]; then
|
|
1736
|
+
base_profile=$(echo "$base_profile" | jq --arg cmd "$test_cmd" '.testing.test_cmd = $cmd')
|
|
1737
|
+
fi
|
|
1738
|
+
if [[ -n "$arch_pattern" && "$arch_pattern" != "null" && "$arch_pattern" != "" ]]; then
|
|
1739
|
+
base_profile=$(echo "$base_profile" | jq --arg arch "$arch_pattern" '.architecture.pattern = $arch')
|
|
1740
|
+
fi
|
|
1741
|
+
fi
|
|
1742
|
+
|
|
1743
|
+
# Save the profile
|
|
1744
|
+
if qp_save "$base_profile"; then
|
|
1745
|
+
success "Quality profile saved to .claude/quality-profile.json"
|
|
1746
|
+
track_file ".claude/quality-profile.json"
|
|
1747
|
+
return 0
|
|
1748
|
+
else
|
|
1749
|
+
error "Failed to save quality profile"
|
|
1750
|
+
return 1
|
|
1751
|
+
fi
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1575
1754
|
# ─── prep_report — Summary output ──────────────────────────────────────────
|
|
1576
1755
|
|
|
1577
1756
|
prep_report() {
|
|
@@ -1627,6 +1806,7 @@ main() {
|
|
|
1627
1806
|
# Generation
|
|
1628
1807
|
prep_generate_claude_md
|
|
1629
1808
|
prep_generate_settings
|
|
1809
|
+
prep_generate_managed_mcp
|
|
1630
1810
|
prep_generate_hooks
|
|
1631
1811
|
prep_generate_agents
|
|
1632
1812
|
prep_generate_architecture
|
|
@@ -1634,6 +1814,9 @@ main() {
|
|
|
1634
1814
|
prep_generate_dod
|
|
1635
1815
|
prep_generate_issue_templates
|
|
1636
1816
|
|
|
1817
|
+
# Quality profile (auto or interactive)
|
|
1818
|
+
generate_quality_profile
|
|
1819
|
+
|
|
1637
1820
|
# Deep analysis (optional)
|
|
1638
1821
|
prep_with_claude
|
|
1639
1822
|
|
package/scripts/sw-ps.sh
CHANGED
|
@@ -5,32 +5,12 @@
|
|
|
5
5
|
# ║ Displays a table of agents running in claude-* tmux windows with ║
|
|
6
6
|
# ║ PID, status, idle time, and pane references. ║
|
|
7
7
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
8
|
-
|
|
8
|
+
# shellcheck disable=SC2034
|
|
9
|
+
VERSION="3.3.0"
|
|
9
10
|
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
11
|
+
|
|
12
|
+
# shellcheck source=lib/bootstrap.sh
|
|
13
|
+
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/bootstrap.sh"
|
|
34
14
|
# ─── Format idle time ───────────────────────────────────────────────────────
|
|
35
15
|
format_idle() {
|
|
36
16
|
local seconds="$1"
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# shellcheck disable=SC2034
|
|
10
|
+
VERSION="3.3.0"
|
|
10
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
12
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
13
|
|
|
@@ -29,7 +30,8 @@ fi
|
|
|
29
30
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
30
31
|
emit_event() {
|
|
31
32
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
32
|
-
local payload
|
|
33
|
+
local payload
|
|
34
|
+
payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
33
35
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
34
36
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
37
|
}
|
|
@@ -79,11 +81,13 @@ sanitize_for_privacy() {
|
|
|
79
81
|
gather_pipeline_state() {
|
|
80
82
|
local privacy="${1:-stages_only}"
|
|
81
83
|
|
|
84
|
+
# shellcheck disable=SC2034
|
|
82
85
|
local state_file="${REPO_DIR}/.claude/pipeline-state.md"
|
|
83
86
|
local daemon_state="${HOME}/.shipwright/daemon-state.json"
|
|
84
87
|
local pipeline_artifacts="${REPO_DIR}/.claude/pipeline-artifacts"
|
|
85
88
|
|
|
86
|
-
local pipeline_data
|
|
89
|
+
local pipeline_data
|
|
90
|
+
pipeline_data='{
|
|
87
91
|
"status":"unknown",
|
|
88
92
|
"stages":[],
|
|
89
93
|
"agents":[],
|
|
@@ -140,6 +144,7 @@ generate_html() {
|
|
|
140
144
|
|
|
141
145
|
# Escape JSON for embedding in HTML
|
|
142
146
|
local json_escaped
|
|
147
|
+
# shellcheck disable=SC2034
|
|
143
148
|
json_escaped=$(echo "$data_json" | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
144
149
|
|
|
145
150
|
cat <<'EOF'
|
|
@@ -418,6 +423,7 @@ cmd_export() {
|
|
|
418
423
|
# Atomic write
|
|
419
424
|
local tmp_file
|
|
420
425
|
tmp_file=$(mktemp)
|
|
426
|
+
# shellcheck disable=SC2064
|
|
421
427
|
trap "rm -f '$tmp_file'" EXIT
|
|
422
428
|
echo "$html" > "$tmp_file"
|
|
423
429
|
mv "$tmp_file" "$output_file"
|
|
@@ -453,6 +459,7 @@ cmd_share() {
|
|
|
453
459
|
# Append to share links file (atomic)
|
|
454
460
|
local tmp_file
|
|
455
461
|
tmp_file=$(mktemp)
|
|
462
|
+
# shellcheck disable=SC2064
|
|
456
463
|
trap "rm -f '$tmp_file'" EXIT
|
|
457
464
|
jq ".links += [$link_entry]" "$SHARE_LINKS_FILE" > "$tmp_file"
|
|
458
465
|
mv "$tmp_file" "$SHARE_LINKS_FILE"
|
|
@@ -480,6 +487,7 @@ cmd_revoke() {
|
|
|
480
487
|
|
|
481
488
|
local tmp_file
|
|
482
489
|
tmp_file=$(mktemp)
|
|
490
|
+
# shellcheck disable=SC2064
|
|
483
491
|
trap "rm -f '$tmp_file'" EXIT
|
|
484
492
|
|
|
485
493
|
if jq ".links |= map(select(.token != \"$token\"))" "$SHARE_LINKS_FILE" > "$tmp_file"; then
|
|
@@ -545,6 +553,7 @@ cmd_config() {
|
|
|
545
553
|
[[ -z "$value" ]] && error "Value required for privacy" && return 1
|
|
546
554
|
local tmp_file
|
|
547
555
|
tmp_file=$(mktemp)
|
|
556
|
+
# shellcheck disable=SC2064
|
|
548
557
|
trap "rm -f '$tmp_file'" EXIT
|
|
549
558
|
jq ".privacy = \"$value\"" "$SHARE_CONFIG_FILE" > "$tmp_file"
|
|
550
559
|
mv "$tmp_file" "$SHARE_CONFIG_FILE"
|
|
@@ -554,6 +563,7 @@ cmd_config() {
|
|
|
554
563
|
[[ -z "$value" ]] && error "Value required for expiry (hours)" && return 1
|
|
555
564
|
local tmp_file
|
|
556
565
|
tmp_file=$(mktemp)
|
|
566
|
+
# shellcheck disable=SC2064
|
|
557
567
|
trap "rm -f '$tmp_file'" EXIT
|
|
558
568
|
jq ".expiry_hours = $value" "$SHARE_CONFIG_FILE" > "$tmp_file"
|
|
559
569
|
mv "$tmp_file" "$SHARE_CONFIG_FILE"
|
|
@@ -563,6 +573,7 @@ cmd_config() {
|
|
|
563
573
|
[[ -z "$value" ]] && error "Value required for domain" && return 1
|
|
564
574
|
local tmp_file
|
|
565
575
|
tmp_file=$(mktemp)
|
|
576
|
+
# shellcheck disable=SC2064
|
|
566
577
|
trap "rm -f '$tmp_file'" EXIT
|
|
567
578
|
jq ".custom_domain = \"$value\"" "$SHARE_CONFIG_FILE" > "$tmp_file"
|
|
568
579
|
mv "$tmp_file" "$SHARE_CONFIG_FILE"
|
|
@@ -642,6 +653,7 @@ cmd_cleanup() {
|
|
|
642
653
|
|
|
643
654
|
local tmp_file
|
|
644
655
|
tmp_file=$(mktemp)
|
|
656
|
+
# shellcheck disable=SC2064
|
|
645
657
|
trap "rm -f '$tmp_file'" EXIT
|
|
646
658
|
|
|
647
659
|
jq ".links |= map(select((.expires | fromdateiso8601) > $now_epoch_val))" "$SHARE_LINKS_FILE" > "$tmp_file"
|
package/scripts/sw-quality.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
8
|
|
|
9
|
-
VERSION="3.
|
|
9
|
+
VERSION="3.3.0"
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
12
|
|
|
@@ -30,6 +30,7 @@ fi
|
|
|
30
30
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
31
31
|
emit_event() {
|
|
32
32
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
33
|
+
# shellcheck disable=SC2155
|
|
33
34
|
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
34
35
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
35
36
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
package/scripts/sw-reaper.sh
CHANGED
|
@@ -11,32 +11,12 @@
|
|
|
11
11
|
# ║ shipwright reaper --watch Continuous loop (default: 5s) ║
|
|
12
12
|
# ║ shipwright reaper --dry-run Preview what would be reaped ║
|
|
13
13
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
14
|
-
|
|
14
|
+
# shellcheck disable=SC2034
|
|
15
|
+
VERSION="3.3.0"
|
|
15
16
|
set -euo pipefail
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# Canonical helpers (colors, output, events)
|
|
21
|
-
# shellcheck source=lib/helpers.sh
|
|
22
|
-
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
|
|
23
|
-
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
|
|
24
|
-
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
|
|
25
|
-
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
|
|
26
|
-
[[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
|
|
27
|
-
[[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
|
|
28
|
-
if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
|
|
29
|
-
now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
|
|
30
|
-
now_epoch() { date +%s; }
|
|
31
|
-
fi
|
|
32
|
-
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
33
|
-
emit_event() {
|
|
34
|
-
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
35
|
-
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
36
|
-
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
37
|
-
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
38
|
-
}
|
|
39
|
-
fi
|
|
17
|
+
|
|
18
|
+
# shellcheck source=lib/bootstrap.sh
|
|
19
|
+
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/bootstrap.sh"
|
|
40
20
|
# ─── Defaults ──────────────────────────────────────────────────────────────
|
|
41
21
|
WATCH=false
|
|
42
22
|
DRY_RUN=false
|
|
@@ -193,6 +173,8 @@ scan_and_reap() {
|
|
|
193
173
|
local skipped=0
|
|
194
174
|
local scanned=0
|
|
195
175
|
|
|
176
|
+
# shellcheck disable=SC2034
|
|
177
|
+
# shellcheck disable=SC2034
|
|
196
178
|
while IFS='|' read -r window_name pane_title pane_pid cmd pane_active pane_idle pane_dead pane_ref; do
|
|
197
179
|
[[ -z "$window_name" ]] && continue
|
|
198
180
|
|
|
@@ -291,6 +273,7 @@ cleanup_team_dirs() {
|
|
|
291
273
|
cleaned=$((cleaned + 1))
|
|
292
274
|
}
|
|
293
275
|
if [[ -d "${tasks_dir}/${team_name}" ]]; then
|
|
276
|
+
# shellcheck disable=SC2115
|
|
294
277
|
rm -rf "${tasks_dir}/${team_name}" && {
|
|
295
278
|
echo -e " ${RED}✗${RESET} Removed task dir: ${BOLD}${team_name}/${RESET}"
|
|
296
279
|
log "CLEAN_TASKS team=${team_name}"
|