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
package/scripts/sw-fix.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
|
|
|
12
13
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -43,6 +44,8 @@ REPOS=()
|
|
|
43
44
|
REPOS_FROM=""
|
|
44
45
|
TEMPLATE="fast"
|
|
45
46
|
MODEL=""
|
|
47
|
+
EFFORT_LEVEL=""
|
|
48
|
+
FALLBACK_MODEL=""
|
|
46
49
|
MAX_PARALLEL=3
|
|
47
50
|
DRY_RUN=false
|
|
48
51
|
BRANCH_PREFIX="fix/"
|
|
@@ -60,6 +63,8 @@ show_help() {
|
|
|
60
63
|
echo -e " ${DIM}--repos-from file${RESET} Read repo paths from file (one per line)"
|
|
61
64
|
echo -e " ${DIM}--pipeline template${RESET} Pipeline template (default: fast)"
|
|
62
65
|
echo -e " ${DIM}--model model${RESET} Model to use (default: auto)"
|
|
66
|
+
echo -e " ${DIM}--effort level${RESET} Effort level: low, medium, high"
|
|
67
|
+
echo -e " ${DIM}--fallback-model model${RESET} Fallback model on rate limits (default: sonnet)"
|
|
63
68
|
echo -e " ${DIM}--max-parallel N${RESET} Max concurrent pipelines (default: 3)"
|
|
64
69
|
echo -e " ${DIM}--branch-prefix prefix${RESET} Branch name prefix (default: \"fix/\")"
|
|
65
70
|
echo -e " ${DIM}--dry-run${RESET} Show what would happen without executing"
|
|
@@ -94,6 +99,14 @@ parse_args() {
|
|
|
94
99
|
MODEL="$2"
|
|
95
100
|
shift 2
|
|
96
101
|
;;
|
|
102
|
+
--effort)
|
|
103
|
+
EFFORT_LEVEL="$2"
|
|
104
|
+
shift 2
|
|
105
|
+
;;
|
|
106
|
+
--fallback-model)
|
|
107
|
+
FALLBACK_MODEL="$2"
|
|
108
|
+
shift 2
|
|
109
|
+
;;
|
|
97
110
|
--max-parallel)
|
|
98
111
|
MAX_PARALLEL="$2"
|
|
99
112
|
shift 2
|
|
@@ -222,6 +235,7 @@ fix_start() {
|
|
|
222
235
|
local sanitized
|
|
223
236
|
sanitized=$(sanitize_branch "$GOAL")
|
|
224
237
|
local branch_name="${BRANCH_PREFIX}${sanitized}"
|
|
238
|
+
# shellcheck disable=SC2155
|
|
225
239
|
local session_id="fix-$(date +%s)"
|
|
226
240
|
local state_file="$FIX_DIR/${session_id}.json"
|
|
227
241
|
local log_dir="$FIX_DIR/${session_id}-logs"
|
|
@@ -242,6 +256,8 @@ fix_start() {
|
|
|
242
256
|
echo -e " ${BOLD}Branch:${RESET} $branch_name"
|
|
243
257
|
echo -e " ${BOLD}Parallel:${RESET} $MAX_PARALLEL"
|
|
244
258
|
[[ -n "$MODEL" ]] && echo -e " ${BOLD}Model:${RESET} $MODEL"
|
|
259
|
+
[[ -n "$EFFORT_LEVEL" ]] && echo -e " ${BOLD}Effort:${RESET} $EFFORT_LEVEL"
|
|
260
|
+
[[ -n "$FALLBACK_MODEL" ]] && echo -e " ${BOLD}Fallback:${RESET} $FALLBACK_MODEL"
|
|
245
261
|
echo ""
|
|
246
262
|
|
|
247
263
|
# ─── Dry Run ────────────────────────────────────────────────────────────
|
|
@@ -289,6 +305,7 @@ fix_start() {
|
|
|
289
305
|
|
|
290
306
|
# ─── Parallel Execution ─────────────────────────────────────────────────
|
|
291
307
|
local pids=()
|
|
308
|
+
# shellcheck disable=SC2034
|
|
292
309
|
local pid_to_idx=()
|
|
293
310
|
local idx=0
|
|
294
311
|
|
|
@@ -335,6 +352,8 @@ fix_start() {
|
|
|
335
352
|
# Build pipeline command
|
|
336
353
|
local cmd=("$SCRIPT_DIR/sw-pipeline.sh" start --goal "$GOAL" --pipeline "$TEMPLATE" --skip-gates)
|
|
337
354
|
[[ -n "$MODEL" ]] && cmd+=(--model "$MODEL")
|
|
355
|
+
[[ -n "$EFFORT_LEVEL" ]] && cmd+=(--effort "$EFFORT_LEVEL")
|
|
356
|
+
[[ -n "$FALLBACK_MODEL" ]] && cmd+=(--fallback-model "$FALLBACK_MODEL")
|
|
338
357
|
|
|
339
358
|
# Run pipeline
|
|
340
359
|
"${cmd[@]}"
|
|
@@ -6,8 +6,9 @@
|
|
|
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
|
+
# shellcheck disable=SC2034
|
|
11
12
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
13
|
|
|
13
14
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -29,6 +30,7 @@ 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"
|
|
33
|
+
# shellcheck disable=SC2155
|
|
32
34
|
local 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"
|
|
@@ -118,6 +120,7 @@ discover_repos() {
|
|
|
118
120
|
|
|
119
121
|
# Paginate through org repos
|
|
120
122
|
local page=1
|
|
123
|
+
# shellcheck disable=SC2034
|
|
121
124
|
local per_page=100
|
|
122
125
|
local total_found=0
|
|
123
126
|
local has_more=true
|
|
@@ -150,6 +153,7 @@ discover_repos() {
|
|
|
150
153
|
|
|
151
154
|
name=$(echo "$repo_data" | jq -r '.name // ""')
|
|
152
155
|
full_name=$(echo "$repo_data" | jq -r '.full_name // ""')
|
|
156
|
+
# shellcheck disable=SC2034
|
|
153
157
|
url=$(echo "$repo_data" | jq -r '.url // ""')
|
|
154
158
|
archived=$(echo "$repo_data" | jq -r '.archived // false')
|
|
155
159
|
disabled=$(echo "$repo_data" | jq -r '.disabled // false')
|
|
@@ -376,7 +380,7 @@ merge_into_config() {
|
|
|
376
380
|
|
|
377
381
|
# Merge into config
|
|
378
382
|
local tmp_config="${config_path}.tmp.$$"
|
|
379
|
-
local updated_config=$(cat "$config_path")
|
|
383
|
+
local updated_config; updated_config=$(cat "$config_path")
|
|
380
384
|
|
|
381
385
|
for repo_path in "${repos_to_add[@]}"; do
|
|
382
386
|
updated_config=$(echo "$updated_config" | jq \
|
package/scripts/sw-fleet-viz.sh
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
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
|
+
# shellcheck disable=SC2034
|
|
11
12
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
13
|
|
|
13
14
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -31,6 +32,7 @@ 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"
|
|
@@ -156,6 +158,7 @@ show_workers() {
|
|
|
156
158
|
echo ""
|
|
157
159
|
|
|
158
160
|
# Get per-repo worker counts
|
|
161
|
+
# shellcheck disable=SC2034
|
|
159
162
|
local total_workers_allocated=0
|
|
160
163
|
jq -r '.active_jobs[]? | .repo' "$FLEET_STATE" 2>/dev/null | sort -u | while read -r repo; do
|
|
161
164
|
local worker_count job_count utilization
|
|
@@ -176,7 +179,7 @@ show_workers() {
|
|
|
176
179
|
echo -e "${BOLD}Remote Machines:${RESET}"
|
|
177
180
|
echo ""
|
|
178
181
|
|
|
179
|
-
if jq '.machines[]?' "$MACHINES_FILE" 2>/dev/null | grep -q
|
|
182
|
+
if jq '.machines[]?' "$MACHINES_FILE" 2>/dev/null | grep -q . 2>/dev/null; then
|
|
180
183
|
jq -r '.machines[]? | "\(.name) (\(.hostname)) — \(.status) — \(.active_jobs // 0) active"' "$MACHINES_FILE" 2>/dev/null | while read -r machine; do
|
|
181
184
|
echo -e " ${machine}"
|
|
182
185
|
done
|
|
@@ -205,8 +208,10 @@ show_insights() {
|
|
|
205
208
|
|
|
206
209
|
# Fleet-wide success rate (last 30 days)
|
|
207
210
|
local total_pipelines successful_pipelines
|
|
208
|
-
total_pipelines=$(grep '"type":"pipeline.completed"' "$EVENTS_FILE" 2>/dev/null | tail -5000 | wc -l ||
|
|
209
|
-
|
|
211
|
+
total_pipelines=$(grep '"type":"pipeline.completed"' "$EVENTS_FILE" 2>/dev/null | tail -5000 | wc -l || true)
|
|
212
|
+
total_pipelines="${total_pipelines:-0}"
|
|
213
|
+
successful_pipelines=$(grep '"type":"pipeline.completed".*"status":"success"' "$EVENTS_FILE" 2>/dev/null | tail -5000 | wc -l || true)
|
|
214
|
+
successful_pipelines="${successful_pipelines:-0}"
|
|
210
215
|
|
|
211
216
|
local success_rate=0
|
|
212
217
|
if [[ "$total_pipelines" -gt 0 ]]; then
|
package/scripts/sw-fleet.sh
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
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
|
+
# shellcheck disable=SC2034
|
|
11
12
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
13
|
|
|
13
14
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -29,6 +30,7 @@ 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"
|
|
33
|
+
# shellcheck disable=SC2155
|
|
32
34
|
local 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"
|
|
@@ -357,6 +359,7 @@ fleet_rebalance() {
|
|
|
357
359
|
# When intelligence weighting is active, use weighted demand
|
|
358
360
|
local allocated_total=0
|
|
359
361
|
local alloc_list=()
|
|
362
|
+
# shellcheck disable=SC2034
|
|
360
363
|
local use_weight="$total_weight"
|
|
361
364
|
local effective_total="$total_demand"
|
|
362
365
|
if [[ "$intel_weighting" == "true" && "$total_weight" -gt 0 ]]; then
|
|
@@ -768,6 +771,7 @@ fleet_start() {
|
|
|
768
771
|
default_max_parallel=$(jq -r '.defaults.max_parallel // 2' "$config_file")
|
|
769
772
|
default_model=$(jq -r '.defaults.model // "opus"' "$config_file")
|
|
770
773
|
local shared_events
|
|
774
|
+
# shellcheck disable=SC2034
|
|
771
775
|
shared_events=$(jq -r '.shared_events // true' "$config_file")
|
|
772
776
|
|
|
773
777
|
mkdir -p "$FLEET_DIR"
|
package/scripts/sw-github-app.sh
CHANGED
|
@@ -6,8 +6,10 @@
|
|
|
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)"
|
|
12
|
+
# shellcheck disable=SC2034
|
|
11
13
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
14
|
|
|
13
15
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -29,6 +31,7 @@ fi
|
|
|
29
31
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
30
32
|
emit_event() {
|
|
31
33
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
34
|
+
# shellcheck disable=SC2155
|
|
32
35
|
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
33
36
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
34
37
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
@@ -80,7 +83,9 @@ cmd_setup() {
|
|
|
80
83
|
# Create config atomically
|
|
81
84
|
local tmp_config
|
|
82
85
|
tmp_config=$(mktemp)
|
|
86
|
+
# shellcheck disable=SC2064
|
|
83
87
|
trap "rm -f '$tmp_config'" RETURN
|
|
88
|
+
# shellcheck disable=SC2046
|
|
84
89
|
jq -n \
|
|
85
90
|
--arg app_id "$app_id" \
|
|
86
91
|
--arg key_path "$key_path" \
|
|
@@ -185,13 +190,21 @@ _cache_token() {
|
|
|
185
190
|
|
|
186
191
|
local tmp_tokens
|
|
187
192
|
tmp_tokens=$(mktemp)
|
|
193
|
+
# shellcheck disable=SC2064
|
|
188
194
|
trap "rm -f '$tmp_tokens'" RETURN
|
|
189
195
|
|
|
196
|
+
local new_entry
|
|
197
|
+
new_entry=$(jq -n \
|
|
198
|
+
--argjson installation_id "$installation_id" \
|
|
199
|
+
--arg token "$token" \
|
|
200
|
+
--arg expires_at "$expires_at" \
|
|
201
|
+
'{installation_id: $installation_id, token: $token, expires_at: $expires_at}')
|
|
202
|
+
|
|
190
203
|
if [[ -f "$TOKENS_FILE" ]]; then
|
|
191
|
-
jq ".tokens += [
|
|
204
|
+
jq --argjson entry "$new_entry" '.tokens += [$entry]' \
|
|
192
205
|
"$TOKENS_FILE" > "$tmp_tokens"
|
|
193
206
|
else
|
|
194
|
-
jq -n ".tokens = [
|
|
207
|
+
jq -n --argjson entry "$new_entry" '.tokens = [$entry]' \
|
|
195
208
|
> "$tmp_tokens"
|
|
196
209
|
fi
|
|
197
210
|
|
|
@@ -454,7 +467,8 @@ cmd_status() {
|
|
|
454
467
|
# Show recent webhook events
|
|
455
468
|
if [[ -f "$WEBHOOK_LOG" ]]; then
|
|
456
469
|
local count
|
|
457
|
-
count=$(wc -l < "$WEBHOOK_LOG" 2>/dev/null ||
|
|
470
|
+
count=$(wc -l < "$WEBHOOK_LOG" 2>/dev/null || true)
|
|
471
|
+
count="${count:-0}"
|
|
458
472
|
if [[ "$count" -gt 0 ]]; then
|
|
459
473
|
echo -e "${BOLD}Recent Webhook Events (last 10):${RESET}"
|
|
460
474
|
tail -10 "$WEBHOOK_LOG" | jq '{timestamp, event_type}' -c
|
|
@@ -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="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
|
11
11
|
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
12
12
|
|
|
@@ -29,6 +29,7 @@ fi
|
|
|
29
29
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
30
30
|
emit_event() {
|
|
31
31
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
32
|
+
# shellcheck disable=SC2155
|
|
32
33
|
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
33
34
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
34
35
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
@@ -142,7 +143,7 @@ gh_checks_create_run() {
|
|
|
142
143
|
if [[ "$result" -ne 0 ]]; then
|
|
143
144
|
warn "Failed to create check run '${name}' (API returned ${result})" >&2
|
|
144
145
|
echo ""
|
|
145
|
-
return
|
|
146
|
+
return 1
|
|
146
147
|
fi
|
|
147
148
|
|
|
148
149
|
local run_id
|
|
@@ -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
|
|
|
@@ -29,6 +29,7 @@ fi
|
|
|
29
29
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
30
30
|
emit_event() {
|
|
31
31
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
32
|
+
# shellcheck disable=SC2155
|
|
32
33
|
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
33
34
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
34
35
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
@@ -95,7 +96,7 @@ gh_deploy_create() {
|
|
|
95
96
|
if [[ "$result" -ne 0 ]]; then
|
|
96
97
|
warn "Failed to create deployment for ref '${ref}' to '${environment}' (API returned ${result})" >&2
|
|
97
98
|
echo ""
|
|
98
|
-
return
|
|
99
|
+
return 1
|
|
99
100
|
fi
|
|
100
101
|
|
|
101
102
|
local deploy_id
|
|
@@ -6,8 +6,10 @@
|
|
|
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)"
|
|
12
|
+
# shellcheck disable=SC2034
|
|
11
13
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
14
|
|
|
13
15
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -29,12 +31,14 @@ fi
|
|
|
29
31
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
30
32
|
emit_event() {
|
|
31
33
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
32
|
-
local payload
|
|
34
|
+
local payload
|
|
35
|
+
payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
33
36
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
34
37
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
35
38
|
}
|
|
36
39
|
fi
|
|
37
40
|
# ─── Structured Event Log ──────────────────────────────────────────────────
|
|
41
|
+
# shellcheck disable=SC2034
|
|
38
42
|
EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
|
|
39
43
|
|
|
40
44
|
# ─── Cache Configuration ───────────────────────────────────────────────────
|
|
@@ -116,7 +120,9 @@ _gh_cache_stats() {
|
|
|
116
120
|
_gh_cache_init
|
|
117
121
|
local count=0
|
|
118
122
|
local total_size=0
|
|
123
|
+
# shellcheck disable=SC2034
|
|
119
124
|
local oldest=""
|
|
125
|
+
# shellcheck disable=SC2034
|
|
120
126
|
local newest=""
|
|
121
127
|
|
|
122
128
|
for f in "$GH_CACHE_DIR"/*.json; do
|
|
@@ -257,7 +263,8 @@ gh_file_change_frequency() {
|
|
|
257
263
|
since=$(date -u -d "${days} days ago" +"%Y-%m-%dT%H:%M:%SZ")
|
|
258
264
|
fi
|
|
259
265
|
|
|
260
|
-
local cache_key
|
|
266
|
+
local cache_key
|
|
267
|
+
cache_key="freq_${owner}_${repo}_$(echo "$path" | tr '/' '_')_${days}d"
|
|
261
268
|
|
|
262
269
|
local query='query($owner: String!, $repo: String!, $since: GitTimestamp!) {
|
|
263
270
|
repository(owner: $owner, name: $repo) {
|
|
@@ -301,7 +308,8 @@ gh_blame_data() {
|
|
|
301
308
|
return 0
|
|
302
309
|
fi
|
|
303
310
|
|
|
304
|
-
local cache_key
|
|
311
|
+
local cache_key
|
|
312
|
+
cache_key="blame_${owner}_${repo}_$(echo "$path" | tr '/' '_')"
|
|
305
313
|
local cached
|
|
306
314
|
cached=$(_gh_cache_get "$cache_key" "14400" 2>/dev/null) && {
|
|
307
315
|
emit_event "github.cache_hit" "key=$cache_key"
|
|
@@ -386,7 +394,8 @@ gh_similar_issues() {
|
|
|
386
394
|
fi
|
|
387
395
|
|
|
388
396
|
local search_query="repo:${owner}/${repo} is:issue is:closed ${search_text}"
|
|
389
|
-
local cache_key
|
|
397
|
+
local cache_key
|
|
398
|
+
cache_key="similar_${owner}_${repo}_$(echo "$search_text" | tr ' /' '__' | head -c 50)"
|
|
390
399
|
|
|
391
400
|
local query='query($q: String!, $limit: Int!) {
|
|
392
401
|
search(query: $q, type: ISSUE, first: $limit) {
|
|
@@ -436,7 +445,8 @@ gh_commit_history() {
|
|
|
436
445
|
return 0
|
|
437
446
|
fi
|
|
438
447
|
|
|
439
|
-
local cache_key
|
|
448
|
+
local cache_key
|
|
449
|
+
cache_key="history_${owner}_${repo}_$(echo "$path" | tr '/' '_')_${limit}"
|
|
440
450
|
local cached
|
|
441
451
|
cached=$(_gh_cache_get "$cache_key" "3600" 2>/dev/null) && {
|
|
442
452
|
emit_event "github.cache_hit" "key=$cache_key"
|
|
@@ -701,7 +711,8 @@ gh_actions_runs() {
|
|
|
701
711
|
return 0
|
|
702
712
|
fi
|
|
703
713
|
|
|
704
|
-
local cache_key
|
|
714
|
+
local cache_key
|
|
715
|
+
cache_key="actions_${owner}_${repo}_$(echo "$workflow" | tr '/' '_')_${limit}"
|
|
705
716
|
local cached
|
|
706
717
|
cached=$(_gh_cache_get "$cache_key" "900" 2>/dev/null) && {
|
|
707
718
|
emit_event "github.cache_hit" "key=$cache_key"
|
package/scripts/sw-guild.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
|
|
|
12
13
|
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
@@ -28,6 +29,7 @@ fi
|
|
|
28
29
|
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
29
30
|
emit_event() {
|
|
30
31
|
local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
|
|
32
|
+
# shellcheck disable=SC2155
|
|
31
33
|
local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
|
|
32
34
|
while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
|
|
33
35
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
@@ -39,6 +41,7 @@ GUILD_CONFIG="${GUILD_ROOT}/config.json"
|
|
|
39
41
|
GUILD_DATA="${GUILD_ROOT}/guilds.json"
|
|
40
42
|
|
|
41
43
|
# ─── Event Logging ────────────────────────────────────────────────────────
|
|
44
|
+
# shellcheck disable=SC2034
|
|
42
45
|
EVENTS_FILE="${HOME}/.shipwright/events.jsonl"
|
|
43
46
|
|
|
44
47
|
# ─── Initialization ────────────────────────────────────────────────────────
|
|
@@ -311,6 +314,7 @@ cmd_learn() {
|
|
|
311
314
|
# ─── Inject Knowledge into Prompt ────────────────────────────────────────
|
|
312
315
|
cmd_inject() {
|
|
313
316
|
local task_type="${1:-}"
|
|
317
|
+
# shellcheck disable=SC2034
|
|
314
318
|
local context="${2:-}"
|
|
315
319
|
|
|
316
320
|
if [[ -z "$task_type" ]]; then
|
package/scripts/sw-heartbeat.sh
CHANGED
|
@@ -4,39 +4,14 @@
|
|
|
4
4
|
# ║ Write · Check · List · Clear heartbeats for autonomous agents ║
|
|
5
5
|
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
6
6
|
set -euo pipefail
|
|
7
|
-
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
8
7
|
|
|
9
|
-
VERSION="3.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# ─── Cross-platform compatibility ──────────────────────────────────────────
|
|
13
|
-
# shellcheck source=lib/compat.sh
|
|
14
|
-
[[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
|
|
15
|
-
|
|
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"
|
|
8
|
+
VERSION="3.3.0"
|
|
9
|
+
# shellcheck source=lib/bootstrap.sh
|
|
10
|
+
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/bootstrap.sh"
|
|
19
11
|
|
|
20
12
|
# SQLite persistence (DB as primary read path)
|
|
21
13
|
# shellcheck source=sw-db.sh
|
|
22
14
|
[[ -f "$SCRIPT_DIR/sw-db.sh" ]] && source "$SCRIPT_DIR/sw-db.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
|
|
40
15
|
# ─── Constants ──────────────────────────────────────────────────────────────
|
|
41
16
|
HEARTBEAT_DIR="$HOME/.shipwright/heartbeats"
|
|
42
17
|
|
|
@@ -136,7 +111,7 @@ cmd_write() {
|
|
|
136
111
|
ensure_dir
|
|
137
112
|
|
|
138
113
|
local tmp_file
|
|
139
|
-
tmp_file="$(mktemp "${HEARTBEAT_DIR}/.tmp.XXXXXX")"
|
|
114
|
+
tmp_file="$(mktemp "${HEARTBEAT_DIR}/.tmp.XXXXXX")" || { error "mktemp failed for heartbeat"; return 1; }
|
|
140
115
|
|
|
141
116
|
# Build JSON with jq for proper escaping
|
|
142
117
|
jq -n \
|
|
@@ -160,7 +135,7 @@ cmd_write() {
|
|
|
160
135
|
}' > "$tmp_file" || { rm -f "$tmp_file"; return 1; }
|
|
161
136
|
|
|
162
137
|
# Atomic write
|
|
163
|
-
mv "$tmp_file" "${HEARTBEAT_DIR}/${job_id}.json"
|
|
138
|
+
mv "$tmp_file" "${HEARTBEAT_DIR}/${job_id}.json" || { rm -f "$tmp_file"; return 1; }
|
|
164
139
|
|
|
165
140
|
# Dual-write to DB when available
|
|
166
141
|
if type db_record_heartbeat >/dev/null 2>&1 && db_available 2>/dev/null; then
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
# ║ sw-hello.sh — Hello World Command ║
|
|
4
|
+
# ║ ║
|
|
5
|
+
# ║ A simple hello world command that demonstrates the CLI structure. ║
|
|
6
|
+
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
7
|
+
# shellcheck disable=SC2034
|
|
8
|
+
VERSION="3.3.0"
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
|
|
14
|
+
# Canonical helpers (colors, output, events)
|
|
15
|
+
# shellcheck source=lib/helpers.sh
|
|
16
|
+
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
|
|
17
|
+
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
|
|
18
|
+
[[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
|
|
19
|
+
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
|
|
20
|
+
[[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
|
|
21
|
+
[[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
|
|
22
|
+
|
|
23
|
+
# ─── Help text ──────────────────────────────────────────────────────────────
|
|
24
|
+
show_help() {
|
|
25
|
+
cat <<EOF
|
|
26
|
+
USAGE
|
|
27
|
+
shipwright hello [OPTIONS]
|
|
28
|
+
|
|
29
|
+
DESCRIPTION
|
|
30
|
+
A simple hello world command.
|
|
31
|
+
|
|
32
|
+
OPTIONS
|
|
33
|
+
--help, -h Show this help text
|
|
34
|
+
--version, -v Show version
|
|
35
|
+
|
|
36
|
+
EXAMPLES
|
|
37
|
+
shipwright hello Print "hello world"
|
|
38
|
+
shipwright hello --help Show this help text
|
|
39
|
+
|
|
40
|
+
EOF
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# ─── Main ───────────────────────────────────────────────────────────────────
|
|
44
|
+
main() {
|
|
45
|
+
case "${1:-}" in
|
|
46
|
+
--help|-h)
|
|
47
|
+
show_help
|
|
48
|
+
exit 0
|
|
49
|
+
;;
|
|
50
|
+
--version|-v)
|
|
51
|
+
echo "$VERSION"
|
|
52
|
+
exit 0
|
|
53
|
+
;;
|
|
54
|
+
"")
|
|
55
|
+
# No arguments: output hello world
|
|
56
|
+
echo "hello world"
|
|
57
|
+
exit 0
|
|
58
|
+
;;
|
|
59
|
+
*)
|
|
60
|
+
error "Unknown option: $1"
|
|
61
|
+
show_help
|
|
62
|
+
exit 1
|
|
63
|
+
;;
|
|
64
|
+
esac
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
main "$@"
|
package/scripts/sw-hygiene.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
|
|
|
@@ -27,6 +27,7 @@ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
|
|
|
27
27
|
emit_event() {
|
|
28
28
|
local event_type="$1"; shift
|
|
29
29
|
mkdir -p "${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
33
|
echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
|
|
@@ -103,7 +104,8 @@ detect_dead_code() {
|
|
|
103
104
|
|
|
104
105
|
# Check if function is used in other files (count lines with this function name)
|
|
105
106
|
local usage_count
|
|
106
|
-
usage_count=$(grep -r "$func" "$REPO_DIR/scripts" --include="*.sh" 2>/dev/null | wc -l
|
|
107
|
+
usage_count=$(grep -r "$func" "$REPO_DIR/scripts" --include="*.sh" 2>/dev/null | wc -l || true)
|
|
108
|
+
usage_count="${usage_count:-0}"
|
|
107
109
|
usage_count=$(printf '%s' "$usage_count" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
108
110
|
|
|
109
111
|
# Function definition counts as 1 usage; if only 1, it's unused
|
|
@@ -319,6 +321,7 @@ list_stale_branches() {
|
|
|
319
321
|
|
|
320
322
|
# Find branches not updated in 30 days
|
|
321
323
|
local old_branches
|
|
324
|
+
# shellcheck disable=SC2046
|
|
322
325
|
old_branches=$(git branch -r --format="%(refname:short)%09%(committerdate:short)" 2>/dev/null | \
|
|
323
326
|
awk -v cutoff=$(date -d "30 days ago" +%Y-%m-%d 2>/dev/null || date -v-30d +%Y-%m-%d) \
|
|
324
327
|
'$2 < cutoff {print $1}' || true)
|
|
@@ -341,10 +344,12 @@ list_stale_branches() {
|
|
|
341
344
|
analyze_size() {
|
|
342
345
|
info "Analyzing repository size..."
|
|
343
346
|
|
|
347
|
+
# shellcheck disable=SC2034
|
|
344
348
|
local total_size=0
|
|
345
349
|
|
|
346
350
|
# Find large files
|
|
347
351
|
info "Largest files:"
|
|
352
|
+
# shellcheck disable=SC2038
|
|
348
353
|
find "$REPO_DIR" -type f ! -path '*/.git/*' ! -path '*/node_modules/*' 2>/dev/null | \
|
|
349
354
|
xargs ls -lh 2>/dev/null | \
|
|
350
355
|
awk '{print $5, $9}' | \
|
|
@@ -403,6 +408,7 @@ scan_platform_refactor() {
|
|
|
403
408
|
grep -rnE "hardcoded|Hardcoded|Fallback:|fallback:|TODO|FIXME|HACK|KLUDGE" "$scripts_dir" --include="*.sh" 2>/dev/null > "$findings_raw" || true
|
|
404
409
|
while IFS= read -r line; do
|
|
405
410
|
[[ -z "$line" ]] && continue
|
|
411
|
+
# shellcheck disable=SC2318
|
|
406
412
|
local f="${line%%:*}" rest="${line#*:}" ln="${rest%%:*}"
|
|
407
413
|
ln="${ln:-0}"
|
|
408
414
|
printf '{"file":"%s","line":%s}\n' "${f#$REPO_DIR/}" "$ln"
|
|
@@ -417,7 +423,8 @@ scan_platform_refactor() {
|
|
|
417
423
|
sizes_file=$(mktemp)
|
|
418
424
|
find "$scripts_dir" -maxdepth 1 -name "*.sh" -type f 2>/dev/null | while read -r f; do
|
|
419
425
|
local lines
|
|
420
|
-
lines=$(wc -l < "$f" 2>/dev/null ||
|
|
426
|
+
lines=$(wc -l < "$f" 2>/dev/null || true)
|
|
427
|
+
lines="${lines:-0}"
|
|
421
428
|
printf '{"script":"%s","lines":%s}\n' "$(basename "$f")" "$lines"
|
|
422
429
|
done | jq -s 'sort_by(-.lines) | .[0:15]' 2>/dev/null > "$sizes_file"
|
|
423
430
|
local script_sizes
|