shipwright-cli 3.1.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 +22 -8
- 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/config/defaults.json +25 -2
- package/config/policy.json +1 -1
- package/dashboard/middleware/auth.ts +134 -0
- package/dashboard/middleware/constants.ts +21 -0
- package/dashboard/public/index.html +8 -6
- package/dashboard/public/styles.css +176 -97
- package/dashboard/routes/auth.ts +38 -0
- package/dashboard/server.ts +117 -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/api.ts +5 -0
- 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 +12 -1
- package/dashboard/src/views/activity.ts +2 -1
- package/dashboard/src/views/metrics.ts +69 -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 +14 -2
- package/scripts/lib/daemon-dispatch.sh +106 -17
- package/scripts/lib/daemon-failure.sh +34 -4
- package/scripts/lib/daemon-patrol.sh +25 -4
- 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 +119 -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 +180 -5
- 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 +101 -3
- 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 +104 -1138
- package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
- package/scripts/lib/pipeline-quality-checks.sh +17 -711
- 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 +161 -2901
- 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 -8
- package/scripts/sw-adaptive.sh +8 -7
- 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 +15 -6
- package/scripts/sw-cleanup.sh +4 -26
- package/scripts/sw-code-review.sh +45 -20
- package/scripts/sw-connect.sh +2 -1
- package/scripts/sw-context.sh +2 -1
- package/scripts/sw-cost.sh +107 -5
- package/scripts/sw-daemon.sh +71 -11
- package/scripts/sw-dashboard.sh +3 -1
- package/scripts/sw-db.sh +71 -20
- 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 +378 -5
- 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 +12 -7
- package/scripts/sw-e2e-orchestrator.sh +17 -16
- package/scripts/sw-eventbus.sh +13 -4
- 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 +9 -4
- package/scripts/sw-fleet.sh +5 -1
- package/scripts/sw-github-app.sh +18 -4
- 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 +10 -3
- package/scripts/sw-incident.sh +273 -5
- package/scripts/sw-init.sh +18 -2
- package/scripts/sw-instrument.sh +10 -2
- package/scripts/sw-intelligence.sh +44 -7
- 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 +436 -1076
- package/scripts/sw-memory.sh +357 -3
- package/scripts/sw-mission-control.sh +6 -1
- package/scripts/sw-model-router.sh +483 -27
- package/scripts/sw-otel.sh +15 -4
- package/scripts/sw-oversight.sh +14 -5
- package/scripts/sw-patrol-meta.sh +334 -0
- package/scripts/sw-pipeline-composer.sh +7 -1
- package/scripts/sw-pipeline-vitals.sh +12 -6
- package/scripts/sw-pipeline.sh +54 -2653
- package/scripts/sw-pm.sh +16 -8
- package/scripts/sw-pr-lifecycle.sh +2 -1
- package/scripts/sw-predictive.sh +17 -5
- package/scripts/sw-prep.sh +185 -2
- package/scripts/sw-ps.sh +5 -25
- package/scripts/sw-public-dashboard.sh +17 -4
- package/scripts/sw-quality.sh +14 -6
- 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 +14 -5
- package/scripts/sw-security-audit.sh +6 -1
- package/scripts/sw-self-optimize.sh +173 -6
- 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 +14 -6
- package/scripts/sw-stream.sh +13 -4
- package/scripts/sw-swarm.sh +20 -7
- package/scripts/sw-team-stages.sh +13 -6
- package/scripts/sw-templates.sh +7 -31
- package/scripts/sw-testgen.sh +17 -6
- 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 +37 -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 +3 -2
- package/scripts/sw-upgrade.sh +3 -1
- package/scripts/sw-ux.sh +5 -2
- package/scripts/sw-webhook.sh +5 -2
- package/scripts/sw-widgets.sh +9 -4
- 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
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Module: pipeline-cli
|
|
3
|
+
# CLI parsing, config loading, help display
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
# Module guard
|
|
7
|
+
[[ -n "${_MODULE_PIPELINE_CLI_LOADED:-}" ]] && return 0; _MODULE_PIPELINE_CLI_LOADED=1
|
|
8
|
+
|
|
9
|
+
# ─── Defaults (needed if sourced independently) ──────────────────────────────
|
|
10
|
+
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
11
|
+
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
12
|
+
PROJECT_ROOT="${PROJECT_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
|
|
13
|
+
STATE_DIR="${STATE_DIR:-$PROJECT_ROOT/.claude}"
|
|
14
|
+
STATE_FILE="${STATE_FILE:-$STATE_DIR/pipeline-state.md}"
|
|
15
|
+
ARTIFACTS_DIR="${ARTIFACTS_DIR:-$STATE_DIR/pipeline-artifacts}"
|
|
16
|
+
EVENTS_FILE="${EVENTS_FILE:-$HOME/.shipwright/events.jsonl}"
|
|
17
|
+
|
|
18
|
+
# Ensure helpers are loaded
|
|
19
|
+
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh" 2>/dev/null || true
|
|
20
|
+
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo "$*"; }
|
|
21
|
+
[[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo "$*" >&2; }
|
|
22
|
+
[[ "$(type -t emit_event 2>/dev/null)" == "function" ]] || emit_event() { true; }
|
|
23
|
+
[[ "$(type -t _config_get_int 2>/dev/null)" == "function" ]] || _config_get_int() { echo "${3:-$2}"; }
|
|
24
|
+
[[ "$(type -t file_mtime 2>/dev/null)" == "function" ]] || file_mtime() { stat -f "%m" "$1" 2>/dev/null || echo "0"; }
|
|
25
|
+
[[ "$(type -t now_epoch 2>/dev/null)" == "function" ]] || now_epoch() { date +%s; }
|
|
26
|
+
|
|
27
|
+
# ─── Help ──────────────────────────────────────────────────────────
|
|
28
|
+
show_help() {
|
|
29
|
+
echo -e "${CYAN}${BOLD}shipwright pipeline${RESET} — Autonomous Feature Delivery"
|
|
30
|
+
echo ""
|
|
31
|
+
echo -e "${BOLD}USAGE${RESET}"
|
|
32
|
+
echo -e " ${CYAN}shipwright pipeline${RESET} <command> [options]"
|
|
33
|
+
echo ""
|
|
34
|
+
echo -e "${BOLD}COMMANDS${RESET}"
|
|
35
|
+
echo -e " ${CYAN}start${RESET} --goal \"...\" Start a new pipeline"
|
|
36
|
+
echo -e " ${CYAN}resume${RESET} Continue from last completed stage"
|
|
37
|
+
echo -e " ${CYAN}status${RESET} Show pipeline progress dashboard"
|
|
38
|
+
echo -e " ${CYAN}abort${RESET} Stop pipeline and mark aborted"
|
|
39
|
+
echo -e " ${CYAN}list${RESET} Show available pipeline templates"
|
|
40
|
+
echo -e " ${CYAN}show${RESET} <name> Display pipeline stages"
|
|
41
|
+
echo ""
|
|
42
|
+
echo -e "${BOLD}START OPTIONS${RESET}"
|
|
43
|
+
echo -e " ${DIM}--goal \"description\"${RESET} What to build (required unless --issue)"
|
|
44
|
+
echo -e " ${DIM}--issue <number>${RESET} Fetch goal from GitHub issue"
|
|
45
|
+
echo -e " ${DIM}--repo <path>${RESET} Change to directory before running (must be a git repo)"
|
|
46
|
+
echo -e " ${DIM}--local${RESET} Alias for --no-github --no-github-label (local-only mode)"
|
|
47
|
+
echo -e " ${DIM}--pipeline <name>${RESET} Pipeline template (default: standard)"
|
|
48
|
+
echo -e " ${DIM}--test-cmd \"command\"${RESET} Override test command (auto-detected if omitted)"
|
|
49
|
+
echo -e " ${DIM}--model <model>${RESET} Override AI model (opus, sonnet, haiku)"
|
|
50
|
+
echo -e " ${DIM}--agents <n>${RESET} Override agent count"
|
|
51
|
+
echo -e " ${DIM}--skip-gates${RESET} Auto-approve all gates (fully autonomous)"
|
|
52
|
+
echo -e " ${DIM}--headless${RESET} Full headless mode (skip gates, no prompts)"
|
|
53
|
+
echo -e " ${DIM}--base <branch>${RESET} Base branch for PR (default: main)"
|
|
54
|
+
echo -e " ${DIM}--reviewers \"a,b\"${RESET} Request PR reviewers (auto-detected if omitted)"
|
|
55
|
+
echo -e " ${DIM}--labels \"a,b\"${RESET} Add labels to PR (inherited from issue if omitted)"
|
|
56
|
+
echo -e " ${DIM}--no-github${RESET} Disable GitHub integration"
|
|
57
|
+
echo -e " ${DIM}--no-github-label${RESET} Don't modify issue labels"
|
|
58
|
+
echo -e " ${DIM}--ci${RESET} CI mode (skip gates, non-interactive)"
|
|
59
|
+
echo -e " ${DIM}--ignore-budget${RESET} Skip budget enforcement checks"
|
|
60
|
+
echo -e " ${DIM}--worktree [=name]${RESET} Run in isolated git worktree (parallel-safe)"
|
|
61
|
+
echo -e " ${DIM}--dry-run${RESET} Show what would happen without executing"
|
|
62
|
+
echo -e " ${DIM}--slack-webhook <url>${RESET} Send notifications to Slack"
|
|
63
|
+
echo -e " ${DIM}--self-heal <n>${RESET} Build→test retry cycles on failure (default: 2)"
|
|
64
|
+
echo -e " ${DIM}--max-iterations <n>${RESET} Override max build loop iterations"
|
|
65
|
+
echo -e " ${DIM}--max-restarts <n>${RESET} Max session restarts in build loop"
|
|
66
|
+
echo -e " ${DIM}--fast-test-cmd <cmd>${RESET} Fast/subset test for build loop"
|
|
67
|
+
echo -e " ${DIM}--tdd${RESET} Test-first: generate tests before implementation"
|
|
68
|
+
echo -e " ${DIM}--completed-stages \"a,b\"${RESET} Skip these stages (CI resume)"
|
|
69
|
+
echo ""
|
|
70
|
+
echo -e "${BOLD}STAGES${RESET} ${DIM}(configurable per pipeline template)${RESET}"
|
|
71
|
+
echo -e " intake → plan → design → build → test → review → pr → deploy → validate → monitor"
|
|
72
|
+
echo ""
|
|
73
|
+
echo -e "${BOLD}GITHUB INTEGRATION${RESET} ${DIM}(automatic when gh CLI available)${RESET}"
|
|
74
|
+
echo -e " • Issue intake: fetch metadata, labels, milestone, self-assign"
|
|
75
|
+
echo -e " • Progress tracking: live updates posted as issue comments"
|
|
76
|
+
echo -e " • Task checklist: plan posted as checkbox list on issue"
|
|
77
|
+
echo -e " • PR creation: labels, milestone, reviewers auto-propagated"
|
|
78
|
+
echo -e " • Issue lifecycle: labeled in-progress → closed on completion"
|
|
79
|
+
echo ""
|
|
80
|
+
echo -e "${BOLD}SELF-HEALING${RESET} ${DIM}(autonomous error recovery)${RESET}"
|
|
81
|
+
echo -e " • Build→test feedback loop: failures feed back as build context"
|
|
82
|
+
echo -e " • Configurable retry cycles (--self-heal N, default: 2)"
|
|
83
|
+
echo -e " • Auto-rebase before PR: handles base branch drift"
|
|
84
|
+
echo -e " • Signal-safe: Ctrl+C saves state for clean resume"
|
|
85
|
+
echo -e " • Git stash/restore: protects uncommitted work"
|
|
86
|
+
echo ""
|
|
87
|
+
echo -e "${BOLD}AUTO-DETECTION${RESET} ${DIM}(zero-config for common setups)${RESET}"
|
|
88
|
+
echo -e " • Test command: package.json, Makefile, Cargo.toml, go.mod, etc."
|
|
89
|
+
echo -e " • Branch prefix: feat/, fix/, refactor/ based on task type"
|
|
90
|
+
echo -e " • Reviewers: from CODEOWNERS or recent git contributors"
|
|
91
|
+
echo -e " • Project type: language and framework detection"
|
|
92
|
+
echo ""
|
|
93
|
+
echo -e "${BOLD}NOTIFICATIONS${RESET} ${DIM}(team awareness)${RESET}"
|
|
94
|
+
echo -e " • Slack: --slack-webhook <url>"
|
|
95
|
+
echo -e " • Custom webhook: set SHIPWRIGHT_WEBHOOK_URL env var"
|
|
96
|
+
echo -e " • Events: start, stage complete, failure, self-heal, done"
|
|
97
|
+
echo ""
|
|
98
|
+
echo -e "${BOLD}EXAMPLES${RESET}"
|
|
99
|
+
echo -e " ${DIM}# From GitHub issue (fully autonomous)${RESET}"
|
|
100
|
+
echo -e " ${DIM}shipwright pipeline start --issue 123 --skip-gates${RESET}"
|
|
101
|
+
echo ""
|
|
102
|
+
echo -e " ${DIM}# From inline goal${RESET}"
|
|
103
|
+
echo -e " ${DIM}shipwright pipeline start --goal \"Add JWT authentication\"${RESET}"
|
|
104
|
+
echo ""
|
|
105
|
+
echo -e " ${DIM}# Hotfix with custom test command${RESET}"
|
|
106
|
+
echo -e " ${DIM}shipwright pipeline start --issue 456 --pipeline hotfix --test-cmd \"pytest\"${RESET}"
|
|
107
|
+
echo ""
|
|
108
|
+
echo -e " ${DIM}# Full deployment pipeline with 3 agents${RESET}"
|
|
109
|
+
echo -e " ${DIM}shipwright pipeline start --goal \"Build payment flow\" --pipeline full --agents 3${RESET}"
|
|
110
|
+
echo ""
|
|
111
|
+
echo -e " ${DIM}# Parallel pipeline in isolated worktree${RESET}"
|
|
112
|
+
echo -e " ${DIM}shipwright pipeline start --issue 42 --worktree${RESET}"
|
|
113
|
+
echo ""
|
|
114
|
+
echo -e " ${DIM}# Resume / monitor / abort${RESET}"
|
|
115
|
+
echo -e " ${DIM}shipwright pipeline resume${RESET}"
|
|
116
|
+
echo -e " ${DIM}shipwright pipeline status${RESET}"
|
|
117
|
+
echo -e " ${DIM}shipwright pipeline abort${RESET}"
|
|
118
|
+
echo ""
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# ─── Argument Parsing ──────────────────────────────────────────────
|
|
122
|
+
parse_args() {
|
|
123
|
+
while [[ $# -gt 0 ]]; do
|
|
124
|
+
case "$1" in
|
|
125
|
+
--goal) GOAL="$2"; shift 2 ;;
|
|
126
|
+
--issue) ISSUE_NUMBER="$2"; shift 2 ;;
|
|
127
|
+
--repo) REPO_OVERRIDE="$2"; shift 2 ;;
|
|
128
|
+
--local) NO_GITHUB=true; NO_GITHUB_LABEL=true; shift ;;
|
|
129
|
+
--pipeline|--template) PIPELINE_NAME="$2"; shift 2 ;;
|
|
130
|
+
--test-cmd) TEST_CMD="$2"; shift 2 ;;
|
|
131
|
+
--model) MODEL="$2"; shift 2 ;;
|
|
132
|
+
--agents) AGENTS="$2"; shift 2 ;;
|
|
133
|
+
--skip-gates) SKIP_GATES=true; shift ;;
|
|
134
|
+
--headless) HEADLESS=true; SKIP_GATES=true; shift ;;
|
|
135
|
+
--base) BASE_BRANCH="$2"; shift 2 ;;
|
|
136
|
+
--reviewers) REVIEWERS="$2"; shift 2 ;;
|
|
137
|
+
--labels) LABELS="$2"; shift 2 ;;
|
|
138
|
+
--no-github) NO_GITHUB=true; shift ;;
|
|
139
|
+
--no-github-label) NO_GITHUB_LABEL=true; shift ;;
|
|
140
|
+
--ci) CI_MODE=true; SKIP_GATES=true; shift ;;
|
|
141
|
+
--ignore-budget) IGNORE_BUDGET=true; shift ;;
|
|
142
|
+
--max-iterations) MAX_ITERATIONS_OVERRIDE="$2"; shift 2 ;;
|
|
143
|
+
--completed-stages) COMPLETED_STAGES="$2"; shift 2 ;;
|
|
144
|
+
--resume) RESUME_FROM_CHECKPOINT=true; shift ;;
|
|
145
|
+
--worktree=*) AUTO_WORKTREE=true; WORKTREE_NAME="${1#--worktree=}"; WORKTREE_NAME="${WORKTREE_NAME//[^a-zA-Z0-9_-]/}"; if [[ -z "$WORKTREE_NAME" ]]; then error "Invalid worktree name (alphanumeric, hyphens, underscores only)"; exit 1; fi; shift ;;
|
|
146
|
+
--worktree) AUTO_WORKTREE=true; shift ;;
|
|
147
|
+
--dry-run) DRY_RUN=true; shift ;;
|
|
148
|
+
--slack-webhook) SLACK_WEBHOOK="$2"; shift 2 ;;
|
|
149
|
+
--self-heal) BUILD_TEST_RETRIES="${2:-3}"; shift 2 ;;
|
|
150
|
+
--max-restarts)
|
|
151
|
+
MAX_RESTARTS_OVERRIDE="$2"
|
|
152
|
+
if ! [[ "$MAX_RESTARTS_OVERRIDE" =~ ^[0-9]+$ ]]; then
|
|
153
|
+
error "--max-restarts must be numeric (got: $MAX_RESTARTS_OVERRIDE)"
|
|
154
|
+
exit 1
|
|
155
|
+
fi
|
|
156
|
+
shift 2 ;;
|
|
157
|
+
|
|
158
|
+
--fast-test-cmd) FAST_TEST_CMD_OVERRIDE="$2"; shift 2 ;;
|
|
159
|
+
--tdd) TDD_ENABLED=true; shift ;;
|
|
160
|
+
--effort)
|
|
161
|
+
EFFORT_LEVEL_OVERRIDE="${2:-}"
|
|
162
|
+
[[ -z "$EFFORT_LEVEL_OVERRIDE" ]] && { error "Missing value for --effort"; exit 1; }
|
|
163
|
+
shift 2 ;;
|
|
164
|
+
--effort=*) EFFORT_LEVEL_OVERRIDE="${1#--effort=}"; shift ;;
|
|
165
|
+
--fallback-model)
|
|
166
|
+
PIPELINE_FALLBACK_MODEL="${2:-}"
|
|
167
|
+
[[ -z "$PIPELINE_FALLBACK_MODEL" ]] && { error "Missing value for --fallback-model"; exit 1; }
|
|
168
|
+
shift 2 ;;
|
|
169
|
+
--fallback-model=*) PIPELINE_FALLBACK_MODEL="${1#--fallback-model=}"; shift ;;
|
|
170
|
+
--help|-h) show_help; exit 0 ;;
|
|
171
|
+
*)
|
|
172
|
+
if [[ -z "$PIPELINE_NAME_ARG" ]]; then
|
|
173
|
+
PIPELINE_NAME_ARG="$1"
|
|
174
|
+
fi
|
|
175
|
+
shift ;;
|
|
176
|
+
esac
|
|
177
|
+
done
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
# ─── Directory Setup ───────────────────────────────────────────────
|
|
181
|
+
setup_dirs() {
|
|
182
|
+
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
183
|
+
STATE_DIR="$PROJECT_ROOT/.claude"
|
|
184
|
+
STATE_FILE="$STATE_DIR/pipeline-state.md"
|
|
185
|
+
ARTIFACTS_DIR="$STATE_DIR/pipeline-artifacts"
|
|
186
|
+
export ARTIFACTS_DIR # Export so child processes (sw-loop.sh) can write audit events
|
|
187
|
+
TASKS_FILE="$STATE_DIR/pipeline-tasks.md"
|
|
188
|
+
mkdir -p "$STATE_DIR" "$ARTIFACTS_DIR"
|
|
189
|
+
export SHIPWRIGHT_PIPELINE_ID="pipeline-$$-${ISSUE_NUMBER:-0}"
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# ─── Pipeline Config Loading ───────────────────────────────────────
|
|
193
|
+
find_pipeline_config() {
|
|
194
|
+
local name="$1"
|
|
195
|
+
local locations=(
|
|
196
|
+
"$REPO_DIR/templates/pipelines/${name}.json"
|
|
197
|
+
"${PROJECT_ROOT:-}/templates/pipelines/${name}.json"
|
|
198
|
+
"$HOME/.shipwright/pipelines/${name}.json"
|
|
199
|
+
)
|
|
200
|
+
for loc in "${locations[@]}"; do
|
|
201
|
+
if [[ -n "$loc" && -f "$loc" ]]; then
|
|
202
|
+
echo "$loc"
|
|
203
|
+
return 0
|
|
204
|
+
fi
|
|
205
|
+
done
|
|
206
|
+
return 1
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
load_pipeline_config() {
|
|
210
|
+
# Check for intelligence-composed pipeline first
|
|
211
|
+
local composed_pipeline="${ARTIFACTS_DIR}/composed-pipeline.json"
|
|
212
|
+
if [[ -f "$composed_pipeline" ]] && type composer_validate_pipeline >/dev/null 2>&1; then
|
|
213
|
+
# Use composed pipeline if fresh (within cache TTL)
|
|
214
|
+
local composed_cache_ttl
|
|
215
|
+
composed_cache_ttl=$(_config_get_int "pipeline.composed_cache_ttl" 3600 2>/dev/null || echo 3600)
|
|
216
|
+
local composed_age=99999
|
|
217
|
+
local composed_mtime
|
|
218
|
+
composed_mtime=$(file_mtime "$composed_pipeline")
|
|
219
|
+
if [[ "$composed_mtime" -gt 0 ]]; then
|
|
220
|
+
composed_age=$(( $(now_epoch) - composed_mtime ))
|
|
221
|
+
fi
|
|
222
|
+
if [[ "$composed_age" -lt "$composed_cache_ttl" ]]; then
|
|
223
|
+
local validate_json
|
|
224
|
+
validate_json=$(cat "$composed_pipeline" 2>/dev/null || echo "")
|
|
225
|
+
if [[ -n "$validate_json" ]] && composer_validate_pipeline "$validate_json" 2>/dev/null; then
|
|
226
|
+
PIPELINE_CONFIG="$composed_pipeline"
|
|
227
|
+
info "Pipeline: ${BOLD}composed${RESET} ${DIM}(intelligence-driven)${RESET}"
|
|
228
|
+
emit_event "pipeline.composed_loaded" "issue=${ISSUE_NUMBER:-0}"
|
|
229
|
+
return
|
|
230
|
+
fi
|
|
231
|
+
fi
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
PIPELINE_CONFIG=$(find_pipeline_config "$PIPELINE_NAME") || {
|
|
235
|
+
error "Pipeline template not found: $PIPELINE_NAME"
|
|
236
|
+
echo -e " Available templates: ${DIM}shipwright pipeline list${RESET}"
|
|
237
|
+
exit 1
|
|
238
|
+
}
|
|
239
|
+
info "Pipeline: ${BOLD}$PIPELINE_NAME${RESET} ${DIM}($PIPELINE_CONFIG)${RESET}"
|
|
240
|
+
# TDD from template (overridable by --tdd)
|
|
241
|
+
[[ "$(jq -r '.tdd // false' "$PIPELINE_CONFIG" 2>/dev/null)" == "true" ]] && PIPELINE_TDD=true
|
|
242
|
+
return 0
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# ─── Composed Pipeline Loading ─────────────────────────────────────
|
|
246
|
+
load_composed_pipeline() {
|
|
247
|
+
local spec_file="$1"
|
|
248
|
+
[[ ! -f "$spec_file" ]] && return 1
|
|
249
|
+
|
|
250
|
+
# Read enabled stages from composed spec
|
|
251
|
+
local composed_stages
|
|
252
|
+
composed_stages=$(jq -r '.stages // [] | .[] | .id' "$spec_file" 2>/dev/null) || return 1
|
|
253
|
+
[[ -z "$composed_stages" ]] && return 1
|
|
254
|
+
|
|
255
|
+
# Override enabled stages
|
|
256
|
+
COMPOSED_STAGES="$composed_stages"
|
|
257
|
+
|
|
258
|
+
# Override per-stage settings
|
|
259
|
+
local build_max
|
|
260
|
+
build_max=$(jq -r '.stages[] | select(.id=="build") | .max_iterations // ""' "$spec_file" 2>/dev/null) || true
|
|
261
|
+
[[ -n "$build_max" && "$build_max" != "null" ]] && COMPOSED_BUILD_ITERATIONS="$build_max"
|
|
262
|
+
|
|
263
|
+
emit_event "pipeline.composed_loaded" "stages=$(echo "$composed_stages" | wc -l | tr -d ' ')"
|
|
264
|
+
return 0
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# ─── List & Show Commands ──────────────────────────────────────────
|
|
268
|
+
pipeline_list() {
|
|
269
|
+
local locations=(
|
|
270
|
+
"$REPO_DIR/templates/pipelines"
|
|
271
|
+
"$HOME/.shipwright/pipelines"
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
echo ""
|
|
275
|
+
echo -e "${PURPLE}${BOLD}━━━ Pipeline Templates ━━━${RESET}"
|
|
276
|
+
echo ""
|
|
277
|
+
|
|
278
|
+
local found=false
|
|
279
|
+
for dir in "${locations[@]}"; do
|
|
280
|
+
if [[ -d "$dir" ]]; then
|
|
281
|
+
for f in "$dir"/*.json; do
|
|
282
|
+
[[ -f "$f" ]] || continue
|
|
283
|
+
found=true
|
|
284
|
+
local name desc stages_enabled gate_count
|
|
285
|
+
name=$(jq -r '.name' "$f" 2>/dev/null)
|
|
286
|
+
desc=$(jq -r '.description' "$f" 2>/dev/null)
|
|
287
|
+
stages_enabled=$(jq -r '[.stages[] | select(.enabled == true) | .id] | join(" → ")' "$f" 2>/dev/null)
|
|
288
|
+
gate_count=$(jq '[.stages[] | select(.gate == "approve" and .enabled == true)] | length' "$f" 2>/dev/null)
|
|
289
|
+
echo -e " ${CYAN}${BOLD}$name${RESET}"
|
|
290
|
+
echo -e " $desc"
|
|
291
|
+
echo -e " ${DIM}$stages_enabled${RESET}"
|
|
292
|
+
echo -e " ${DIM}(${gate_count} approval gates)${RESET}"
|
|
293
|
+
echo ""
|
|
294
|
+
done
|
|
295
|
+
fi
|
|
296
|
+
done
|
|
297
|
+
|
|
298
|
+
if [[ "$found" != "true" ]]; then
|
|
299
|
+
warn "No pipeline templates found."
|
|
300
|
+
echo -e " Expected at: ${DIM}templates/pipelines/*.json${RESET}"
|
|
301
|
+
fi
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
pipeline_show() {
|
|
305
|
+
local name="${PIPELINE_NAME_ARG:-$PIPELINE_NAME}"
|
|
306
|
+
|
|
307
|
+
local config_file
|
|
308
|
+
config_file=$(find_pipeline_config "$name") || {
|
|
309
|
+
error "Pipeline template not found: $name"
|
|
310
|
+
echo -e " Available: ${DIM}shipwright pipeline list${RESET}"
|
|
311
|
+
exit 1
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
echo ""
|
|
315
|
+
echo -e "${PURPLE}${BOLD}━━━ Pipeline: $(jq -r '.name' "$config_file") ━━━${RESET}"
|
|
316
|
+
echo -e " $(jq -r '.description' "$config_file")"
|
|
317
|
+
echo ""
|
|
318
|
+
|
|
319
|
+
echo -e "${BOLD} Defaults:${RESET}"
|
|
320
|
+
jq -r '.defaults | to_entries[] | " \(.key): \(.value)"' "$config_file" 2>/dev/null
|
|
321
|
+
echo ""
|
|
322
|
+
|
|
323
|
+
echo -e "${BOLD} Stages:${RESET}"
|
|
324
|
+
jq -r '.stages[] |
|
|
325
|
+
(if .enabled then " ✓" else " ○" end) +
|
|
326
|
+
" \(.id)" +
|
|
327
|
+
(if .gate == "approve" then " [gate: approve]" elif .gate == "skip" then " [skip]" else "" end)
|
|
328
|
+
' "$config_file" 2>/dev/null
|
|
329
|
+
echo ""
|
|
330
|
+
|
|
331
|
+
echo -e "${BOLD} GitHub Integration:${RESET}"
|
|
332
|
+
echo -e " • Issue: self-assign, label lifecycle, progress comments"
|
|
333
|
+
echo -e " • PR: labels, milestone, reviewers auto-propagated"
|
|
334
|
+
echo -e " • Validation: auto-close issue on completion"
|
|
335
|
+
echo ""
|
|
336
|
+
}
|