rhachet-roles-ehmpathy 1.9.0 → 1.9.1
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/dist/logic/roles/mechanic/.skills/declapract.upgrade.sh +50 -0
- package/dist/logic/roles/mechanic/.skills/init.claude.hooks.sh +113 -0
- package/dist/logic/roles/mechanic/.skills/link.claude.transcripts.sh +43 -0
- package/dist/logic/roles/mechanic/.skills/run.test.sh +245 -0
- package/dist/logic/roles/mechanic/.skills/test.integration.sh +50 -0
- package/package.json +2 -2
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = upgrade declapract and apply latest best practices
|
|
4
|
+
#
|
|
5
|
+
# .why = declapract manages development best practices and tooling
|
|
6
|
+
# configuration across projects, ensuring consistency and
|
|
7
|
+
# enabling easy upgrades to latest standards.
|
|
8
|
+
#
|
|
9
|
+
# this skill upgrades declapract packages and reapplies
|
|
10
|
+
# practices, then validates the build still passes.
|
|
11
|
+
#
|
|
12
|
+
# guarantee:
|
|
13
|
+
# ✔ verifies declapract.use.yml exists before proceeding
|
|
14
|
+
# ✔ upgrades to latest declapract packages
|
|
15
|
+
# ✔ applies practices twice (ensures idempotency)
|
|
16
|
+
# ✔ reinstalls dependencies after application
|
|
17
|
+
# ✔ fail-fast on any error
|
|
18
|
+
######################################################################
|
|
19
|
+
|
|
20
|
+
set -euo pipefail
|
|
21
|
+
|
|
22
|
+
PROJECT_ROOT="$PWD"
|
|
23
|
+
CONFIG_FILE="$PROJECT_ROOT/declapract.use.yml"
|
|
24
|
+
|
|
25
|
+
# Verify declapract config exists
|
|
26
|
+
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
27
|
+
echo "❌ no declapract.use.yml found in project root"
|
|
28
|
+
echo " $CONFIG_FILE"
|
|
29
|
+
echo "➡️ first configure declapract for this project"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
echo "📦 upgrading declapract packages..."
|
|
34
|
+
npm install --save-dev declapract@latest declapract-typescript-ehmpathy@latest
|
|
35
|
+
|
|
36
|
+
echo ""
|
|
37
|
+
echo "✨ applying best practices..."
|
|
38
|
+
npx declapract apply && npx declapract apply
|
|
39
|
+
|
|
40
|
+
echo ""
|
|
41
|
+
echo "📦 reinstalling dependencies..."
|
|
42
|
+
npm install
|
|
43
|
+
|
|
44
|
+
echo ""
|
|
45
|
+
echo "✅ declapract upgrade complete!"
|
|
46
|
+
echo ""
|
|
47
|
+
echo "⚠️ next steps:"
|
|
48
|
+
echo " 1. verify build passes: npm run test:types && npm run build"
|
|
49
|
+
echo " 2. review changes for breaking updates"
|
|
50
|
+
echo " 3. test that all still behaves as expected"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = bind mechanic SessionStart hook to Claude settings
|
|
4
|
+
#
|
|
5
|
+
# .why = the mechanic role needs to boot on every Claude session
|
|
6
|
+
# to ensure project context and briefs are loaded.
|
|
7
|
+
#
|
|
8
|
+
# this script "findserts" (find-or-insert) the SessionStart
|
|
9
|
+
# hook into .claude/settings.local.json, ensuring:
|
|
10
|
+
# • the hook is present after running this skill
|
|
11
|
+
# • no duplication if already present
|
|
12
|
+
# • idempotent: safe to rerun
|
|
13
|
+
#
|
|
14
|
+
# .how = uses jq to merge the SessionStart hook configuration
|
|
15
|
+
# into the existing hooks structure, creating it if absent.
|
|
16
|
+
#
|
|
17
|
+
# guarantee:
|
|
18
|
+
# ✔ creates .claude/settings.local.json if missing
|
|
19
|
+
# ✔ preserves existing settings (permissions, other hooks)
|
|
20
|
+
# ✔ idempotent: no-op if hook already present
|
|
21
|
+
# ✔ fail-fast on errors
|
|
22
|
+
######################################################################
|
|
23
|
+
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
PROJECT_ROOT="$PWD"
|
|
27
|
+
SETTINGS_FILE="$PROJECT_ROOT/.claude/settings.local.json"
|
|
28
|
+
|
|
29
|
+
# Define the hook configuration to findsert
|
|
30
|
+
HOOK_CONFIG=$(cat <<'EOF'
|
|
31
|
+
{
|
|
32
|
+
"hooks": {
|
|
33
|
+
"SessionStart": [
|
|
34
|
+
{
|
|
35
|
+
"matcher": "*",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "npx rhachet roles boot --repo ehmpathy --role mechanic",
|
|
40
|
+
"timeout": 60
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
EOF
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Ensure .claude directory exists
|
|
51
|
+
mkdir -p "$(dirname "$SETTINGS_FILE")"
|
|
52
|
+
|
|
53
|
+
# Initialize settings file if it doesn't exist
|
|
54
|
+
if [[ ! -f "$SETTINGS_FILE" ]]; then
|
|
55
|
+
echo "{}" > "$SETTINGS_FILE"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Findsert: merge the hook configuration if not already present
|
|
59
|
+
# Strategy: deep merge with existing hooks, creating structure if needed
|
|
60
|
+
jq --argjson hook "$HOOK_CONFIG" '
|
|
61
|
+
# Define the target command for comparison
|
|
62
|
+
def targetCmd: "npx rhachet roles boot --repo ehmpathy --role mechanic";
|
|
63
|
+
|
|
64
|
+
# Check if hook already exists
|
|
65
|
+
def hookExists:
|
|
66
|
+
(.hooks.SessionStart // [])
|
|
67
|
+
| map(select(.matcher == "*") | .hooks // [])
|
|
68
|
+
| flatten
|
|
69
|
+
| map(.command)
|
|
70
|
+
| index(targetCmd) != null;
|
|
71
|
+
|
|
72
|
+
# If hook already exists, return unchanged
|
|
73
|
+
if hookExists then
|
|
74
|
+
.
|
|
75
|
+
else
|
|
76
|
+
# Ensure .hooks exists
|
|
77
|
+
.hooks //= {} |
|
|
78
|
+
|
|
79
|
+
# Ensure .hooks.SessionStart exists
|
|
80
|
+
.hooks.SessionStart //= [] |
|
|
81
|
+
|
|
82
|
+
# Check if our matcher already exists
|
|
83
|
+
if (.hooks.SessionStart | map(.matcher) | index("*")) then
|
|
84
|
+
# Matcher exists, add our hook to its hooks array
|
|
85
|
+
.hooks.SessionStart |= map(
|
|
86
|
+
if .matcher == "*" then
|
|
87
|
+
.hooks += $hook.hooks.SessionStart[0].hooks
|
|
88
|
+
else
|
|
89
|
+
.
|
|
90
|
+
end
|
|
91
|
+
)
|
|
92
|
+
else
|
|
93
|
+
# Matcher does not exist, add the entire entry
|
|
94
|
+
.hooks.SessionStart += $hook.hooks.SessionStart
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
' "$SETTINGS_FILE" > "$SETTINGS_FILE.tmp"
|
|
98
|
+
|
|
99
|
+
# Check if any changes were made
|
|
100
|
+
if diff -q "$SETTINGS_FILE" "$SETTINGS_FILE.tmp" >/dev/null 2>&1; then
|
|
101
|
+
rm "$SETTINGS_FILE.tmp"
|
|
102
|
+
echo "👌 mechanic SessionStart hook already bound"
|
|
103
|
+
echo " $SETTINGS_FILE"
|
|
104
|
+
exit 0
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# Atomic replace
|
|
108
|
+
mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
|
|
109
|
+
|
|
110
|
+
echo "🔗 mechanic SessionStart hook bound successfully!"
|
|
111
|
+
echo " $SETTINGS_FILE"
|
|
112
|
+
echo ""
|
|
113
|
+
echo "✨ next time you start a Claude session, the mechanic will boot automatically"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = link Claude transcripts into project-local structure
|
|
4
|
+
#
|
|
5
|
+
# .why = Claude stores transcripts in ~/.claude/projects/<encoded-path>
|
|
6
|
+
# which makes them hard to browse, version-control, and sync.
|
|
7
|
+
#
|
|
8
|
+
# this script creates a symlink so transcripts appear under:
|
|
9
|
+
# <project>/.rhachet/claude/transcripts
|
|
10
|
+
#
|
|
11
|
+
# without altering, moving, or creating files in Claude storage.
|
|
12
|
+
#
|
|
13
|
+
# guarantee:
|
|
14
|
+
# ✔ zero mutation to Claude's storage
|
|
15
|
+
# ✔ fail-fast if transcripts don't exist yet
|
|
16
|
+
# ✔ safe to rerun (idempotent)
|
|
17
|
+
######################################################################
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
PROJECT_ROOT="$PWD"
|
|
22
|
+
DEST="$PROJECT_ROOT/.rhachet/claude/transcripts"
|
|
23
|
+
|
|
24
|
+
# Resolve where Claude stores transcripts for this project’s cwd
|
|
25
|
+
ENCODED_PATH="$(echo "$PROJECT_ROOT" | sed 's#/#-#g')"
|
|
26
|
+
CLAUDE_STORAGE="$HOME/.claude/projects/$ENCODED_PATH"
|
|
27
|
+
|
|
28
|
+
# Fail if Claude hasn't created the storage dir yet
|
|
29
|
+
if [[ ! -d "$CLAUDE_STORAGE" ]]; then
|
|
30
|
+
echo "❌ no Claude transcripts found for this project:"
|
|
31
|
+
echo " $CLAUDE_STORAGE"
|
|
32
|
+
echo "➡️ first run 'claude' once in this directory to create them"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Ensure our local parent folder exists (not Claude’s)
|
|
37
|
+
mkdir -p "$(dirname "$DEST")"
|
|
38
|
+
|
|
39
|
+
# Create symlink pointing into Claude-managed storage
|
|
40
|
+
ln -sfn "$CLAUDE_STORAGE" "$DEST"
|
|
41
|
+
|
|
42
|
+
echo "🔗 linked:"
|
|
43
|
+
echo " $DEST → $CLAUDE_STORAGE"
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# # tldr
|
|
4
|
+
#
|
|
5
|
+
# .what: run tests with proper setup, logs, and context preservation
|
|
6
|
+
# .why: preserve test output for review without rerun, auto-configure AWS and testdb
|
|
7
|
+
# .how: ./run.test.sh unit
|
|
8
|
+
# ./run.test.sh integration "pattern"
|
|
9
|
+
# ./run.test.sh acceptance
|
|
10
|
+
#
|
|
11
|
+
######################################################################
|
|
12
|
+
# # full
|
|
13
|
+
#
|
|
14
|
+
# .what
|
|
15
|
+
#
|
|
16
|
+
# run tests with proper setup, logs, and context preservation
|
|
17
|
+
#
|
|
18
|
+
# supports unit, integration, and acceptance tests with automatic:
|
|
19
|
+
# - output logs to .log/test/ for repeated review
|
|
20
|
+
# - scope filter and THOROUGH mode
|
|
21
|
+
# - AWS profile configuration (for repos with AWS resources)
|
|
22
|
+
# - test database provision (when start:testdb is available)
|
|
23
|
+
#
|
|
24
|
+
#
|
|
25
|
+
# .why
|
|
26
|
+
#
|
|
27
|
+
# tests require different setup depending on their type:
|
|
28
|
+
#
|
|
29
|
+
# unit tests:
|
|
30
|
+
# - isolated, no external dependencies
|
|
31
|
+
# - fast execution
|
|
32
|
+
# - use --changedSince by default for speed
|
|
33
|
+
#
|
|
34
|
+
# integration tests:
|
|
35
|
+
# - interact with databases and remote resources
|
|
36
|
+
# - require AWS credentials (if repo uses AWS)
|
|
37
|
+
# - require test databases (if repo uses a testdb)
|
|
38
|
+
# - test interactions between components
|
|
39
|
+
#
|
|
40
|
+
# acceptance tests:
|
|
41
|
+
# - end-to-end testing
|
|
42
|
+
# - require AWS credentials (if repo uses AWS)
|
|
43
|
+
# - require test database provisioning
|
|
44
|
+
# - verify complete user workflows
|
|
45
|
+
#
|
|
46
|
+
# all tests benefit from:
|
|
47
|
+
# - output logs via tee to .log/test/{type}/run.{timestamp}.out
|
|
48
|
+
# - preserved context for review without rerun
|
|
49
|
+
# - comparison of results across test runs
|
|
50
|
+
#
|
|
51
|
+
#
|
|
52
|
+
# .howto.use
|
|
53
|
+
#
|
|
54
|
+
# ## unit tests
|
|
55
|
+
#
|
|
56
|
+
# run all unit tests (uses --changedSince for speed):
|
|
57
|
+
# ./run.test.sh unit
|
|
58
|
+
#
|
|
59
|
+
# run unit tests that match a pattern (automatically THOROUGH):
|
|
60
|
+
# ./run.test.sh unit "syncPhone"
|
|
61
|
+
# ./run.test.sh unit "relate.*Path"
|
|
62
|
+
#
|
|
63
|
+
# run all unit tests thoroughly (no --changedSince):
|
|
64
|
+
# THOROUGH=true ./run.test.sh unit
|
|
65
|
+
#
|
|
66
|
+
# behavior:
|
|
67
|
+
# - no AWS_PROFILE configuration
|
|
68
|
+
# - no test database provision
|
|
69
|
+
# - uses --changedSince by default (unless scope provided or THOROUGH=true)
|
|
70
|
+
# - logs to .log/test/unit/run.{timestamp}.out
|
|
71
|
+
#
|
|
72
|
+
#
|
|
73
|
+
# ## integration tests
|
|
74
|
+
#
|
|
75
|
+
# run all integration tests:
|
|
76
|
+
# ./run.test.sh integration
|
|
77
|
+
#
|
|
78
|
+
# run integration tests that match a pattern:
|
|
79
|
+
# ./run.test.sh integration "database.*sync"
|
|
80
|
+
# ./run.test.sh integration "whodis"
|
|
81
|
+
#
|
|
82
|
+
# behavior:
|
|
83
|
+
# - sets AWS_PROFILE=$org.dev (if awsAccountId in declapract.use.yml)
|
|
84
|
+
# - runs start:testdb (if available in package.json)
|
|
85
|
+
# - uses --changedSince by default (unless scope provided or THOROUGH=true)
|
|
86
|
+
# - logs to .log/test/integration/run.{timestamp}.out
|
|
87
|
+
#
|
|
88
|
+
#
|
|
89
|
+
# ## acceptance tests
|
|
90
|
+
#
|
|
91
|
+
# run all acceptance tests locally:
|
|
92
|
+
# ./run.test.sh acceptance
|
|
93
|
+
#
|
|
94
|
+
# run acceptance tests that match a pattern:
|
|
95
|
+
# ./run.test.sh acceptance "user.*flow"
|
|
96
|
+
#
|
|
97
|
+
# behavior:
|
|
98
|
+
# - sets AWS_PROFILE=$org.dev (if awsAccountId in declapract.use.yml)
|
|
99
|
+
# - runs start:testdb (if available in package.json)
|
|
100
|
+
# - uses test:acceptance:locally (local execution only for now)
|
|
101
|
+
# - logs to .log/test/acceptance/run.{timestamp}.out
|
|
102
|
+
#
|
|
103
|
+
#
|
|
104
|
+
# ## review test output
|
|
105
|
+
#
|
|
106
|
+
# all test output is logged via tee to .log/test/{type}/run.{timestamp}.out
|
|
107
|
+
#
|
|
108
|
+
# review the latest test run:
|
|
109
|
+
# cat .log/test/unit/run.*.out | tail -n 1 | xargs cat
|
|
110
|
+
#
|
|
111
|
+
# compare test results across runs:
|
|
112
|
+
# ls -t .log/test/unit/
|
|
113
|
+
# diff .log/test/unit/run.2025-11-23T15-00-00Z.out \
|
|
114
|
+
# .log/test/unit/run.2025-11-23T15-10-00Z.out
|
|
115
|
+
#
|
|
116
|
+
# search for failures in logs:
|
|
117
|
+
# grep -r "FAIL" .log/test/unit/
|
|
118
|
+
#
|
|
119
|
+
#
|
|
120
|
+
# .guarantee
|
|
121
|
+
#
|
|
122
|
+
# ✔ configure AWS_PROFILE only if awsAccountId in declapract.use.yml
|
|
123
|
+
# ✔ provision test database only if start:testdb in package.json
|
|
124
|
+
# ✔ log output to .log/test/{type}/run.{timestamp}.out via tee
|
|
125
|
+
# ✔ preserve context for repeated review without rerun
|
|
126
|
+
# ✔ support jest pattern/scope filter
|
|
127
|
+
# ✔ automatically set THOROUGH=true when scope is provided
|
|
128
|
+
# ✔ fail-fast on test failures
|
|
129
|
+
# ✔ show relative paths for easy navigation
|
|
130
|
+
######################################################################
|
|
131
|
+
|
|
132
|
+
set -euo pipefail
|
|
133
|
+
|
|
134
|
+
# Parse arguments
|
|
135
|
+
TEST_TYPE="${1:-}"
|
|
136
|
+
SCOPE="${2:-}"
|
|
137
|
+
|
|
138
|
+
# Default to THOROUGH mode when scope is provided (unless explicitly set)
|
|
139
|
+
if [[ -n "$SCOPE" ]] && [[ -z "${THOROUGH:-}" ]]; then
|
|
140
|
+
export THOROUGH=true
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# Validate test type
|
|
144
|
+
if [[ -z "$TEST_TYPE" ]]; then
|
|
145
|
+
echo "✗ test type required"
|
|
146
|
+
echo ""
|
|
147
|
+
echo "usage: $0 <type> [pattern]"
|
|
148
|
+
echo ""
|
|
149
|
+
echo "types:"
|
|
150
|
+
echo " unit - run unit tests"
|
|
151
|
+
echo " integration - run integration tests"
|
|
152
|
+
echo " acceptance - run acceptance tests"
|
|
153
|
+
echo ""
|
|
154
|
+
echo "examples:"
|
|
155
|
+
echo " $0 unit"
|
|
156
|
+
echo " $0 integration 'database.*sync'"
|
|
157
|
+
echo " THOROUGH=true $0 unit"
|
|
158
|
+
exit 1
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
if [[ ! "$TEST_TYPE" =~ ^(unit|integration|acceptance)$ ]]; then
|
|
162
|
+
echo "✗ invalid test type: $TEST_TYPE"
|
|
163
|
+
echo " valid types: unit, integration, acceptance"
|
|
164
|
+
exit 1
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
PROJECT_ROOT="$PWD"
|
|
168
|
+
LOG_DIR="$PROJECT_ROOT/.log/test/$TEST_TYPE"
|
|
169
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
170
|
+
LOG_FILE="$LOG_DIR/run.$TIMESTAMP.out"
|
|
171
|
+
|
|
172
|
+
# Ensure log directory exists
|
|
173
|
+
mkdir -p "$LOG_DIR"
|
|
174
|
+
|
|
175
|
+
echo "→ run $TEST_TYPE tests"
|
|
176
|
+
echo "→ log to: ${LOG_FILE#$PROJECT_ROOT/}"
|
|
177
|
+
echo ""
|
|
178
|
+
|
|
179
|
+
# Configure AWS profile and provision test database for integration/acceptance tests
|
|
180
|
+
if [[ "$TEST_TYPE" == "integration" ]] || [[ "$TEST_TYPE" == "acceptance" ]]; then
|
|
181
|
+
# Check if awsAccountId is specified in declapract.use.yml
|
|
182
|
+
if [[ -f "declapract.use.yml" ]] && grep -q "awsAccountId:" declapract.use.yml; then
|
|
183
|
+
# Extract organization from declapract.use.yml
|
|
184
|
+
ORGANIZATION=$(grep -E '^\s*organizationName:' declapract.use.yml | sed "s/.*organizationName:[[:space:]]*['\"]*//" | sed "s/['\"].*//")
|
|
185
|
+
|
|
186
|
+
if [[ -n "$ORGANIZATION" ]]; then
|
|
187
|
+
# Configure AWS profile for dev resources
|
|
188
|
+
export AWS_PROFILE="$ORGANIZATION.dev"
|
|
189
|
+
echo "→ AWS_PROFILE=$AWS_PROFILE"
|
|
190
|
+
fi
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
# Start test database if available in package.json
|
|
194
|
+
if npm run | grep -q "start:testdb"; then
|
|
195
|
+
echo "→ start:testdb"
|
|
196
|
+
echo ""
|
|
197
|
+
npm run start:testdb 2>&1 | tee -a "$LOG_FILE"
|
|
198
|
+
fi
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# Build the test command
|
|
202
|
+
case "$TEST_TYPE" in
|
|
203
|
+
unit)
|
|
204
|
+
TEST_COMMAND="npm run test:unit"
|
|
205
|
+
;;
|
|
206
|
+
integration)
|
|
207
|
+
TEST_COMMAND="npm run test:integration"
|
|
208
|
+
;;
|
|
209
|
+
acceptance)
|
|
210
|
+
# only support local acceptance tests for now
|
|
211
|
+
TEST_COMMAND="npm run test:acceptance:locally"
|
|
212
|
+
;;
|
|
213
|
+
esac
|
|
214
|
+
|
|
215
|
+
# Add scope filter if provided
|
|
216
|
+
if [[ -n "$SCOPE" ]]; then
|
|
217
|
+
echo "→ scope filter: $SCOPE"
|
|
218
|
+
echo ""
|
|
219
|
+
TEST_COMMAND="$TEST_COMMAND -- '$SCOPE'"
|
|
220
|
+
else
|
|
221
|
+
echo "→ scope: all tests"
|
|
222
|
+
echo ""
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
# Run tests with output logged via tee
|
|
226
|
+
echo "> $TEST_COMMAND" | tee -a "$LOG_FILE"
|
|
227
|
+
echo "" | tee -a "$LOG_FILE"
|
|
228
|
+
|
|
229
|
+
eval "$TEST_COMMAND" 2>&1 | tee -a "$LOG_FILE"
|
|
230
|
+
TEST_EXIT_CODE=${PIPESTATUS[0]}
|
|
231
|
+
|
|
232
|
+
echo "" | tee -a "$LOG_FILE"
|
|
233
|
+
|
|
234
|
+
if [[ $TEST_EXIT_CODE -eq 0 ]]; then
|
|
235
|
+
echo "✓ $TEST_TYPE tests complete!" | tee -a "$LOG_FILE"
|
|
236
|
+
echo "→ log saved: ${LOG_FILE#$PROJECT_ROOT/}"
|
|
237
|
+
exit 0
|
|
238
|
+
else
|
|
239
|
+
echo "✗ $TEST_TYPE tests failed" | tee -a "$LOG_FILE"
|
|
240
|
+
echo "→ log saved: ${LOG_FILE#$PROJECT_ROOT/}"
|
|
241
|
+
echo ""
|
|
242
|
+
echo "→ review the log file for details:"
|
|
243
|
+
echo " cat ${LOG_FILE#$PROJECT_ROOT/}"
|
|
244
|
+
exit $TEST_EXIT_CODE
|
|
245
|
+
fi
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = run integration tests thoroughly with optional scope filter
|
|
4
|
+
#
|
|
5
|
+
# .why = integration tests verify interactions between components
|
|
6
|
+
# and external systems. running them thoroughly (without
|
|
7
|
+
# --changedSince) ensures all tests pass, not just changed ones.
|
|
8
|
+
#
|
|
9
|
+
# this is critical before releases, after major changes, or
|
|
10
|
+
# when verifying the entire test suite.
|
|
11
|
+
#
|
|
12
|
+
# usage for agents:
|
|
13
|
+
# - run all integration tests:
|
|
14
|
+
# ./test.integration.sh
|
|
15
|
+
#
|
|
16
|
+
# - run tests matching a specific scope/pattern:
|
|
17
|
+
# ./test.integration.sh <pattern>
|
|
18
|
+
# example: ./test.integration.sh "user.*auth"
|
|
19
|
+
# example: ./test.integration.sh "database"
|
|
20
|
+
#
|
|
21
|
+
# - the THOROUGH=true flag forces ALL tests to run, not just
|
|
22
|
+
# those changed since main branch
|
|
23
|
+
#
|
|
24
|
+
# guarantee:
|
|
25
|
+
# ✔ runs ALL integration tests (ignores --changedSince)
|
|
26
|
+
# ✔ supports optional jest pattern/scope filtering
|
|
27
|
+
# ✔ uses verbose output for debugging
|
|
28
|
+
# ✔ passes with no tests if scope matches nothing
|
|
29
|
+
# ✔ fail-fast on test failures
|
|
30
|
+
######################################################################
|
|
31
|
+
|
|
32
|
+
set -euo pipefail
|
|
33
|
+
|
|
34
|
+
SCOPE="${1:-}"
|
|
35
|
+
|
|
36
|
+
echo "🧪 running integration tests thoroughly..."
|
|
37
|
+
echo ""
|
|
38
|
+
|
|
39
|
+
if [[ -n "$SCOPE" ]]; then
|
|
40
|
+
echo "📍 scope filter: $SCOPE"
|
|
41
|
+
echo ""
|
|
42
|
+
THOROUGH=true npm run test:integration -- "$SCOPE"
|
|
43
|
+
else
|
|
44
|
+
echo "📍 scope: all tests"
|
|
45
|
+
echo ""
|
|
46
|
+
THOROUGH=true npm run test:integration
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
echo ""
|
|
50
|
+
echo "✅ integration tests complete!"
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "rhachet-roles-ehmpathy",
|
|
3
3
|
"author": "ehmpathy",
|
|
4
4
|
"description": "empathetic software construction roles and skills, via rhachet",
|
|
5
|
-
"version": "1.9.
|
|
5
|
+
"version": "1.9.1",
|
|
6
6
|
"repository": "ehmpathy/rhachet-roles-ehmpathy",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet-roles-ehmpathy",
|
|
8
8
|
"keywords": [
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"fix:lint": "eslint -c ./.eslintrc.js src/**/*.ts --fix",
|
|
27
27
|
"build:clean": "rm dist/ -rf",
|
|
28
28
|
"build:compile": "tsc -p ./tsconfig.build.json",
|
|
29
|
-
"build:complete": "rsync -a --prune-empty-dirs --include='*/' --exclude='**/.route/**' --exclude='**/.scratch/**' --include='**/*.template.md' --include='**/.briefs/**/*.md' --include='**/.briefs/*.md' --exclude='*' src/ dist/",
|
|
29
|
+
"build:complete": "rsync -a --prune-empty-dirs --include='*/' --exclude='**/.route/**' --exclude='**/.scratch/**' --include='**/*.template.md' --include='**/.briefs/**/*.md' --include='**/.briefs/*.md' --include='**/.skills/**/*.sh' --include='**/.skills/*.sh' --exclude='*' src/ dist/",
|
|
30
30
|
"build": "npm run build:clean && npm run build:compile && npm run build:complete",
|
|
31
31
|
"test:commits": "LAST_TAG=$(git describe --tags --abbrev=0 @^ 2> /dev/null || git rev-list --max-parents=0 HEAD) && npx commitlint --from $LAST_TAG --to HEAD --verbose",
|
|
32
32
|
"test:types": "tsc -p ./tsconfig.build.json --noEmit",
|