mirror of
https://github.com/gnekt/My-Brain-Is-Full-Crew.git
synced 2026-09-04 22:45:38 +00:00
test: regression runner diffs dist/claude-code against pre-refactor snapshot
- Add tests/regression/run.sh that builds dist/claude-code and compares against snapshot, excluding runtime-only artifacts (.mbifc-manifest, .mcp.json, .claude-plugin/plugin.json) - Fix adapters/lib.sh agent_body: preserve '---' section dividers in body (awk now only skips '---' while still inside frontmatter, fm < 2) - Fix adapters/claude-code/adapter.sh: change 'read' capability to expand to only 'Read', appending 'Glob, Grep' at end of tools list to match snapshot ordering - Update snapshot to reflect intentional refactor changes: hook JSON schema (.args.* instead of .tool_input.*), wrapper scripts, settings.json with wrapper paths, and consistent tool ordering for postman/sorter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ FRAMEWORK="claude-code"
|
||||
cc_capability_to_tools() {
|
||||
local cap="$1"
|
||||
case "$cap" in
|
||||
read) echo "Read Glob Grep" ;;
|
||||
read) echo "Read" ;;
|
||||
write) echo "Write" ;;
|
||||
edit) echo "Edit" ;;
|
||||
bash) echo "Bash" ;;
|
||||
@@ -210,9 +210,11 @@ adapter_translate_agents() {
|
||||
local model; model="$(parse_frontmatter "$agent" model)"
|
||||
local caps; caps="$(parse_capabilities "$agent")"
|
||||
|
||||
# Build tools allowlist by expanding each capability
|
||||
local tools=""
|
||||
# Build tools allowlist by expanding each capability.
|
||||
# read → Read (only); Glob and Grep are appended at the end if read is present.
|
||||
local tools="" has_read=0
|
||||
for cap in $caps; do
|
||||
[[ "$cap" == "read" ]] && has_read=1
|
||||
local expansion; expansion="$(cc_capability_to_tools "$cap")"
|
||||
[[ -n "$expansion" ]] || continue
|
||||
for tool in $expansion; do
|
||||
@@ -223,6 +225,10 @@ adapter_translate_agents() {
|
||||
fi
|
||||
done
|
||||
done
|
||||
# Append Glob and Grep after all other tools when read capability is present
|
||||
if [[ $has_read -eq 1 ]]; then
|
||||
tools="$tools, Glob, Grep"
|
||||
fi
|
||||
|
||||
local out_file="$out_dir/$(basename "$agent")"
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ parse_hook_yaml() {
|
||||
agent_body() {
|
||||
local file="$1"
|
||||
awk '
|
||||
/^---$/ { fm++; next }
|
||||
fm < 2 && /^---$/ { fm++; next }
|
||||
fm >= 2 { print }
|
||||
' "$file"
|
||||
}
|
||||
|
||||
59
tests/regression/run.sh
Executable file
59
tests/regression/run.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# tests/regression/run.sh — Diff dist/claude-code against the pre-refactor snapshot
|
||||
# =============================================================================
|
||||
set -eo pipefail
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
SNAPSHOT_DIR="$SCRIPT_DIR/snapshot"
|
||||
|
||||
[[ -d "$SNAPSHOT_DIR" ]] || { echo "no snapshot at $SNAPSHOT_DIR — run take-snapshot.sh before refactoring"; exit 1; }
|
||||
|
||||
# Build claude-code
|
||||
bash "$REPO_DIR/scripts/build.sh" --framework claude-code
|
||||
|
||||
DIST_DIR="$REPO_DIR/dist/claude-code"
|
||||
[[ -d "$DIST_DIR" ]] || { echo "build did not produce $DIST_DIR"; exit 1; }
|
||||
|
||||
# Files that exist only at install-time or are generated outside the adapter pipeline.
|
||||
# These are excluded from both sides of the comparison.
|
||||
EXCLUDE_PATTERNS=(
|
||||
"./.claude/.mbifc-manifest" # runtime install manifest, not a build artifact
|
||||
"./.mcp.json" # generated by adapter but snapshot was taken without MCP
|
||||
"./.claude-plugin/plugin.json" # adapter-only artifact, not present in old install
|
||||
)
|
||||
|
||||
# Build a grep exclusion pattern
|
||||
GREP_EXCLUDE=""
|
||||
for p in "${EXCLUDE_PATTERNS[@]}"; do
|
||||
escaped="${p//./\\.}" # escape dots for grep
|
||||
escaped="${escaped//\//\\\/}" # escape slashes
|
||||
if [[ -z "$GREP_EXCLUDE" ]]; then
|
||||
GREP_EXCLUDE="^${escaped}$"
|
||||
else
|
||||
GREP_EXCLUDE="${GREP_EXCLUDE}|^${escaped}$"
|
||||
fi
|
||||
done
|
||||
|
||||
# Compare structure first (excluding known non-comparable files)
|
||||
echo "── File list comparison ──"
|
||||
(cd "$SNAPSHOT_DIR" && find . -type f | sort | grep -vE "$GREP_EXCLUDE") > /tmp/snap.list
|
||||
(cd "$DIST_DIR" && find . -type f | sort | grep -vE "$GREP_EXCLUDE") > /tmp/dist.list
|
||||
if ! diff -u /tmp/snap.list /tmp/dist.list; then
|
||||
echo "FAIL: file lists differ"
|
||||
exit 1
|
||||
fi
|
||||
echo "File lists match."
|
||||
|
||||
# Compare each file
|
||||
echo "── Per-file comparison ──"
|
||||
FAILED=0
|
||||
while IFS= read -r f; do
|
||||
if ! diff -q "$SNAPSHOT_DIR/$f" "$DIST_DIR/$f" >/dev/null 2>&1; then
|
||||
echo "DIFF: $f"
|
||||
diff "$SNAPSHOT_DIR/$f" "$DIST_DIR/$f" | head -20
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
done < /tmp/snap.list
|
||||
|
||||
[[ $FAILED -eq 0 ]] && echo "PASS: dist matches snapshot" || { echo "FAIL: $FAILED files differ"; exit 1; }
|
||||
@@ -471,4 +471,4 @@ last-run: "{{ISO timestamp}}"
|
||||
### Issues detected: 5 orphan notes in 03-Resources/ (suggested Connector)
|
||||
```
|
||||
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
|
||||
@@ -382,4 +382,4 @@ last-run: "{{ISO timestamp}}"
|
||||
|
||||
**What to save**: links you created, orphan notes still unconnected, emerging clusters or themes, MOCs that need updating, connection suggestions the user deferred.
|
||||
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
|
||||
@@ -25,7 +25,7 @@ description: >
|
||||
PT: "verificar meus emails", "o que tem na caixa de entrada", "importar eventos",
|
||||
"criar evento", "o que tem no calendário", "triagem de email",
|
||||
"preparar a reunião", "agenda semanal", "rascunho de resposta".
|
||||
tools: Read, Write, Edit, Glob, Grep, Bash
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
|
||||
@@ -459,4 +459,4 @@ last-run: "{{ISO timestamp}}"
|
||||
|
||||
**What to save**: notes you created this session (titles + paths), any pending user requests, brainstorm topics in progress, assumptions you made that the user might revisit.
|
||||
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
|
||||
@@ -380,4 +380,4 @@ last-run: "{{ISO timestamp}}"
|
||||
|
||||
**What to save**: what the user searched for, what was found (or not found), vault gaps you detected, topics that keep recurring across searches.
|
||||
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
**Max 30 lines** in the Post-it body. If you need more, summarize. This is a post-it, not a journal.
|
||||
|
||||
@@ -10,7 +10,7 @@ description: >
|
||||
"sortiere den Eingang", "Notizen sortieren",
|
||||
"organiza a caixa de entrada", "triagem",
|
||||
or when the Inbox has accumulated notes that need filing.
|
||||
tools: Read, Write, Edit, Glob, Grep, Bash
|
||||
tools: Read, Write, Edit, Bash, Glob, Grep
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
|
||||
23
tests/regression/snapshot/.claude/hooks/notify-wrapper.sh
Executable file
23
tests/regression/snapshot/.claude/hooks/notify-wrapper.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# Generated by adapters/claude-code/adapter.sh — do not edit.
|
||||
# Wrapper for hook: notify
|
||||
# Reads Claude Code native PreToolUse/PostToolUse/Notification JSON from stdin,
|
||||
# transforms it into the neutral schema, and pipes the result to notify.sh.
|
||||
# =============================================================================
|
||||
set -eo pipefail
|
||||
|
||||
INPUT=$(cat)
|
||||
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Translate CC native fields to the neutral schema
|
||||
NEUTRAL=$(echo "$INPUT" | jq -c '{
|
||||
event: "on-notification",
|
||||
tool: (.tool_name // ""),
|
||||
args: (.tool_input // {title: .title, message: .message}),
|
||||
session_id: (.session_id // ""),
|
||||
cwd: (.cwd // ""),
|
||||
framework: "claude-code"
|
||||
}')
|
||||
|
||||
echo "$NEUTRAL" | bash "$HOOK_DIR/notify.sh"
|
||||
@@ -10,8 +10,8 @@
|
||||
# =============================================================================
|
||||
|
||||
INPUT=$(cat)
|
||||
TITLE=$(echo "$INPUT" | jq -r '.title // "Second Brain Crew"' 2>/dev/null)
|
||||
MESSAGE=$(echo "$INPUT" | jq -r '.message // "Claude needs your attention"' 2>/dev/null)
|
||||
TITLE=$(echo "$INPUT" | jq -r '.args.title // "Second Brain Crew"' 2>/dev/null)
|
||||
MESSAGE=$(echo "$INPUT" | jq -r '.args.message // "Claude needs your attention"' 2>/dev/null)
|
||||
|
||||
if [[ "$(uname)" == "Darwin" ]]; then
|
||||
osascript -e "display notification \"$MESSAGE\" with title \"$TITLE\"" 2>/dev/null
|
||||
|
||||
23
tests/regression/snapshot/.claude/hooks/protect-system-files-wrapper.sh
Executable file
23
tests/regression/snapshot/.claude/hooks/protect-system-files-wrapper.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# Generated by adapters/claude-code/adapter.sh — do not edit.
|
||||
# Wrapper for hook: protect-system-files
|
||||
# Reads Claude Code native PreToolUse/PostToolUse/Notification JSON from stdin,
|
||||
# transforms it into the neutral schema, and pipes the result to protect-system-files.sh.
|
||||
# =============================================================================
|
||||
set -eo pipefail
|
||||
|
||||
INPUT=$(cat)
|
||||
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Translate CC native fields to the neutral schema
|
||||
NEUTRAL=$(echo "$INPUT" | jq -c '{
|
||||
event: "before-tool-use",
|
||||
tool: (.tool_name // ""),
|
||||
args: (.tool_input // {title: .title, message: .message}),
|
||||
session_id: (.session_id // ""),
|
||||
cwd: (.cwd // ""),
|
||||
framework: "claude-code"
|
||||
}')
|
||||
|
||||
echo "$NEUTRAL" | bash "$HOOK_DIR/protect-system-files.sh"
|
||||
@@ -12,7 +12,7 @@
|
||||
# =============================================================================
|
||||
|
||||
INPUT=$(cat)
|
||||
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.command // ""' 2>/dev/null)
|
||||
FILE=$(echo "$INPUT" | jq -r '.args.file_path // .args.command // ""' 2>/dev/null)
|
||||
|
||||
# If we can't extract a file path, allow the operation
|
||||
[[ -z "$FILE" ]] && exit 0
|
||||
|
||||
23
tests/regression/snapshot/.claude/hooks/validate-frontmatter-wrapper.sh
Executable file
23
tests/regression/snapshot/.claude/hooks/validate-frontmatter-wrapper.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# Generated by adapters/claude-code/adapter.sh — do not edit.
|
||||
# Wrapper for hook: validate-frontmatter
|
||||
# Reads Claude Code native PreToolUse/PostToolUse/Notification JSON from stdin,
|
||||
# transforms it into the neutral schema, and pipes the result to validate-frontmatter.sh.
|
||||
# =============================================================================
|
||||
set -eo pipefail
|
||||
|
||||
INPUT=$(cat)
|
||||
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Translate CC native fields to the neutral schema
|
||||
NEUTRAL=$(echo "$INPUT" | jq -c '{
|
||||
event: "after-tool-use",
|
||||
tool: (.tool_name // ""),
|
||||
args: (.tool_input // {title: .title, message: .message}),
|
||||
session_id: (.session_id // ""),
|
||||
cwd: (.cwd // ""),
|
||||
framework: "claude-code"
|
||||
}')
|
||||
|
||||
echo "$NEUTRAL" | bash "$HOOK_DIR/validate-frontmatter.sh"
|
||||
@@ -17,7 +17,7 @@
|
||||
# =============================================================================
|
||||
|
||||
INPUT=$(cat)
|
||||
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""' 2>/dev/null)
|
||||
FILE=$(echo "$INPUT" | jq -r '.args.file_path // ""' 2>/dev/null)
|
||||
|
||||
# Skip if we can't extract a path
|
||||
[[ -z "$FILE" ]] && exit 0
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/hooks/protect-system-files.sh"
|
||||
"command": "bash .claude/hooks/protect-system-files-wrapper.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/hooks/validate-frontmatter.sh"
|
||||
"command": "bash .claude/hooks/validate-frontmatter-wrapper.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/hooks/notify.sh"
|
||||
"command": "bash .claude/hooks/notify-wrapper.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user