@dtt_siye/atool 1.3.1 → 1.4.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/VERSION +1 -1
- package/hooks/doc-sync-reminder +4 -4
- package/hooks/hooks-cursor.json +20 -0
- package/hooks/hooks.json +21 -1
- package/hooks/pre-commit +191 -0
- package/hooks/prompt-guard +84 -35
- package/hooks/session-start +34 -12
- package/hooks/task-state-tracker +145 -0
- package/lib/common.sh +36 -23
- package/lib/compute-importance.sh +73 -0
- package/lib/install-cursor.sh +2 -2
- package/lib/install-hooks.sh +64 -0
- package/lib/install-skills.sh +5 -2
- package/lib/pre-scan.sh +11 -1
- package/package.json +1 -1
- package/skills/agent-audit/SKILL.md +180 -0
- package/skills/architecture-guard/SKILL.md +164 -0
- package/skills/architecture-guard/rules/violation-detection.md +90 -0
- package/skills/ci-feedback/SKILL.md +165 -0
- package/skills/project-analyze/SKILL.md +100 -11
- package/skills/project-analyze/phases/phase1-setup.md +15 -1
- package/skills/project-analyze/phases/phase2-understand.md +10 -1
- package/skills/project-analyze/phases/phase2.5-refine.md +32 -23
- package/skills/project-analyze/phases/phase3-graph.md +7 -1
- package/skills/project-analyze/phases/phase4-synthesize.md +17 -1
- package/skills/project-analyze/phases/phase5-export.md +42 -4
- package/skills/project-query/SKILL.md +681 -120
package/lib/common.sh
CHANGED
|
@@ -140,11 +140,9 @@ ensure_dir() {
|
|
|
140
140
|
# ── IDE Config Directory Helpers (cross-platform) ─────────────────────────────
|
|
141
141
|
|
|
142
142
|
get_claude_config_dir() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
echo "$HOME/.claude"
|
|
147
|
-
fi
|
|
143
|
+
# Claude Code CLI always uses ~/.claude/ on all platforms
|
|
144
|
+
# (APPDATA/claude is the Claude Desktop app, not the CLI)
|
|
145
|
+
echo "$HOME/.claude"
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
get_cursor_config_dir() {
|
|
@@ -861,15 +859,20 @@ scan_skills_catalog() {
|
|
|
861
859
|
;;
|
|
862
860
|
pdf|docx|pptx|xlsx)
|
|
863
861
|
office="${office}- ${skill_name}: ${desc}
|
|
862
|
+
"
|
|
863
|
+
;;
|
|
864
|
+
# Core initialization
|
|
865
|
+
atool-init)
|
|
866
|
+
planning="${planning}- ${skill_name}: ${desc}
|
|
864
867
|
"
|
|
865
868
|
;;
|
|
866
869
|
# Architecture & Design
|
|
867
|
-
software-architecture|ai-project-architecture|ui-ux-pro)
|
|
870
|
+
software-architecture|ai-project-architecture|ui-ux-pro|architecture-guard)
|
|
868
871
|
arch_design="${arch_design}- ${skill_name}: ${desc}
|
|
869
872
|
"
|
|
870
873
|
;;
|
|
871
874
|
# Quality & Review
|
|
872
|
-
code-review|project-analyze|project-query|verification-before-completion)
|
|
875
|
+
code-review|project-analyze|project-query|verification-before-completion|agent-audit)
|
|
873
876
|
quality_review="${quality_review}- ${skill_name}: ${desc}
|
|
874
877
|
"
|
|
875
878
|
;;
|
|
@@ -879,8 +882,13 @@ scan_skills_catalog() {
|
|
|
879
882
|
"
|
|
880
883
|
;;
|
|
881
884
|
# Planning & Dispatch
|
|
882
|
-
writing-plans|smart-dispatch|brainstorming|clarify-before-build)
|
|
885
|
+
writing-plans|smart-dispatch|brainstorming|clarify-before-build|using-git-worktrees|find-skills)
|
|
883
886
|
planning="${planning}- ${skill_name}: ${desc}
|
|
887
|
+
"
|
|
888
|
+
;;
|
|
889
|
+
# Testing & Automation
|
|
890
|
+
webapp-testing|ci-feedback)
|
|
891
|
+
quality_review="${quality_review}- ${skill_name}: ${desc}
|
|
884
892
|
"
|
|
885
893
|
;;
|
|
886
894
|
*)
|
|
@@ -890,26 +898,31 @@ scan_skills_catalog() {
|
|
|
890
898
|
esac
|
|
891
899
|
done
|
|
892
900
|
|
|
893
|
-
# Check for Superpowers skills
|
|
901
|
+
# Check for Superpowers skills (only if Superpowers directory exists and is separate from skills_dir)
|
|
894
902
|
local sp_dir="$skills_dir"
|
|
895
903
|
if [[ -d "$skills_dir/_superpowers/skills" ]]; then
|
|
896
904
|
sp_dir="$skills_dir/_superpowers/skills"
|
|
897
905
|
fi
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
906
|
+
|
|
907
|
+
# Only scan Superpowers directory if it exists and is NOT the same as skills_dir
|
|
908
|
+
# (prevents double-scanning skills already categorized in first loop)
|
|
909
|
+
if [[ "$sp_dir" != "$skills_dir" ]] && [[ -d "$sp_dir" ]]; then
|
|
910
|
+
for skill_dir in "$sp_dir"/*/; do
|
|
911
|
+
[[ ! -d "$skill_dir" ]] && continue
|
|
912
|
+
local skill_name
|
|
913
|
+
skill_name=$(basename "$skill_dir")
|
|
914
|
+
[[ -L "$skill_dir" ]] && continue
|
|
915
|
+
local sp_md="$skill_dir/SKILL.md"
|
|
916
|
+
[[ ! -f "$sp_md" ]] && continue
|
|
917
|
+
local desc=""
|
|
918
|
+
desc=$(head -10 "$sp_md" | sed -n '/^---$/,/^---$/p' | grep '^description:' | head -1 | sed 's/^description:[[:space:]]*//')
|
|
919
|
+
if [[ -z "$desc" ]]; then
|
|
920
|
+
desc=$(head -10 "$sp_md" | grep -i '^#' | head -1 | sed 's/^#*\s*//' || echo "$skill_name")
|
|
921
|
+
fi
|
|
922
|
+
superpowers_list="${superpowers_list}- ${skill_name}: ${desc}
|
|
911
923
|
"
|
|
912
|
-
|
|
924
|
+
done
|
|
925
|
+
fi
|
|
913
926
|
|
|
914
927
|
# Output catalog
|
|
915
928
|
if [[ -n "$conventions" ]]; then
|
|
@@ -591,6 +591,79 @@ compute_importance() {
|
|
|
591
591
|
rm -rf "$tmpdir"
|
|
592
592
|
}
|
|
593
593
|
|
|
594
|
+
# === Batch Processing (for pre-scan manifest.json) ===
|
|
595
|
+
|
|
596
|
+
# Update manifest.json modules array with importance scores
|
|
597
|
+
# Args: MANIFEST_PATH - path to manifest.json
|
|
598
|
+
# PROJECT_ROOT - project root directory (parent of .atool-docs)
|
|
599
|
+
# Updates: manifest.json modules[].importance field in-place
|
|
600
|
+
compute_importance_batch() {
|
|
601
|
+
local manifest_path="${1:-.atool-docs/pre-scan/manifest.json}"
|
|
602
|
+
local project_root="${2:-.}"
|
|
603
|
+
|
|
604
|
+
if [[ ! -f "$manifest_path" ]]; then
|
|
605
|
+
log_error "Manifest not found: $manifest_path"
|
|
606
|
+
return 1
|
|
607
|
+
fi
|
|
608
|
+
|
|
609
|
+
log_info "Computing importance scores for modules in manifest..."
|
|
610
|
+
|
|
611
|
+
# Get inventory directory from project_root
|
|
612
|
+
local inventory_dir="${project_root}/.atool-docs/inventory"
|
|
613
|
+
|
|
614
|
+
# Read modules from manifest
|
|
615
|
+
local modules_json
|
|
616
|
+
modules_json=$(jq -r '.modules[] | .slug' "$manifest_path" 2>/dev/null)
|
|
617
|
+
|
|
618
|
+
if [[ -z "$modules_json" ]]; then
|
|
619
|
+
log_warn "No modules found in manifest"
|
|
620
|
+
return 0
|
|
621
|
+
fi
|
|
622
|
+
|
|
623
|
+
# Build module path map: slug -> importance_score
|
|
624
|
+
local tmpdir
|
|
625
|
+
tmpdir=$(mktemp -d)
|
|
626
|
+
|
|
627
|
+
# Discover all modules in project and compute importance
|
|
628
|
+
local all_modules
|
|
629
|
+
all_modules=$(discover_modules "$project_root")
|
|
630
|
+
|
|
631
|
+
if [[ -z "$all_modules" ]]; then
|
|
632
|
+
log_warn "No source modules found in project"
|
|
633
|
+
echo "{}" > "$tmpdir/importance_map"
|
|
634
|
+
else
|
|
635
|
+
# Compute importance for all discovered modules
|
|
636
|
+
log_info "Computing importance factors for discovered modules..."
|
|
637
|
+
local importance_output
|
|
638
|
+
importance_output=$(compute_importance "$project_root" --inventory-dir "$inventory_dir" 2>/dev/null || true)
|
|
639
|
+
|
|
640
|
+
# Build slug-to-importance map from output (module_path<tab>score<tab>tier)
|
|
641
|
+
# Convert module path to slug: extract last path component
|
|
642
|
+
{
|
|
643
|
+
while IFS=$'\t' read -r module_path score tier; do
|
|
644
|
+
[[ -z "$module_path" ]] && continue
|
|
645
|
+
local slug
|
|
646
|
+
slug=$(basename "$module_path")
|
|
647
|
+
printf '%s\t%s\n' "$slug" "$score"
|
|
648
|
+
done <<< "$importance_output"
|
|
649
|
+
} > "$tmpdir/importance_map"
|
|
650
|
+
fi
|
|
651
|
+
|
|
652
|
+
# Update manifest.json with importance scores
|
|
653
|
+
log_info "Updating manifest with importance scores..."
|
|
654
|
+
jq --slurpfile importance_data <(cat "$tmpdir/importance_map" | jq -R 'split("\t") | {key: .[0], value: (.[1] | tonumber)}' | jq -s 'from_entries') \
|
|
655
|
+
'.modules |= map(.importance = ($importance_data[0][.slug] // 0))' \
|
|
656
|
+
"$manifest_path" > "$tmpdir/manifest_updated.json"
|
|
657
|
+
|
|
658
|
+
# Atomically replace manifest
|
|
659
|
+
mv "$tmpdir/manifest_updated.json" "$manifest_path"
|
|
660
|
+
|
|
661
|
+
# Cleanup
|
|
662
|
+
rm -rf "$tmpdir"
|
|
663
|
+
|
|
664
|
+
log_success "Importance scores computed and manifest updated"
|
|
665
|
+
}
|
|
666
|
+
|
|
594
667
|
# === Standalone Execution ===
|
|
595
668
|
# When run directly (not sourced), execute compute_importance with CLI args
|
|
596
669
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
package/lib/install-cursor.sh
CHANGED
|
@@ -79,8 +79,8 @@ should_always_apply() {
|
|
|
79
79
|
project-analyze) return 0 ;;
|
|
80
80
|
# Workflow skill with no good glob match - must be always-on
|
|
81
81
|
using-git-worktrees) return 0 ;;
|
|
82
|
-
# Conventions skills -
|
|
83
|
-
*-conventions) return
|
|
82
|
+
# Conventions skills - globs handle triggering by file type (no need for alwaysApply)
|
|
83
|
+
*-conventions) return 1 ;;
|
|
84
84
|
# All other skills: use globs or on-demand (reduces context token consumption)
|
|
85
85
|
*) return 1 ;;
|
|
86
86
|
esac
|
package/lib/install-hooks.sh
CHANGED
|
@@ -132,6 +132,58 @@ install_hooks() {
|
|
|
132
132
|
fi
|
|
133
133
|
fi
|
|
134
134
|
|
|
135
|
+
# Install pre-commit hook (PreToolUse - checks before git commit)
|
|
136
|
+
local pre_commit_src="$atool_root/hooks/pre-commit"
|
|
137
|
+
if [[ -f "$pre_commit_src" ]]; then
|
|
138
|
+
local pre_commit_name="atool-pre-commit"
|
|
139
|
+
local dest_pre_commit="$hooks_dir/$pre_commit_name"
|
|
140
|
+
|
|
141
|
+
if [[ -f "$dest_pre_commit" ]] && [[ "${ATOOL_FORCE:-0}" != "1" ]]; then
|
|
142
|
+
local pc_existing pc_source
|
|
143
|
+
pc_existing=$(file_checksum "$dest_pre_commit")
|
|
144
|
+
pc_source=$(file_checksum "$pre_commit_src")
|
|
145
|
+
if [[ "$pc_existing" == "$pc_source" ]]; then
|
|
146
|
+
log_info "Hook '$pre_commit_name' already up to date, skipping"
|
|
147
|
+
else
|
|
148
|
+
log_info "Hook '$pre_commit_name' exists but differs - backing up"
|
|
149
|
+
backup_file "$dest_pre_commit"
|
|
150
|
+
run_cmd cp "$pre_commit_src" "$dest_pre_commit"
|
|
151
|
+
run_cmd chmod +x "$dest_pre_commit"
|
|
152
|
+
log_success "Hook installed: $dest_pre_commit"
|
|
153
|
+
fi
|
|
154
|
+
else
|
|
155
|
+
run_cmd cp "$pre_commit_src" "$dest_pre_commit"
|
|
156
|
+
run_cmd chmod +x "$dest_pre_commit"
|
|
157
|
+
log_success "Hook installed: $dest_pre_commit"
|
|
158
|
+
fi
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# Install task-state-tracker hook (PostToolUse - tracks session state)
|
|
162
|
+
local task_state_src="$atool_root/hooks/task-state-tracker"
|
|
163
|
+
if [[ -f "$task_state_src" ]]; then
|
|
164
|
+
local task_state_name="atool-task-state-tracker"
|
|
165
|
+
local dest_task_state="$hooks_dir/$task_state_name"
|
|
166
|
+
|
|
167
|
+
if [[ -f "$dest_task_state" ]] && [[ "${ATOOL_FORCE:-0}" != "1" ]]; then
|
|
168
|
+
local ts_existing ts_source
|
|
169
|
+
ts_existing=$(file_checksum "$dest_task_state")
|
|
170
|
+
ts_source=$(file_checksum "$task_state_src")
|
|
171
|
+
if [[ "$ts_existing" == "$ts_source" ]]; then
|
|
172
|
+
log_info "Hook '$task_state_name' already up to date, skipping"
|
|
173
|
+
else
|
|
174
|
+
log_info "Hook '$task_state_name' exists but differs - backing up"
|
|
175
|
+
backup_file "$dest_task_state"
|
|
176
|
+
run_cmd cp "$task_state_src" "$dest_task_state"
|
|
177
|
+
run_cmd chmod +x "$dest_task_state"
|
|
178
|
+
log_success "Hook installed: $dest_task_state"
|
|
179
|
+
fi
|
|
180
|
+
else
|
|
181
|
+
run_cmd cp "$task_state_src" "$dest_task_state"
|
|
182
|
+
run_cmd chmod +x "$dest_task_state"
|
|
183
|
+
log_success "Hook installed: $dest_task_state"
|
|
184
|
+
fi
|
|
185
|
+
fi
|
|
186
|
+
|
|
135
187
|
# Install hooks config JSON
|
|
136
188
|
local config_file
|
|
137
189
|
case "$ide_type" in
|
|
@@ -224,6 +276,18 @@ install_hooks_global() {
|
|
|
224
276
|
run_cmd chmod +x "$claude_hooks_dir/atool-doc-sync-reminder"
|
|
225
277
|
fi
|
|
226
278
|
|
|
279
|
+
# Copy pre-commit hook (PreToolUse)
|
|
280
|
+
if [[ -f "$atool_root/hooks/pre-commit" ]]; then
|
|
281
|
+
run_cmd cp "$atool_root/hooks/pre-commit" "$claude_hooks_dir/atool-pre-commit"
|
|
282
|
+
run_cmd chmod +x "$claude_hooks_dir/atool-pre-commit"
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
# Copy task-state-tracker hook (PostToolUse)
|
|
286
|
+
if [[ -f "$atool_root/hooks/task-state-tracker" ]]; then
|
|
287
|
+
run_cmd cp "$atool_root/hooks/task-state-tracker" "$claude_hooks_dir/atool-task-state-tracker"
|
|
288
|
+
run_cmd chmod +x "$claude_hooks_dir/atool-task-state-tracker"
|
|
289
|
+
fi
|
|
290
|
+
|
|
227
291
|
# 2. Register hooks config in settings.json
|
|
228
292
|
# Claude Code reads hooks from settings.json, NOT from files on disk
|
|
229
293
|
local settings_file="$claude_config_dir/settings.json"
|
package/lib/install-skills.sh
CHANGED
|
@@ -122,8 +122,11 @@ install_skills() {
|
|
|
122
122
|
# Skills reference scripts via "source lib/X.sh" relative to the skill dir
|
|
123
123
|
local skill_lib_dir="$target_skill/lib"
|
|
124
124
|
local referenced_libs
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
local _find_paths=()
|
|
126
|
+
[[ -d "$target_skill/phases" ]] && _find_paths+=("$target_skill/phases")
|
|
127
|
+
_find_paths+=("$target_skill")
|
|
128
|
+
referenced_libs=$(find "${_find_paths[@]}" -maxdepth 2 -name '*.md' -exec grep -roh 'source lib/[^ ]*\.sh' {} + 2>/dev/null \
|
|
129
|
+
| sed 's/source lib\///' | sort -u || true)
|
|
127
130
|
if [[ -n "$referenced_libs" ]]; then
|
|
128
131
|
run_cmd mkdir -p "$skill_lib_dir"
|
|
129
132
|
for lib_name in $referenced_libs; do
|
package/lib/pre-scan.sh
CHANGED
|
@@ -1098,7 +1098,17 @@ pre_scan_project() {
|
|
|
1098
1098
|
generated_at: (now | todate),
|
|
1099
1099
|
total_modules: length,
|
|
1100
1100
|
scan_duration_seconds: null,
|
|
1101
|
-
modules: [.[]
|
|
1101
|
+
modules: [.[] | {
|
|
1102
|
+
slug: .module,
|
|
1103
|
+
name: .module,
|
|
1104
|
+
importance: 0
|
|
1105
|
+
} + (.module_summary // {} | {
|
|
1106
|
+
total_files,
|
|
1107
|
+
total_classes,
|
|
1108
|
+
total_functions,
|
|
1109
|
+
total_api_endpoints,
|
|
1110
|
+
total_data_models
|
|
1111
|
+
})]
|
|
1102
1112
|
}' "$output_dir"/*.json 2>/dev/null || echo '{}')
|
|
1103
1113
|
|
|
1104
1114
|
# Add duration to manifest
|
package/package.json
CHANGED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-audit
|
|
3
|
+
description: "Use when multiple agents or parallel tasks are running — tracks each agent's modifications, detects file conflicts, and provides audit trail. 在多Agent并行工作时使用 — 追踪每个Agent的修改、检测文件冲突、提供审计记录."
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
category: quality
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Agent Audit — Multi-Agent Modification Tracking
|
|
9
|
+
|
|
10
|
+
Tracks file modifications across multiple AI agents or parallel tasks, detects conflicts, and provides a complete audit trail for coordination.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- When using `/smart-dispatch` for parallel agent execution
|
|
15
|
+
- When using `/dispatching-parallel-agents` for independent tasks
|
|
16
|
+
- When using `/subagent-driven-development` for implementation plans
|
|
17
|
+
- After parallel agents complete, before merging results
|
|
18
|
+
- When reviewing what changes each agent made
|
|
19
|
+
|
|
20
|
+
## How It Works
|
|
21
|
+
|
|
22
|
+
### Audit Log Format
|
|
23
|
+
|
|
24
|
+
Each agent's modifications are recorded in `.claude/agent-audit.json`:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"audit_entries": [
|
|
29
|
+
{
|
|
30
|
+
"agent_id": "agent-1",
|
|
31
|
+
"task": "Implement user authentication",
|
|
32
|
+
"started_at": 1712649600,
|
|
33
|
+
"completed_at": 1712649900,
|
|
34
|
+
"files_modified": [
|
|
35
|
+
{
|
|
36
|
+
"path": "src/auth/UserService.java",
|
|
37
|
+
"action": "modified",
|
|
38
|
+
"lines_added": 45,
|
|
39
|
+
"lines_removed": 12,
|
|
40
|
+
"intent": "Add JWT token generation"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"files_planned": ["src/auth/UserService.java", "src/auth/AuthController.java"],
|
|
44
|
+
"files_unexpected": [],
|
|
45
|
+
"impact_scope": ["auth", "api"],
|
|
46
|
+
"status": "completed"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"conflicts": [],
|
|
50
|
+
"summary": {
|
|
51
|
+
"total_agents": 3,
|
|
52
|
+
"total_files_modified": 8,
|
|
53
|
+
"conflicts_detected": 0
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Step 1: Agent Registration
|
|
59
|
+
|
|
60
|
+
Before dispatching an agent, register it:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Read: agent-audit.json (or create if not exists)
|
|
64
|
+
Add entry:
|
|
65
|
+
{
|
|
66
|
+
"agent_id": "{agent-N}",
|
|
67
|
+
"task": "{task description}",
|
|
68
|
+
"files_planned": [{list of expected files}],
|
|
69
|
+
"started_at": {timestamp}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Step 2: Modification Tracking
|
|
74
|
+
|
|
75
|
+
Each agent should record its modifications. Use git diff or task-state data:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
After agent completes:
|
|
79
|
+
git diff --stat HEAD → extract file list and line changes
|
|
80
|
+
Compare with files_planned → flag unexpected files
|
|
81
|
+
Cross-reference with knowledge-graph → compute impact_scope
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Step 3: Conflict Detection
|
|
85
|
+
|
|
86
|
+
After all agents complete, detect file-level conflicts:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
For each pair of agents (A, B):
|
|
90
|
+
overlap = A.files_modified ∩ B.files_modified
|
|
91
|
+
if overlap is not empty:
|
|
92
|
+
CONFLICT: agents A and B both modified: {overlap}
|
|
93
|
+
severity = check if changes are in same lines (git merge-base)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Conflict severity levels:
|
|
97
|
+
- **Critical**: Same file, same lines → merge conflict likely
|
|
98
|
+
- **Warning**: Same file, different sections → manual review needed
|
|
99
|
+
- **Info**: Different files, same module → review for logical consistency
|
|
100
|
+
|
|
101
|
+
### Step 4: Impact Analysis
|
|
102
|
+
|
|
103
|
+
Using knowledge-graph.json (from project-analyze):
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
For each agent's modified files:
|
|
107
|
+
1. Find the module each file belongs to
|
|
108
|
+
2. Find upstream dependents (who depends on this module)
|
|
109
|
+
3. Find downstream dependencies (what this module depends on)
|
|
110
|
+
4. Compute impact scope = module + direct dependents
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Step 5: Consolidated Audit Report
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
## Agent Audit Report
|
|
117
|
+
|
|
118
|
+
### Execution Summary
|
|
119
|
+
| Agent | Task | Files | Status | Duration |
|
|
120
|
+
|-------|------|-------|--------|----------|
|
|
121
|
+
| agent-1 | User auth | 3 | completed | 5m |
|
|
122
|
+
| agent-2 | Payment API | 4 | completed | 7m |
|
|
123
|
+
| agent-3 | Tests | 5 | completed | 4m |
|
|
124
|
+
|
|
125
|
+
### File Overlap
|
|
126
|
+
| File | Agent-1 | Agent-2 | Agent-3 |
|
|
127
|
+
|------|---------|---------|---------|
|
|
128
|
+
| src/common/Utils.java | modified | - | modified |
|
|
129
|
+
|
|
130
|
+
### Conflicts
|
|
131
|
+
| Severity | File | Details |
|
|
132
|
+
|----------|------|---------|
|
|
133
|
+
| Warning | src/common/Utils.java | Both agent-1 and agent-3 modified this file |
|
|
134
|
+
|
|
135
|
+
### Impact Scope
|
|
136
|
+
| Agent | Modules Affected | Downstream Impact |
|
|
137
|
+
|-------|-----------------|-------------------|
|
|
138
|
+
| agent-1 | auth, api | gateway, frontend |
|
|
139
|
+
| agent-2 | payment, billing | notification, reporting |
|
|
140
|
+
|
|
141
|
+
### Recommendations
|
|
142
|
+
1. Review src/common/Utils.java for merge conflicts before integrating
|
|
143
|
+
2. Run integration tests after merging all agent changes
|
|
144
|
+
3. Update documentation for auth and payment modules
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Integration with task-state
|
|
148
|
+
|
|
149
|
+
The agent-audit reads from and writes to `.claude/task-state.json`:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"active_agents": 3,
|
|
154
|
+
"completed_agents": 2,
|
|
155
|
+
"agent_conflicts": ["src/common/Utils.java"],
|
|
156
|
+
"pending_actions": ["resolve_conflict:Utils.java", "run_integration_tests", "update_docs"]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Smart-Dispatch Integration
|
|
161
|
+
|
|
162
|
+
When using `/smart-dispatch`:
|
|
163
|
+
|
|
164
|
+
1. **Before dispatch**: Register each chunk as an agent entry
|
|
165
|
+
2. **During execution**: Each agent records its modifications
|
|
166
|
+
3. **After all complete**: Run conflict detection
|
|
167
|
+
4. **Review phase**: Present consolidated audit report
|
|
168
|
+
5. **Integration**: User resolves conflicts, then merge
|
|
169
|
+
|
|
170
|
+
## Skill 协作
|
|
171
|
+
|
|
172
|
+
| 协作 Skill | 触发条件 | 交互方式 |
|
|
173
|
+
|-----------|---------|---------|
|
|
174
|
+
| smart-dispatch | Parallel execution | 每个chunk注册为agent,完成后审计 |
|
|
175
|
+
| dispatching-parallel-agents | Independent tasks | 跟踪每个后台agent的修改 |
|
|
176
|
+
| subagent-driven-development | Implementation plans | 追踪sub-agent修改范围 |
|
|
177
|
+
| project-analyze | Knowledge-graph available | 使用图谱计算impact scope |
|
|
178
|
+
| architecture-guard | Conflicts detected | 检查冲突是否违反架构约束 |
|
|
179
|
+
| verification-before-completion | After agent merge | 合并后验证整体完整性 |
|
|
180
|
+
| ci-feedback | After merge | 运行集成测试验证 |
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architecture-guard
|
|
3
|
+
description: "Use when reviewing or modifying code in analyzed projects — detects architectural violations in real-time using knowledge-graph data. 在修改代码时使用 — 实时检测架构违规(分层违反/依赖方向/循环依赖/边界泄漏)."
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
category: quality
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Architecture Guard
|
|
9
|
+
|
|
10
|
+
Real-time architectural violation detection using knowledge-graph data. Prevents AI and developers from degrading system structure.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- After modifying source files in a previously analyzed project (has `atool-analysis/` or `.atool-docs/`)
|
|
15
|
+
- Before committing changes to verify architectural compliance
|
|
16
|
+
- When reviewing code changes for structural correctness
|
|
17
|
+
- Auto-triggered by verification-before-completion for analyzed projects
|
|
18
|
+
|
|
19
|
+
## How It Works
|
|
20
|
+
|
|
21
|
+
Architecture-guard reads the knowledge-graph.json produced by `/project-analyze` and checks:
|
|
22
|
+
|
|
23
|
+
1. **Dependency Direction** — Enforces layer ordering (e.g., Controller → Service → DAO). Reverse dependencies are violations.
|
|
24
|
+
2. **Package Structure** — New files must belong to recognized package paths.
|
|
25
|
+
3. **API Boundary Leaks** — Response/DTO types should not appear in Service/DAO layers.
|
|
26
|
+
4. **Circular Dependencies** — New imports must not introduce cycles.
|
|
27
|
+
|
|
28
|
+
## Guard Process
|
|
29
|
+
|
|
30
|
+
### Step 1: Load Architecture Data
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Read: atool-analysis/knowledge-graph.json (or .atool-docs/knowledge-graph.json)
|
|
34
|
+
Extract:
|
|
35
|
+
- architectural_layers: {layer_name: [module_names]}
|
|
36
|
+
- edges: [{source, target, edge_type}]
|
|
37
|
+
- nodes: [{id, type, layer}]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If no knowledge-graph.json exists, warn the user and suggest running `/project-analyze` first.
|
|
41
|
+
|
|
42
|
+
### Step 2: Detect Violations in Changed Files
|
|
43
|
+
|
|
44
|
+
For each modified source file, check:
|
|
45
|
+
|
|
46
|
+
#### 2a. Dependency Direction Check
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
For each import/dependency in the modified file:
|
|
50
|
+
source_layer = lookup layer of the modified file's module
|
|
51
|
+
target_layer = lookup layer of the imported module
|
|
52
|
+
if source_layer is lower than target_layer in the layer ordering:
|
|
53
|
+
VIOLATION: "Reverse dependency: {source} ({source_layer}) imports {target} ({target_layer})"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Common layer ordering (adjustable per project):
|
|
57
|
+
- **Java/Spring**: Controller → Service → Repository → Entity
|
|
58
|
+
- **Web/React**: Page → Component → Hook → Service → API
|
|
59
|
+
- **Go**: Handler → Service → Repository → Model
|
|
60
|
+
- **Python**: Route → Service → Repository → Model
|
|
61
|
+
|
|
62
|
+
#### 2b. API Boundary Leak Check
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
For each import in the modified file:
|
|
66
|
+
if the file is in Service/Repository layer:
|
|
67
|
+
check if imported type is a Response/DTO/ViewModel (belongs to API/Presentation layer)
|
|
68
|
+
if yes: VIOLATION: "API type {type} leaked into {layer} layer"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### 2c. Circular Dependency Check
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Build dependency graph from knowledge-graph edges + new imports
|
|
75
|
+
Run cycle detection (DFS)
|
|
76
|
+
if cycle found: VIOLATION: "Circular dependency: {cycle_path}"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### 2d. Module Boundary Check
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
For each new file or moved file:
|
|
83
|
+
Check if it belongs to a recognized module boundary
|
|
84
|
+
if it crosses module boundaries (imports from unrelated modules):
|
|
85
|
+
WARNING: "Cross-module import: {source_module} → {target_module}"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Step 3: Report Results
|
|
89
|
+
|
|
90
|
+
Output a structured violation report:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
## Architecture Guard Report
|
|
94
|
+
|
|
95
|
+
### Summary
|
|
96
|
+
- Files checked: {n}
|
|
97
|
+
- Violations: {n} (Critical: {n}, Warning: {n})
|
|
98
|
+
- Status: PASS / FAIL
|
|
99
|
+
|
|
100
|
+
### Violations
|
|
101
|
+
|
|
102
|
+
| Severity | Type | File | Details |
|
|
103
|
+
|----------|------|------|---------|
|
|
104
|
+
| Critical | Reverse Dependency | UserService.java | Imports UserController (Controller→Service violation) |
|
|
105
|
+
| Critical | Circular Dependency | OrderService.java | Cycle: OrderService → UserService → OrderService |
|
|
106
|
+
| Warning | API Boundary Leak | PaymentService.java | Uses OrderResponse (DTO in Service layer) |
|
|
107
|
+
| Warning | Cross-Module | notification.go | Imports billing/invoice.go (unrelated domain) |
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Step 4: Suggest Fixes
|
|
111
|
+
|
|
112
|
+
For each violation, provide:
|
|
113
|
+
1. The specific line/import causing the issue
|
|
114
|
+
2. Why it violates the architecture
|
|
115
|
+
3. Suggested fix (e.g., "Move logic to OrderService", "Use OrderEntity instead of OrderResponse")
|
|
116
|
+
|
|
117
|
+
## Integration Points
|
|
118
|
+
|
|
119
|
+
### With verification-before-completion
|
|
120
|
+
When the project has been analyzed, verification-before-completion should invoke architecture-guard as an additional check before claiming complete.
|
|
121
|
+
|
|
122
|
+
### With code-review
|
|
123
|
+
Architecture violations detected here feed into the `architecture` dimension of `/code-review` with specific line-level details.
|
|
124
|
+
|
|
125
|
+
### With project-analyze
|
|
126
|
+
Reads the knowledge-graph.json output from `/project-analyze`. If the graph is stale (older than source files), suggest re-running analysis.
|
|
127
|
+
|
|
128
|
+
## Layer Definition Patterns
|
|
129
|
+
|
|
130
|
+
The guard auto-detects layer patterns from the knowledge-graph:
|
|
131
|
+
|
|
132
|
+
| Pattern | Layers |
|
|
133
|
+
|---------|--------|
|
|
134
|
+
| **Spring Boot** | controller → service → repository → entity |
|
|
135
|
+
| **Clean Architecture** | presentation → application → domain → infrastructure |
|
|
136
|
+
| **Hexagonal** | adapter/in → port/in → application → port/out → adapter/out |
|
|
137
|
+
| **Generic Web** | page → component → service → data |
|
|
138
|
+
| **DDD** | ui → application → domain → infrastructure |
|
|
139
|
+
|
|
140
|
+
If no layers are detected, fall back to directory-based heuristics:
|
|
141
|
+
- `controller/` / `handler/` / `api/` → Presentation
|
|
142
|
+
- `service/` / `usecase/` / `application/` → Application
|
|
143
|
+
- `repository/` / `dao/` / `store/` / `data/` → Data
|
|
144
|
+
- `model/` / `entity/` / `domain/` → Domain
|
|
145
|
+
|
|
146
|
+
## Severity Classification
|
|
147
|
+
|
|
148
|
+
| Type | Severity | Auto-fixable |
|
|
149
|
+
|------|----------|-------------|
|
|
150
|
+
| Reverse dependency | Critical | Sometimes (move import) |
|
|
151
|
+
| Circular dependency | Critical | Often (extract interface) |
|
|
152
|
+
| API boundary leak | Warning | Yes (use internal type) |
|
|
153
|
+
| Cross-module import | Warning | Context-dependent |
|
|
154
|
+
| New unknown module | Info | No (may need new layer) |
|
|
155
|
+
|
|
156
|
+
## Skill 协作
|
|
157
|
+
|
|
158
|
+
| 协作 Skill | 触发条件 | 交互方式 |
|
|
159
|
+
|-----------|---------|---------|
|
|
160
|
+
| project-analyze | No knowledge-graph.json found | 建议运行 `/project-analyze` 生成图谱 |
|
|
161
|
+
| code-review | Architecture dimension scoring | 提供层违反数据给 code-review |
|
|
162
|
+
| verification-before-completion | Analyzed project, before claiming done | 作为额外检查步骤 |
|
|
163
|
+
| {stack}-conventions | Stack-specific layer patterns | 加载栈级分层规范 |
|
|
164
|
+
| software-architecture | Architecture score < 60 | 建议运行架构重构 |
|