@haaaiawd/anws 2.2.6 → 2.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.
Files changed (94) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +52 -22
  3. package/lib/diff.js +5 -2
  4. package/lib/init.js +217 -96
  5. package/lib/install-state.js +18 -3
  6. package/lib/manifest.js +510 -213
  7. package/lib/prompt.js +68 -0
  8. package/lib/resources/index.js +36 -2
  9. package/lib/update.js +12 -6
  10. package/package.json +48 -47
  11. package/templates/.agents/skills/anws-system/SKILL.md +108 -108
  12. package/templates/.agents/skills/code-reviewer/SKILL.md +170 -103
  13. package/templates/.agents/skills/concept-modeler/SKILL.md +230 -179
  14. package/templates/.agents/skills/craft-authoring/SKILL.md +112 -49
  15. package/templates/.agents/skills/craft-authoring/references/BUNDLE_POLICY.md +61 -0
  16. package/templates/.agents/skills/craft-authoring/references/PROMPT_QUALITY_RUBRIC.md +99 -0
  17. package/templates/.agents/skills/craft-authoring/references/SCORECARD_TEMPLATE.md +64 -0
  18. package/templates/.agents/skills/design-reviewer/SKILL.md +265 -190
  19. package/templates/.agents/skills/e2e-testing-guide/SKILL.md +246 -135
  20. package/templates/.agents/skills/nexus-mapper/SKILL.md +321 -321
  21. package/templates/.agents/skills/output-contract/SKILL.md +37 -0
  22. package/templates/.agents/skills/report-template/SKILL.md +92 -92
  23. package/templates/.agents/skills/sequential-thinking/SKILL.md +222 -225
  24. package/templates/.agents/skills/spec-writer/SKILL.md +75 -30
  25. package/templates/.agents/skills/system-architect/SKILL.md +538 -678
  26. package/templates/.agents/skills/system-designer/SKILL.md +601 -601
  27. package/templates/.agents/skills/task-planner/SKILL.md +1 -2
  28. package/templates/.agents/skills/task-reviewer/SKILL.md +428 -388
  29. package/templates/.agents/skills/tech-evaluator/SKILL.md +252 -144
  30. package/templates/.agents/workflows/blueprint.md +166 -43
  31. package/templates/.agents/workflows/challenge.md +331 -497
  32. package/templates/.agents/workflows/change.md +182 -339
  33. package/templates/.agents/workflows/craft.md +159 -236
  34. package/templates/.agents/workflows/design-system.md +202 -674
  35. package/templates/.agents/workflows/explore.md +187 -399
  36. package/templates/.agents/workflows/forge.md +650 -550
  37. package/templates/.agents/workflows/genesis.md +439 -351
  38. package/templates/.agents/workflows/probe.md +219 -241
  39. package/templates/.agents/workflows/quickstart.md +302 -123
  40. package/templates/.agents/workflows/upgrade.md +145 -182
  41. package/templates_en/.agents/skills/anws-system/SKILL.md +108 -0
  42. package/templates_en/.agents/skills/code-reviewer/SKILL.md +170 -0
  43. package/templates_en/.agents/skills/concept-modeler/SKILL.md +230 -0
  44. package/templates_en/.agents/skills/craft-authoring/SKILL.md +179 -0
  45. package/templates_en/.agents/skills/craft-authoring/references/BUNDLE_POLICY.md +60 -0
  46. package/templates_en/.agents/skills/craft-authoring/references/PROMPT_QUALITY_RUBRIC.md +92 -0
  47. package/templates_en/.agents/skills/craft-authoring/references/SCORECARD_TEMPLATE.md +52 -0
  48. package/templates_en/.agents/skills/design-reviewer/SKILL.md +265 -0
  49. package/templates_en/.agents/skills/e2e-testing-guide/SKILL.md +246 -0
  50. package/templates_en/.agents/skills/nexus-mapper/SKILL.md +306 -0
  51. package/templates_en/.agents/skills/nexus-mapper/references/language-customization.md +167 -0
  52. package/templates_en/.agents/skills/nexus-mapper/references/output-schema.md +311 -0
  53. package/templates_en/.agents/skills/nexus-mapper/references/probe-protocol.md +246 -0
  54. package/templates_en/.agents/skills/nexus-mapper/scripts/extract_ast.py +706 -0
  55. package/templates_en/.agents/skills/nexus-mapper/scripts/git_detective.py +194 -0
  56. package/templates_en/.agents/skills/nexus-mapper/scripts/languages.json +127 -0
  57. package/templates_en/.agents/skills/nexus-mapper/scripts/query_graph.py +556 -0
  58. package/templates_en/.agents/skills/nexus-mapper/scripts/requirements.txt +6 -0
  59. package/templates_en/.agents/skills/nexus-query/SKILL.md +114 -0
  60. package/templates_en/.agents/skills/nexus-query/scripts/extract_ast.py +706 -0
  61. package/templates_en/.agents/skills/nexus-query/scripts/git_detective.py +194 -0
  62. package/templates_en/.agents/skills/nexus-query/scripts/languages.json +127 -0
  63. package/templates_en/.agents/skills/nexus-query/scripts/query_graph.py +556 -0
  64. package/templates_en/.agents/skills/nexus-query/scripts/requirements.txt +6 -0
  65. package/templates_en/.agents/skills/output-contract/SKILL.md +37 -0
  66. package/templates_en/.agents/skills/report-template/SKILL.md +85 -0
  67. package/templates_en/.agents/skills/report-template/references/REPORT_TEMPLATE.md +100 -0
  68. package/templates_en/.agents/skills/runtime-inspector/SKILL.md +101 -0
  69. package/templates_en/.agents/skills/sequential-thinking/SKILL.md +214 -0
  70. package/templates_en/.agents/skills/spec-writer/SKILL.md +153 -0
  71. package/templates_en/.agents/skills/spec-writer/references/prd_template.md +177 -0
  72. package/templates_en/.agents/skills/system-architect/SKILL.md +538 -0
  73. package/templates_en/.agents/skills/system-architect/references/rfc_template.md +59 -0
  74. package/templates_en/.agents/skills/system-designer/SKILL.md +534 -0
  75. package/templates_en/.agents/skills/system-designer/references/system-design-detail-template.md +187 -0
  76. package/templates_en/.agents/skills/system-designer/references/system-design-template.md +605 -0
  77. package/templates_en/.agents/skills/task-planner/SKILL.md +251 -0
  78. package/templates_en/.agents/skills/task-planner/references/TASK_TEMPLATE_05A.md +109 -0
  79. package/templates_en/.agents/skills/task-planner/references/TASK_TEMPLATE_05B.md +176 -0
  80. package/templates_en/.agents/skills/task-reviewer/SKILL.md +428 -0
  81. package/templates_en/.agents/skills/tech-evaluator/SKILL.md +252 -0
  82. package/templates_en/.agents/skills/tech-evaluator/references/ADR_TEMPLATE.md +78 -0
  83. package/templates_en/.agents/workflows/blueprint.md +200 -0
  84. package/templates_en/.agents/workflows/challenge.md +331 -0
  85. package/templates_en/.agents/workflows/change.md +182 -0
  86. package/templates_en/.agents/workflows/craft.md +159 -0
  87. package/templates_en/.agents/workflows/design-system.md +202 -0
  88. package/templates_en/.agents/workflows/explore.md +187 -0
  89. package/templates_en/.agents/workflows/forge.md +651 -0
  90. package/templates_en/.agents/workflows/genesis.md +439 -0
  91. package/templates_en/.agents/workflows/probe.md +219 -0
  92. package/templates_en/.agents/workflows/quickstart.md +303 -0
  93. package/templates_en/.agents/workflows/upgrade.md +145 -0
  94. package/templates_en/AGENTS.md +149 -0
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ git_detective.py — Git history hotspot and logical file coupling analyzer
4
+
5
+ Purpose: Analyze Git repository change history to identify hotspot files and logical file coupling pairs
6
+ Usage: python git_detective.py <repo_path> [--days 90] [--top-n 20]
7
+
8
+ Methodology: Adam Tornhill "Your Code as a Crime Scene"
9
+ """
10
+
11
+ import sys
12
+ import json
13
+ import argparse
14
+ import subprocess
15
+ from pathlib import Path
16
+ from collections import Counter
17
+ from itertools import combinations
18
+
19
+
20
+ def run_git(repo_path: Path, args: list[str]) -> str:
21
+ """Run git command and return stdout. Raise RuntimeError on failure."""
22
+ cmd = ['git', '-C', str(repo_path)] + args
23
+ result = subprocess.run(
24
+ cmd,
25
+ capture_output=True,
26
+ text=True,
27
+ encoding='utf-8',
28
+ errors='replace',
29
+ )
30
+ if result.returncode != 0:
31
+ raise RuntimeError(
32
+ f"git command failed: {' '.join(cmd)}\n{result.stderr.strip()}"
33
+ )
34
+ return result.stdout
35
+
36
+
37
+ def get_commit_file_changes(repo_path: Path, days: int) -> list[list[str]]:
38
+ """
39
+ Return files changed in each commit within the analysis window.
40
+
41
+ Output format: [[file1, file2], [file3], ...]
42
+ Use COMMIT:<hash> prefix format for stable parsing.
43
+ """
44
+ output = run_git(repo_path, [
45
+ 'log',
46
+ f'--since={days} days ago',
47
+ '--pretty=format:COMMIT:%H',
48
+ '--name-only',
49
+ ])
50
+
51
+ commits: list[list[str]] = []
52
+ current_files: list[str] = []
53
+
54
+ for line in output.splitlines():
55
+ line = line.strip()
56
+ if not line:
57
+ continue
58
+ if line.startswith('COMMIT:'):
59
+ if current_files:
60
+ commits.append(current_files)
61
+ current_files = []
62
+ else:
63
+ current_files.append(line)
64
+
65
+ if current_files:
66
+ commits.append(current_files)
67
+
68
+ return commits
69
+
70
+
71
+ def compute_hotspots(commits: list[list[str]], top_n: int) -> list[dict]:
72
+ """
73
+ Compute file change frequency hotspots, sorted by changes descending.
74
+
75
+ Risk thresholds (Adam Tornhill methodology):
76
+ low: changes < 5
77
+ medium: 5 <= changes < 15
78
+ high: changes >= 15
79
+ """
80
+ counter: Counter[str] = Counter()
81
+ for files in commits:
82
+ counter.update(files)
83
+
84
+ results = []
85
+ for path, changes in counter.most_common(top_n):
86
+ if changes < 5:
87
+ risk = 'low'
88
+ elif changes < 15:
89
+ risk = 'medium'
90
+ else:
91
+ risk = 'high'
92
+ results.append({'path': path, 'changes': changes, 'risk': risk})
93
+
94
+ return results
95
+
96
+
97
+ def compute_coupling_pairs(commits: list[list[str]], top_n: int) -> list[dict]:
98
+ """
99
+ Compute logical file coupling pairs: files changed together in one commit.
100
+
101
+ coupling_score = co_changes / min(total_changes_A, total_changes_B)
102
+ Filter: pairs with co_changes < 2 are not output (too noisy).
103
+ """
104
+ pair_counter: Counter[tuple[str, str]] = Counter()
105
+ file_counter: Counter[str] = Counter()
106
+
107
+ for files in commits:
108
+ unique_files = list(dict.fromkeys(files)) # De-duplicate while preserving order
109
+ file_counter.update(unique_files)
110
+ if len(unique_files) >= 2:
111
+ for a, b in combinations(sorted(unique_files), 2):
112
+ pair_counter[(a, b)] += 1
113
+
114
+ results = []
115
+ for (file_a, file_b), co_changes in pair_counter.most_common():
116
+ if co_changes < 2:
117
+ continue
118
+ min_changes = min(file_counter[file_a], file_counter[file_b])
119
+ score = round(co_changes / min_changes, 3) if min_changes > 0 else 0.0
120
+ results.append({
121
+ 'file_a': file_a,
122
+ 'file_b': file_b,
123
+ 'co_changes': co_changes,
124
+ 'coupling_score': score,
125
+ })
126
+ if len(results) >= top_n:
127
+ break
128
+
129
+ return results
130
+
131
+
132
+ def get_repo_stats(repo_path: Path, days: int) -> dict:
133
+ """Get commit and author counts within the analysis window."""
134
+ try:
135
+ commit_out = run_git(repo_path, [
136
+ 'log', f'--since={days} days ago', '--pretty=format:%H',
137
+ ])
138
+ total_commits = sum(1 for line in commit_out.splitlines() if line.strip())
139
+
140
+ author_out = run_git(repo_path, [
141
+ 'log', f'--since={days} days ago', '--pretty=format:%ae',
142
+ ])
143
+ total_authors = len({line.strip() for line in author_out.splitlines() if line.strip()})
144
+ except RuntimeError:
145
+ total_commits = 0
146
+ total_authors = 0
147
+
148
+ return {'total_commits': total_commits, 'total_authors': total_authors}
149
+
150
+
151
+ def main() -> None:
152
+ parser = argparse.ArgumentParser(
153
+ description='Analyze Git history for hotspots and coupling'
154
+ )
155
+ parser.add_argument('repo_path', help='Target repository path')
156
+ parser.add_argument('--days', type=int, default=90,
157
+ help='Analysis window in days (default: 90)')
158
+ parser.add_argument('--top-n', type=int, default=20,
159
+ help='Max items in hotspots/coupling output (default: 20)')
160
+ args = parser.parse_args()
161
+
162
+ repo_path = Path(args.repo_path).resolve()
163
+ if not repo_path.exists():
164
+ sys.stderr.write(f"[ERROR] repo_path not found: {repo_path}\n")
165
+ sys.exit(1)
166
+ if not (repo_path / '.git').exists():
167
+ sys.stderr.write(
168
+ f"[ERROR] .git not found in {repo_path}. "
169
+ "This tool requires a git repository.\n"
170
+ )
171
+ sys.exit(1)
172
+
173
+ try:
174
+ commits = get_commit_file_changes(repo_path, args.days)
175
+ except RuntimeError as e:
176
+ sys.stderr.write(f"[ERROR] Git command failed: {e}\n")
177
+ sys.exit(1)
178
+
179
+ stats = get_repo_stats(repo_path, args.days)
180
+ hotspots = compute_hotspots(commits, args.top_n)
181
+ coupling_pairs = compute_coupling_pairs(commits, args.top_n)
182
+
183
+ result = {
184
+ 'analysis_period_days': args.days,
185
+ 'stats': stats,
186
+ 'hotspots': hotspots,
187
+ 'coupling_pairs': coupling_pairs,
188
+ }
189
+
190
+ print(json.dumps(result, ensure_ascii=False, indent=2))
191
+
192
+
193
+ if __name__ == '__main__':
194
+ main()
@@ -0,0 +1,127 @@
1
+ {
2
+ "extensions": {
3
+ ".py": "python",
4
+ ".pyw": "python",
5
+ ".pyi": "python",
6
+ ".js": "javascript",
7
+ ".mjs": "javascript",
8
+ ".cjs": "javascript",
9
+ ".jsx": "javascript",
10
+ ".ts": "typescript",
11
+ ".mts": "typescript",
12
+ ".tsx": "tsx",
13
+ ".sh": "bash",
14
+ ".bash": "bash",
15
+ ".zsh": "bash",
16
+ ".java": "java",
17
+ ".go": "go",
18
+ ".rs": "rust",
19
+ ".cs": "csharp",
20
+ ".c": "c",
21
+ ".h": "c",
22
+ ".cpp": "cpp",
23
+ ".cc": "cpp",
24
+ ".cxx": "cpp",
25
+ ".hpp": "cpp",
26
+ ".hxx": "cpp",
27
+ ".kt": "kotlin",
28
+ ".kts": "kotlin",
29
+ ".rb": "ruby",
30
+ ".php": "php",
31
+ ".lua": "lua",
32
+ ".swift": "swift",
33
+ ".scala": "scala",
34
+ ".sc": "scala",
35
+ ".ex": "elixir",
36
+ ".exs": "elixir",
37
+ ".gd": "gdscript",
38
+ ".dart": "dart",
39
+ ".hs": "haskell",
40
+ ".clj": "clojure",
41
+ ".cljs": "clojure",
42
+ ".cljc": "clojure",
43
+ ".sql": "sql",
44
+ ".proto": "proto",
45
+ ".sol": "solidity",
46
+ ".vue": "vue",
47
+ ".svelte": "svelte",
48
+ ".r": "r",
49
+ ".pl": "perl",
50
+ ".pm": "perl"
51
+ },
52
+ "queries": {
53
+ "python": {
54
+ "struct": "(class_definition name: (identifier) @class.name) @class.def\n(function_definition name: (identifier) @func.name) @func.def",
55
+ "imports": "(import_statement name: (dotted_name) @mod)\n(import_from_statement module_name: (dotted_name) @mod)"
56
+ },
57
+ "javascript": {
58
+ "struct": "(class_declaration name: (identifier) @class.name) @class.def\n(function_declaration name: (identifier) @func.name) @func.def\n(method_definition name: (property_identifier) @func.name) @func.def",
59
+ "imports": "(import_statement source: (string (string_fragment) @mod))"
60
+ },
61
+ "typescript": {
62
+ "struct": "(class_declaration name: (type_identifier) @class.name) @class.def\n(function_declaration name: (identifier) @func.name) @func.def\n(method_definition name: (property_identifier) @func.name) @func.def",
63
+ "imports": "(import_statement source: (string (string_fragment) @mod))"
64
+ },
65
+ "tsx": {
66
+ "struct": "(class_declaration name: (type_identifier) @class.name) @class.def\n(function_declaration name: (identifier) @func.name) @func.def\n(method_definition name: (property_identifier) @func.name) @func.def",
67
+ "imports": "(import_statement source: (string (string_fragment) @mod))"
68
+ },
69
+ "java": {
70
+ "struct": "(class_declaration name: (identifier) @class.name) @class.def\n(method_declaration name: (identifier) @func.name) @func.def\n(interface_declaration name: (identifier) @class.name) @class.def",
71
+ "imports": "(import_declaration (scoped_identifier) @mod)"
72
+ },
73
+ "go": {
74
+ "struct": "(type_declaration (type_spec name: (type_identifier) @class.name)) @class.def\n(function_declaration name: (identifier) @func.name) @func.def\n(method_declaration name: (field_identifier) @func.name) @func.def",
75
+ "imports": "(import_spec path: (interpreted_string_literal) @mod)"
76
+ },
77
+ "rust": {
78
+ "struct": "(struct_item name: (type_identifier) @class.name) @class.def\n(enum_item name: (type_identifier) @class.name) @class.def\n(function_item name: (identifier) @func.name) @func.def",
79
+ "imports": "(use_declaration argument: (scoped_identifier) @mod)\n(use_declaration argument: (identifier) @mod)"
80
+ },
81
+ "csharp": {
82
+ "struct": "(class_declaration name: (identifier) @class.name) @class.def\n(method_declaration name: (identifier) @func.name) @func.def\n(interface_declaration name: (identifier) @class.name) @class.def",
83
+ "imports": "(using_directive (qualified_name) @mod)\n(using_directive (identifier) @mod)"
84
+ },
85
+ "cpp": {
86
+ "struct": "(class_specifier name: (type_identifier) @class.name) @class.def\n(function_definition\n declarator: (function_declarator\n declarator: (identifier) @func.name)) @func.def",
87
+ "imports": "(preproc_include path: (system_lib_string) @mod)\n(preproc_include path: (string_literal) @mod)"
88
+ },
89
+ "c": {
90
+ "struct": "(struct_specifier name: (type_identifier) @class.name) @class.def\n(function_definition\n declarator: (function_declarator\n declarator: (identifier) @func.name)) @func.def",
91
+ "imports": "(preproc_include path: (system_lib_string) @mod)\n(preproc_include path: (string_literal) @mod)"
92
+ },
93
+ "kotlin": {
94
+ "struct": "(class_declaration (type_identifier) @class.name) @class.def\n(function_declaration (simple_identifier) @func.name) @func.def",
95
+ "imports": "(import_header (identifier) @mod)"
96
+ },
97
+ "ruby": {
98
+ "struct": "(class name: (constant) @class.name) @class.def\n(method name: (identifier) @func.name) @func.def",
99
+ "imports": ""
100
+ },
101
+ "swift": {
102
+ "struct": "(class_declaration name: (type_identifier) @class.name) @class.def\n(function_declaration name: (simple_identifier) @func.name) @func.def",
103
+ "imports": "(import_declaration (identifier) @mod)"
104
+ },
105
+ "scala": {
106
+ "struct": "(class_definition name: (identifier) @class.name) @class.def\n(function_definition name: (identifier) @func.name) @func.def",
107
+ "imports": "(import_declaration importees: (import_selectors selector: (import_selector name: (identifier) @mod)))"
108
+ },
109
+ "lua": {
110
+ "struct": "(function_declaration name: (identifier) @func.name) @func.def",
111
+ "imports": ""
112
+ },
113
+ "php": {
114
+ "struct": "(class_declaration name: (name) @class.name) @class.def\n(method_declaration name: (name) @func.name) @func.def\n(function_definition name: (name) @func.name) @func.def",
115
+ "imports": "(namespace_use_declaration (namespace_use_clause (qualified_name (name) @mod)))"
116
+ },
117
+ "elixir": {
118
+ "struct": "(call target: (identifier) @_keyword\n arguments: (arguments (alias) @class.name)\n (#match? @_keyword \"^(defmodule|defprotocol)$\")) @class.def\n(call target: (identifier) @_keyword\n arguments: (arguments (identifier) @func.name)\n (#match? @_keyword \"^(def|defp)$\")) @func.def",
119
+ "imports": ""
120
+ },
121
+ "gdscript": {
122
+ "struct": "(class_name_statement name: (name) @class.name) @class.def\n(function_definition name: (name) @func.name) @func.def",
123
+ "imports": ""
124
+ }
125
+ },
126
+ "unsupported_extensions": {}
127
+ }