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,300 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
# ║ error-actionability — Score and enhance error messages for clarity ║
|
|
4
|
+
# ║ ║
|
|
5
|
+
# ║ Scores errors 0-100 based on actionability cues: ║
|
|
6
|
+
# ║ - File path present (25 pts) ║
|
|
7
|
+
# ║ - Line number present (20 pts) ║
|
|
8
|
+
# ║ - Specific error type (20 pts) ║
|
|
9
|
+
# ║ - Actionable detail (20 pts) ║
|
|
10
|
+
# ║ - Fix suggestion (15 pts) ║
|
|
11
|
+
# ║ ║
|
|
12
|
+
# ║ Auto-enhances low-scoring errors (<70) with context. ║
|
|
13
|
+
# ║ Provides error extraction, deduplication, and classification. ║
|
|
14
|
+
# ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
# Module guard
|
|
18
|
+
[[ -n "${_MODULE_ERROR_ACTIONABILITY_LOADED:-}" ]] && return 0
|
|
19
|
+
_MODULE_ERROR_ACTIONABILITY_LOADED=1
|
|
20
|
+
|
|
21
|
+
VERSION="3.3.0"
|
|
22
|
+
|
|
23
|
+
# Score an error message for actionability
|
|
24
|
+
# Input: error message (string)
|
|
25
|
+
# Output: JSON with score, breakdown, and suggestions
|
|
26
|
+
score_error_actionability() {
|
|
27
|
+
local error_msg="$1"
|
|
28
|
+
local score=0
|
|
29
|
+
local has_filepath=0
|
|
30
|
+
local has_line_number=0
|
|
31
|
+
local has_error_type=0
|
|
32
|
+
local has_actionable_detail=0
|
|
33
|
+
local has_fix_suggestion=0
|
|
34
|
+
|
|
35
|
+
# Check for file path (e.g., /path/to/file.sh, ./scripts/file.sh, scripts/file.sh)
|
|
36
|
+
if [[ $error_msg =~ (/[a-zA-Z0-9._/-]+\.[a-zA-Z]+|\./(scripts|src|lib)/[a-zA-Z0-9._/-]+|scripts/[a-zA-Z0-9._/-]+) ]]; then
|
|
37
|
+
has_filepath=1
|
|
38
|
+
score=$((score + 25))
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Check for line number (e.g., :123, line 123, at line 456)
|
|
42
|
+
if [[ $error_msg =~ (:[0-9]+|line [0-9]+|at line [0-9]+) ]]; then
|
|
43
|
+
has_line_number=1
|
|
44
|
+
score=$((score + 20))
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Check for specific error types (e.g., TypeError, SyntaxError, ENOENT, EACCES, etc.)
|
|
48
|
+
if [[ $error_msg =~ (Error|Exception|ENOENT|EACCES|EAGAIN|EPERM|EEXIST|EISDIR|TypeError|SyntaxError|ReferenceError|RangeError|AssertionError) ]]; then
|
|
49
|
+
has_error_type=1
|
|
50
|
+
score=$((score + 20))
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Check for actionable details (e.g., "cannot read property", "is not a function", "does not exist", "permission denied", "not found")
|
|
54
|
+
if [[ $error_msg =~ (cannot|not found|does not exist|permission denied|not a function|is undefined|is null|unexpected token|invalid|failed to) ]]; then
|
|
55
|
+
has_actionable_detail=1
|
|
56
|
+
score=$((score + 20))
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Check for fix suggestions (e.g., "try", "check", "ensure", "verify", "install", "add", "remove")
|
|
60
|
+
if [[ $error_msg =~ (try |check |ensure |verify |install |add |remove |run |use |export |define ) ]]; then
|
|
61
|
+
has_fix_suggestion=1
|
|
62
|
+
score=$((score + 15))
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Cap score at 100
|
|
66
|
+
if [[ $score -gt 100 ]]; then
|
|
67
|
+
score=100
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Output as JSON
|
|
71
|
+
local json="{
|
|
72
|
+
\"score\": $score,
|
|
73
|
+
\"breakdown\": {
|
|
74
|
+
\"filepath\": $has_filepath,
|
|
75
|
+
\"line_number\": $has_line_number,
|
|
76
|
+
\"error_type\": $has_error_type,
|
|
77
|
+
\"actionable_detail\": $has_actionable_detail,
|
|
78
|
+
\"fix_suggestion\": $has_fix_suggestion
|
|
79
|
+
},
|
|
80
|
+
\"threshold_met\": $([ $score -lt 70 ] && echo "false" || echo "true")
|
|
81
|
+
}"
|
|
82
|
+
|
|
83
|
+
echo "$json"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Enhance a low-scoring error with category labels and file context
|
|
87
|
+
# Input: error message, optionally the file path and line number
|
|
88
|
+
# Output: enhanced error message
|
|
89
|
+
enhance_error_message() {
|
|
90
|
+
local error_msg="$1"
|
|
91
|
+
local filepath="${2:-}"
|
|
92
|
+
local line_number="${3:-}"
|
|
93
|
+
local category=""
|
|
94
|
+
|
|
95
|
+
# Determine error category
|
|
96
|
+
if [[ $error_msg =~ (cannot read|cannot access|no such file|ENOENT|EACCES|permission denied) ]]; then
|
|
97
|
+
category="FILE_ACCESS"
|
|
98
|
+
elif [[ $error_msg =~ (is not a function|is undefined|cannot call|is not callable) ]]; then
|
|
99
|
+
category="FUNCTION_ERROR"
|
|
100
|
+
elif [[ $error_msg =~ (unexpected token|syntax error|parse error) ]]; then
|
|
101
|
+
category="SYNTAX_ERROR"
|
|
102
|
+
elif [[ $error_msg =~ (type error|is not|expected) ]]; then
|
|
103
|
+
category="TYPE_ERROR"
|
|
104
|
+
elif [[ $error_msg =~ (assertion|assert|expected|failed) ]]; then
|
|
105
|
+
category="ASSERTION_FAILURE"
|
|
106
|
+
elif [[ $error_msg =~ (timeout|timed out|hang|deadlock) ]]; then
|
|
107
|
+
category="TIMEOUT"
|
|
108
|
+
elif [[ $error_msg =~ (out of memory|OOM|memory|stack) ]]; then
|
|
109
|
+
category="MEMORY_ERROR"
|
|
110
|
+
elif [[ $error_msg =~ (network|socket|ECONNREFUSED|ECONNRESET|ETIMEDOUT) ]]; then
|
|
111
|
+
category="NETWORK_ERROR"
|
|
112
|
+
else
|
|
113
|
+
category="UNKNOWN"
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# Extract file path and line number from error if not provided
|
|
117
|
+
local extracted_filepath=""
|
|
118
|
+
local extracted_line=""
|
|
119
|
+
|
|
120
|
+
if [[ -z "$filepath" && $error_msg =~ (/[a-zA-Z0-9._/-]+\.[a-zA-Z]+|\./(scripts|src|lib)/[a-zA-Z0-9._/-]+) ]]; then
|
|
121
|
+
extracted_filepath="${BASH_REMATCH[0]}"
|
|
122
|
+
else
|
|
123
|
+
extracted_filepath="$filepath"
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if [[ -z "$line_number" && $error_msg =~ (:[0-9]+) ]]; then
|
|
127
|
+
extracted_line="${BASH_REMATCH[1]#:}"
|
|
128
|
+
else
|
|
129
|
+
extracted_line="$line_number"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# Build enhanced message
|
|
133
|
+
local enhanced="[${category}] ${error_msg}"
|
|
134
|
+
|
|
135
|
+
# Add file context if available
|
|
136
|
+
if [[ -n "$extracted_filepath" ]] && [[ -f "$extracted_filepath" ]]; then
|
|
137
|
+
if [[ -n "$extracted_line" ]] && [[ $extracted_line =~ ^[0-9]+$ ]]; then
|
|
138
|
+
# Show context around the line (2 lines before and after)
|
|
139
|
+
local start_line=$((extracted_line - 2))
|
|
140
|
+
local end_line=$((extracted_line + 2))
|
|
141
|
+
[[ $start_line -lt 1 ]] && start_line=1
|
|
142
|
+
|
|
143
|
+
enhanced+=$'\n Context: '
|
|
144
|
+
if command -v sed &>/dev/null; then
|
|
145
|
+
enhanced+=$(sed -n "${start_line},${end_line}p" "$extracted_filepath" 2>/dev/null | \
|
|
146
|
+
awk -v target_line="$extracted_line" 'NR==target_line-start+1 {print " > " $0; next} {print " " $0}' \
|
|
147
|
+
-v start="$start_line" || echo "")
|
|
148
|
+
fi
|
|
149
|
+
fi
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
echo "$enhanced"
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# Main entry point: Score and optionally enhance an error
|
|
156
|
+
# Usage: eval_error_message "error message" [filepath] [line_number]
|
|
157
|
+
eval_error_message() {
|
|
158
|
+
local error_msg="$1"
|
|
159
|
+
local filepath="${2:-}"
|
|
160
|
+
local line_number="${3:-}"
|
|
161
|
+
|
|
162
|
+
# Score the error
|
|
163
|
+
local score_json
|
|
164
|
+
score_json=$(score_error_actionability "$error_msg")
|
|
165
|
+
local score
|
|
166
|
+
score=$(echo "$score_json" | grep -o '"score": [0-9]*' | cut -d: -f2 | tr -d ' ')
|
|
167
|
+
|
|
168
|
+
# Output score info
|
|
169
|
+
echo "$score_json"
|
|
170
|
+
|
|
171
|
+
# If score < 70, enhance the message
|
|
172
|
+
if [[ $score -lt 70 ]]; then
|
|
173
|
+
echo "---ENHANCEMENT---"
|
|
174
|
+
enhance_error_message "$error_msg" "$filepath" "$line_number"
|
|
175
|
+
fi
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
# For simple cases: just get the score
|
|
179
|
+
get_error_score() {
|
|
180
|
+
local error_msg="$1"
|
|
181
|
+
local score_json
|
|
182
|
+
score_json=$(score_error_actionability "$error_msg")
|
|
183
|
+
echo "$score_json" | grep -o '"score": [0-9]*' | cut -d: -f2 | tr -d ' '
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
# For testing: check if error needs enhancement
|
|
187
|
+
needs_enhancement() {
|
|
188
|
+
local error_msg="$1"
|
|
189
|
+
local score
|
|
190
|
+
score=$(get_error_score "$error_msg")
|
|
191
|
+
[[ $score -lt 70 ]] && return 0 || return 1
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# ─── Additional Functions for Issue #187 ──────────────────────────────────
|
|
195
|
+
|
|
196
|
+
# Extract file and line number from error message
|
|
197
|
+
# Output: JSON with file and line fields, or empty if not found
|
|
198
|
+
erract_extract_location() {
|
|
199
|
+
local error_msg="$1"
|
|
200
|
+
local file=""
|
|
201
|
+
local line=""
|
|
202
|
+
|
|
203
|
+
# Pattern 1: file.sh:123
|
|
204
|
+
if [[ $error_msg =~ ([a-zA-Z0-9._/-]+\.[a-zA-Z]+):([0-9]+) ]]; then
|
|
205
|
+
file="${BASH_REMATCH[1]}"
|
|
206
|
+
line="${BASH_REMATCH[2]}"
|
|
207
|
+
# Pattern 2: at line 123
|
|
208
|
+
elif [[ $error_msg =~ at[[:space:]]+line[[:space:]]+([0-9]+) ]]; then
|
|
209
|
+
line="${BASH_REMATCH[1]}"
|
|
210
|
+
# Pattern 3: File "file.py", line 123
|
|
211
|
+
elif [[ $error_msg =~ File[[:space:]]+\"([^\"]+)\",[[:space:]]+line[[:space:]]+([0-9]+) ]]; then
|
|
212
|
+
file="${BASH_REMATCH[1]}"
|
|
213
|
+
line="${BASH_REMATCH[2]}"
|
|
214
|
+
fi
|
|
215
|
+
|
|
216
|
+
# Output JSON
|
|
217
|
+
if [[ -n "$file" ]] || [[ -n "$line" ]]; then
|
|
218
|
+
jq -n \
|
|
219
|
+
--arg file "$file" \
|
|
220
|
+
--arg line "$line" \
|
|
221
|
+
'{file: $file, line: ($line | tonumber? // empty)}'
|
|
222
|
+
else
|
|
223
|
+
echo "{}"
|
|
224
|
+
fi
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
# Remove duplicate error lines and ANSI codes
|
|
228
|
+
# Collapses repeated lines into "... (repeated N times)"
|
|
229
|
+
# Output: cleaned error output (max 50 lines by default)
|
|
230
|
+
erract_deduplicate() {
|
|
231
|
+
local error_output="$1"
|
|
232
|
+
local max_lines="${2:-50}"
|
|
233
|
+
local prev_line=""
|
|
234
|
+
local repeat_count=0
|
|
235
|
+
local line_num=0
|
|
236
|
+
|
|
237
|
+
while IFS= read -r line; do
|
|
238
|
+
line_num=$((line_num + 1))
|
|
239
|
+
|
|
240
|
+
# Strip ANSI color codes using sed (bash 3.2 compatible)
|
|
241
|
+
local clean_line
|
|
242
|
+
clean_line=$(printf '%s' "$line" | sed 's/\x1b\[[0-9;]*m//g')
|
|
243
|
+
|
|
244
|
+
# Skip empty lines
|
|
245
|
+
[[ -z "$clean_line" ]] && continue
|
|
246
|
+
|
|
247
|
+
# Check if this line is same as previous
|
|
248
|
+
if [[ "$clean_line" == "$prev_line" ]]; then
|
|
249
|
+
repeat_count=$((repeat_count + 1))
|
|
250
|
+
else
|
|
251
|
+
# Output previous line (if there was repetition)
|
|
252
|
+
if [[ $repeat_count -gt 0 ]]; then
|
|
253
|
+
printf '%s (repeated %d times)\n' "$prev_line" "$repeat_count"
|
|
254
|
+
elif [[ -n "$prev_line" ]]; then
|
|
255
|
+
printf '%s\n' "$prev_line"
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
prev_line="$clean_line"
|
|
259
|
+
repeat_count=0
|
|
260
|
+
|
|
261
|
+
# Stop if we've output max_lines
|
|
262
|
+
if [[ $line_num -gt $max_lines ]]; then
|
|
263
|
+
break
|
|
264
|
+
fi
|
|
265
|
+
fi
|
|
266
|
+
done <<< "$error_output"
|
|
267
|
+
|
|
268
|
+
# Output final line
|
|
269
|
+
if [[ -n "$prev_line" ]]; then
|
|
270
|
+
if [[ $repeat_count -gt 0 ]]; then
|
|
271
|
+
printf '%s (repeated %d times)\n' "$prev_line" "$repeat_count"
|
|
272
|
+
else
|
|
273
|
+
printf '%s\n' "$prev_line"
|
|
274
|
+
fi
|
|
275
|
+
fi
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
# Classify error into one of: syntax, type, assertion, runtime, dependency, permission, network, unknown
|
|
279
|
+
# Output: error type string
|
|
280
|
+
erract_classify() {
|
|
281
|
+
local error_msg="$1"
|
|
282
|
+
|
|
283
|
+
if [[ $error_msg =~ (SyntaxError|parse error|unexpected token|invalid syntax) ]]; then
|
|
284
|
+
echo "syntax"
|
|
285
|
+
elif [[ $error_msg =~ (TypeError|type mismatch|wrong.*type|is not.*type|expected.*but got) ]]; then
|
|
286
|
+
echo "type"
|
|
287
|
+
elif [[ $error_msg =~ (AssertionError|assert|expect|should|test.*failed) ]]; then
|
|
288
|
+
echo "assertion"
|
|
289
|
+
elif [[ $error_msg =~ (segfault|Segmentation fault|OOM|out of memory|SIGKILL|signal 9|Killed|timeout|timed out) ]]; then
|
|
290
|
+
echo "runtime"
|
|
291
|
+
elif [[ $error_msg =~ (module not found|cannot find|import error|no such package|ENOENT|not found) ]]; then
|
|
292
|
+
echo "dependency"
|
|
293
|
+
elif [[ $error_msg =~ (EACCES|permission denied|permission.*denied|Access denied) ]]; then
|
|
294
|
+
echo "permission"
|
|
295
|
+
elif [[ $error_msg =~ (ECONNREFUSED|ECONNRESET|timeout|network|socket|DNS) ]]; then
|
|
296
|
+
echo "network"
|
|
297
|
+
else
|
|
298
|
+
echo "unknown"
|
|
299
|
+
fi
|
|
300
|
+
}
|