agentic-sdlc 1.6.0 → 1.8.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.
Files changed (144) hide show
  1. package/.agent/rules/agent-execution.md +55 -0
  2. package/.agent/rules/ai-enforcement.md +4 -3
  3. package/.agent/rules/artifacts.md +1 -1
  4. package/.agent/rules/auto-learning.md +78 -0
  5. package/.agent/rules/code-quality.md +40 -0
  6. package/.agent/rules/global.md +2 -2
  7. package/.agent/rules/naming-conventions.md +55 -0
  8. package/.agent/skills/role-ba.md +6 -2
  9. package/.agent/skills/role-brain.md +5 -1
  10. package/.agent/skills/role-cloud.md +38 -0
  11. package/.agent/skills/role-dev.md +22 -1
  12. package/.agent/skills/role-devops.md +4 -0
  13. package/.agent/skills/role-game.md +35 -0
  14. package/.agent/skills/role-mobile.md +55 -0
  15. package/.agent/skills/role-orchestrator.md +4 -0
  16. package/.agent/skills/role-pm.md +4 -0
  17. package/.agent/skills/role-po.md +4 -0
  18. package/.agent/skills/role-reporter.md +4 -0
  19. package/.agent/skills/role-research.md +78 -0
  20. package/.agent/skills/role-sa.md +4 -0
  21. package/.agent/skills/role-seca.md +4 -0
  22. package/.agent/skills/role-stakeholder.md +4 -0
  23. package/.agent/skills/role-tester.md +4 -0
  24. package/.agent/skills/role-uiux.md +4 -0
  25. package/.agent/templates/Specification-Template.md +38 -0
  26. package/.agent/templates/ab-comparison-report.md +175 -0
  27. package/.agent/templates/observer-report.md +131 -0
  28. package/.agent/templates/quality-score-report.md +197 -0
  29. package/.agent/templates/self-learning-digest.md +268 -0
  30. package/.agent/templates/system-health-report.md +330 -0
  31. package/.agent/workflows/ab.md +101 -0
  32. package/.agent/workflows/autogen.md +65 -0
  33. package/.agent/workflows/brain.md +48 -37
  34. package/.agent/workflows/commit.md +61 -0
  35. package/.agent/workflows/cycle.md +32 -11
  36. package/.agent/workflows/debug.md +123 -0
  37. package/.agent/workflows/deep-search.md +82 -0
  38. package/.agent/workflows/docs.md +144 -0
  39. package/.agent/workflows/emergency.md +17 -15
  40. package/.agent/workflows/explore.md +15 -9
  41. package/.agent/workflows/housekeeping.md +24 -11
  42. package/.agent/workflows/metrics.md +14 -12
  43. package/.agent/workflows/monitor.md +98 -0
  44. package/.agent/workflows/observe.md +84 -0
  45. package/.agent/workflows/onboarding.md +135 -0
  46. package/.agent/workflows/orchestrator.md +12 -5
  47. package/.agent/workflows/planning.md +126 -0
  48. package/.agent/workflows/refactor.md +132 -0
  49. package/.agent/workflows/release.md +19 -12
  50. package/.agent/workflows/review.md +99 -0
  51. package/.agent/workflows/score.md +104 -0
  52. package/.agent/workflows/sprint.md +16 -14
  53. package/.agent/workflows/validate.md +13 -11
  54. package/.agent/workflows/worktree.md +154 -0
  55. package/CHANGELOG.md +71 -0
  56. package/README.md +12 -4
  57. package/bin/cli.js +142 -16
  58. package/docs/.brain-health-history.json +42 -0
  59. package/docs/.brain-improvements.json +53 -0
  60. package/docs/.brain-learner-log.json +27 -0
  61. package/docs/.brain-scores.json +310 -0
  62. package/docs/architecture/system-flow.mermaid +81 -0
  63. package/docs/artifacts/2026-01-05-enforcement-gates-plan.md +80 -0
  64. package/docs/artifacts/2026-01-05-workflow-analysis.md +231 -0
  65. package/docs/artifacts/README.md +26 -0
  66. package/docs/guides/MCP-GUIDE.md +1 -0
  67. package/docs/reports/2026-01-05-autogen-evaluation.md +64 -0
  68. package/docs/reports/2026-01-05-brain-layer-analysis.md +109 -0
  69. package/docs/reports/2026-01-05-repository-audit.md +253 -0
  70. package/docs/reports/Metrics-Dashboard-2026-01-08.md +29 -0
  71. package/docs/reports/Metrics-Dashboard-Final.md +29 -0
  72. package/docs/reports/Validation-Report-2026-01-05.md +40 -0
  73. package/docs/reports/Validation-Report-2026-01-08.md +40 -0
  74. package/docs/reports/worktrunk-audit.md +94 -0
  75. package/docs/solutions/README.md +96 -0
  76. package/docs/walkthroughs/2026-01-05-audit-implementation.md +36 -0
  77. package/docs/walkthroughs/2026-01-05-autonomy-release.md +54 -0
  78. package/docs/walkthroughs/2026-01-05-enforcement-gates.md +33 -0
  79. package/docs/walkthroughs/2026-01-05-judge-enhancement.md +30 -0
  80. package/docs/walkthroughs/2026-01-05-landing-page-orchestrator.md +52 -0
  81. package/docs/walkthroughs/2026-01-05-validation.md +32 -0
  82. package/docs/walkthroughs/2026-01-05-workflow-audit.md +89 -0
  83. package/docs/walkthroughs/2026-01-05-workflow-refactoring.md +44 -0
  84. package/docs/walkthroughs/2026-01-06-worktrunk-integration.md +41 -0
  85. package/docs/walkthroughs/README.md +25 -0
  86. package/package.json +33 -19
  87. package/.agent/knowledge-base/AUTO-LEARNING-GUIDE.md +0 -327
  88. package/.agent/knowledge-base/HOW-IT-WORKS.md +0 -365
  89. package/.agent/knowledge-base/INDEX.md +0 -43
  90. package/.agent/knowledge-base/README.md +0 -242
  91. package/.agent/knowledge-base/architecture/.gitkeep +0 -1
  92. package/.agent/knowledge-base/architecture/KB-2026-01-01-003-neo4j-graph-database-skills.md +0 -1146
  93. package/.agent/knowledge-base/architecture/README.md +0 -98
  94. package/.agent/knowledge-base/bugs/.gitkeep +0 -1
  95. package/.agent/knowledge-base/bugs/KB-2026-01-02-yaml-special-character-escaping.md +0 -56
  96. package/.agent/knowledge-base/bugs/medium/KB-2026-01-01-001-example-auto-learned.md +0 -198
  97. package/.agent/knowledge-base/features/.gitkeep +0 -1
  98. package/.agent/knowledge-base/features/KB-2026-01-01-001-landing-page-design-trends-2026.md +0 -646
  99. package/.agent/knowledge-base/features/KB-2026-01-01-004-uiux-design-skills-2026.md +0 -945
  100. package/.agent/knowledge-base/features/KB-2026-01-01-005-modern-ai-landing-page-ui.md +0 -310
  101. package/.agent/knowledge-base/features/KB-2026-01-01-006-award-winning-landing-page-patterns.md +0 -324
  102. package/.agent/knowledge-base/features/KB-2026-01-02-001-cleanup-workflow.md +0 -242
  103. package/.agent/knowledge-base/features/KB-2026-01-02-002-landing-page-monorepo-architecture.md +0 -148
  104. package/.agent/knowledge-base/features/KB-2026-01-02-003-premium-glassmorphism-patterns.md +0 -58
  105. package/.agent/knowledge-base/features/KB-2026-01-04-ai-agent-enforcement.md +0 -46
  106. package/.agent/knowledge-base/features/README.md +0 -83
  107. package/.agent/knowledge-base/features/figma-landing-page-workflow.md +0 -311
  108. package/.agent/knowledge-base/features/figma-mcp-sa-guide.md +0 -673
  109. package/.agent/knowledge-base/features/figma-mcp-uiux-guide.md +0 -459
  110. package/.agent/knowledge-base/performance/.gitkeep +0 -1
  111. package/.agent/knowledge-base/performance/KB-2026-01-02-lazy-loading-optimization.md +0 -80
  112. package/.agent/knowledge-base/platform-specific/.gitkeep +0 -1
  113. package/.agent/knowledge-base/platform-specific/KB-2026-01-02-windows-console-encoding.md +0 -56
  114. package/.agent/knowledge-base/role-guides/DEV-KB-Guide.md +0 -527
  115. package/.agent/knowledge-base/role-guides/DEVOPS-KB-Guide.md +0 -491
  116. package/.agent/knowledge-base/role-guides/PM-KB-Guide.md +0 -299
  117. package/.agent/knowledge-base/role-guides/SECA-KB-Guide.md +0 -555
  118. package/.agent/knowledge-base/role-guides/TESTER-KB-Guide.md +0 -519
  119. package/.agent/knowledge-base/security/.gitkeep +0 -1
  120. package/.agent/knowledge-base/security/KB-2026-01-02-input-validation-sanitization.md +0 -74
  121. package/.agent/rules/AUTO-LEARNING.md +0 -418
  122. package/.agent/rules/KNOWLEDGE-BASE.md +0 -45
  123. package/.agent/workflows/compound.md +0 -51
  124. package/.agent/workflows/preflight.md +0 -35
  125. package/.agent/workflows/route.md +0 -160
  126. package/bin/kb +0 -34
  127. package/bin/kb.bat +0 -28
  128. package/bin/kb_cli.py +0 -226
  129. package/bin/lib/README.md +0 -411
  130. package/bin/lib/__init__.py +0 -7
  131. package/bin/lib/__pycache__/kb_add.cpython-313.pyc +0 -0
  132. package/bin/lib/__pycache__/kb_common.cpython-313.pyc +0 -0
  133. package/bin/lib/__pycache__/kb_compound.cpython-313.pyc +0 -0
  134. package/bin/lib/__pycache__/kb_index.cpython-313.pyc +0 -0
  135. package/bin/lib/__pycache__/kb_list.cpython-313.pyc +0 -0
  136. package/bin/lib/__pycache__/kb_search.cpython-313.pyc +0 -0
  137. package/bin/lib/__pycache__/kb_stats.cpython-313.pyc +0 -0
  138. package/bin/lib/kb_add.py +0 -203
  139. package/bin/lib/kb_common.py +0 -224
  140. package/bin/lib/kb_compound.py +0 -250
  141. package/bin/lib/kb_index.py +0 -193
  142. package/bin/lib/kb_list.py +0 -144
  143. package/bin/lib/kb_search.py +0 -121
  144. package/bin/lib/kb_stats.py +0 -153
@@ -1,193 +0,0 @@
1
- """
2
- KB Index Module
3
- Cross-platform INDEX.md generation
4
- """
5
-
6
- from pathlib import Path
7
- from datetime import datetime
8
- from collections import defaultdict
9
- from kb_common import (
10
- KBConfig, Colors, parse_frontmatter, get_kb_entries, get_all_kb_entries,
11
- print_header, print_success, get_priority_icon, get_category_icon
12
- )
13
-
14
-
15
- def update_index():
16
- """Update INDEX.md"""
17
- config = KBConfig()
18
- Colors.enable_windows()
19
-
20
- print_header("📇 Updating Knowledge Base Index", "Scanning KB + docs directories...")
21
-
22
- all_paths = config.get_all_kb_paths()
23
- entries = get_all_kb_entries(all_paths)
24
-
25
- # Parse all entries
26
- parsed_entries = []
27
- for entry_path in entries:
28
- try:
29
- content = entry_path.read_text(encoding='utf-8')
30
- metadata = parse_frontmatter(content)
31
-
32
- if metadata:
33
- metadata['path'] = entry_path
34
- metadata['filename'] = entry_path.name
35
- parsed_entries.append(metadata)
36
- except Exception as e:
37
- continue
38
-
39
- # Group entries
40
- by_category = defaultdict(list)
41
- by_priority = defaultdict(list)
42
- by_date = defaultdict(list)
43
-
44
- for entry in parsed_entries:
45
- category = entry.get('category', 'unknown')
46
- priority = entry.get('priority', 'unknown')
47
- date = entry.get('date', 'unknown')
48
-
49
- by_category[category].append(entry)
50
- by_priority[priority].append(entry)
51
- by_date[date].append(entry)
52
-
53
- # Generate INDEX.md
54
- index_content = generate_index_content(parsed_entries, by_category, by_priority, by_date)
55
-
56
- # Write INDEX.md
57
- index_path = config.get_index_path()
58
- index_path.write_text(index_content, encoding='utf-8')
59
-
60
- print_success(f"INDEX.md Updated Successfully!")
61
- print()
62
- print(f"{Colors.CYAN}📊 Statistics:{Colors.RESET}")
63
- print(f" Total Entries: {len(parsed_entries)}")
64
- print(f" Categories: {len(by_category)}")
65
- print(f" Priorities: {len(by_priority)}")
66
- print()
67
-
68
-
69
- def generate_index_content(entries, by_category, by_priority, by_date):
70
- """Generate INDEX.md content"""
71
- content = f"""# Knowledge Base Index
72
-
73
- **Last Updated:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
74
- **Total Entries:** {len(entries)}
75
-
76
- This index provides a searchable overview of all knowledge base entries.
77
-
78
- ---
79
-
80
- ## 📊 Quick Stats
81
-
82
- - **Total Entries:** {len(entries)}
83
- - **Categories:** {len(by_category)}
84
- - **Priorities:** {len(by_priority)}
85
-
86
- ---
87
-
88
- ## 📁 By Category
89
-
90
- """
91
-
92
- # Add entries by category
93
- for category in sorted(by_category.keys()):
94
- icon = get_category_icon(category)
95
- entries_list = by_category[category]
96
- content += f"\n### {icon} {category.title()} ({len(entries_list)} entries)\n\n"
97
-
98
- for entry in sorted(entries_list, key=lambda x: x.get('date', ''), reverse=True):
99
- title = entry.get('title', 'Unknown')
100
- filename = entry.get('filename', '')
101
- priority = entry.get('priority', 'unknown')
102
- date = entry.get('date', 'unknown')
103
- tags = entry.get('tags', [])
104
-
105
- priority_icon = get_priority_icon(priority)
106
- tags_str = ', '.join(tags) if isinstance(tags, list) else tags
107
-
108
- content += f"- {priority_icon} **{title}**\n"
109
- content += f" - File: `{filename}`\n"
110
- content += f" - Date: {date} | Priority: {priority}\n"
111
- if tags_str:
112
- content += f" - Tags: {tags_str}\n"
113
- content += "\n"
114
-
115
- # Add by priority
116
- content += "\n---\n\n## ⚠️ By Priority\n\n"
117
-
118
- priority_order = ['critical', 'high', 'medium', 'low']
119
- for priority in priority_order:
120
- if priority in by_priority:
121
- icon = get_priority_icon(priority)
122
- entries_list = by_priority[priority]
123
- content += f"\n### {icon} {priority.title()} ({len(entries_list)} entries)\n\n"
124
-
125
- for entry in sorted(entries_list, key=lambda x: x.get('date', ''), reverse=True)[:10]:
126
- title = entry.get('title', 'Unknown')
127
- filename = entry.get('filename', '')
128
- category = entry.get('category', 'unknown')
129
-
130
- content += f"- **{title}** ({category})\n"
131
- content += f" - `{filename}`\n"
132
-
133
- # Add recent entries
134
- content += "\n---\n\n## 📅 Recent Entries (Last 20)\n\n"
135
-
136
- recent = sorted(entries, key=lambda x: x.get('date', ''), reverse=True)[:20]
137
- for entry in recent:
138
- title = entry.get('title', 'Unknown')
139
- filename = entry.get('filename', '')
140
- category = entry.get('category', 'unknown')
141
- priority = entry.get('priority', 'unknown')
142
- date = entry.get('date', 'unknown')
143
-
144
- icon = get_priority_icon(priority)
145
- content += f"- {icon} **{title}**\n"
146
- content += f" - `{filename}`\n"
147
- content += f" - {date} | {category} | {priority}\n\n"
148
-
149
- # Add search tips
150
- content += """
151
- ---
152
-
153
- ## 🔍 How to Search
154
-
155
- ### Using CLI
156
- ```bash
157
- # Search by keyword
158
- kb search "react hydration"
159
-
160
- # Compound search (file + Neo4j)
161
- kb compound search "authentication"
162
- ```
163
-
164
- ### Using Scripts
165
- ```bash
166
- # PowerShell (Windows)
167
- .\\bin\\kb.ps1 search "term"
168
-
169
- # Bash (Linux/Mac)
170
- ./bin/kb search "term"
171
- ```
172
-
173
- ---
174
-
175
- ## 📝 Adding Entries
176
-
177
- ```bash
178
- # Interactive add
179
- kb add
180
-
181
- # Compound add (auto-sync to Neo4j)
182
- kb compound add
183
- ```
184
-
185
- ---
186
-
187
- **Generated by:** Knowledge Base Index Generator
188
- **Platform:** Cross-platform (Windows/Linux/macOS)
189
-
190
- #knowledge-base #index #searchable
191
- """
192
-
193
- return content
@@ -1,144 +0,0 @@
1
- """
2
- KB List Module
3
- Cross-platform entry listing
4
- """
5
-
6
- from pathlib import Path
7
- from kb_common import (
8
- KBConfig, Colors, parse_frontmatter, get_kb_entries, format_time_ago,
9
- print_header, get_priority_icon, get_category_icon
10
- )
11
-
12
-
13
- def list_entries(category=None, recent=None):
14
- """List KB entries"""
15
- config = KBConfig()
16
- Colors.enable_windows()
17
-
18
- if recent:
19
- list_recent_entries(config, recent)
20
- elif category:
21
- list_by_category(config, category)
22
- else:
23
- list_all_entries(config)
24
-
25
-
26
- def list_all_entries(config: KBConfig):
27
- """List all entries"""
28
- print_header("📋 Listing All Entries", "All knowledge base entries")
29
-
30
- kb_path = config.get_kb_path()
31
- entries = get_kb_entries(kb_path)
32
-
33
- if not entries:
34
- print(f"{Colors.YELLOW}No entries found.{Colors.RESET}")
35
- return
36
-
37
- print(f"{Colors.GREEN}Found {len(entries)} entries:{Colors.RESET}")
38
- print()
39
-
40
- # Sort by date (newest first)
41
- sorted_entries = sorted(entries, key=lambda x: x.name, reverse=True)
42
-
43
- for entry_path in sorted_entries:
44
- try:
45
- content = entry_path.read_text(encoding='utf-8')
46
- metadata = parse_frontmatter(content)
47
-
48
- title = metadata.get('title', 'Unknown')
49
- priority = metadata.get('priority', 'unknown')
50
- category = metadata.get('category', 'unknown')
51
-
52
- priority_icon = get_priority_icon(priority)
53
- category_icon = get_category_icon(category)
54
-
55
- rel_path = entry_path.relative_to(config.root_dir)
56
-
57
- print(f" {priority_icon} {category_icon} {Colors.WHITE}{title}{Colors.RESET}")
58
- print(f" {Colors.GRAY}{rel_path}{Colors.RESET}")
59
- print()
60
- except:
61
- continue
62
-
63
-
64
- def list_by_category(config: KBConfig, category: str):
65
- """List entries by category"""
66
- print_header(f"📋 Listing Entries in Category: {category}", f"Filtered by {category}")
67
-
68
- kb_path = config.get_kb_path()
69
- category_path = kb_path / category
70
-
71
- if not category_path.exists():
72
- # Try common category paths
73
- for cat_dir in ['bugs', 'features', 'architecture', 'security', 'performance', 'platform-specific']:
74
- if category.lower() in cat_dir:
75
- category_path = kb_path / cat_dir
76
- break
77
-
78
- if not category_path.exists():
79
- print(f"{Colors.YELLOW}Category not found: {category}{Colors.RESET}")
80
- print()
81
- print(f"{Colors.CYAN}Available categories:{Colors.RESET}")
82
- for cat_dir in kb_path.iterdir():
83
- if cat_dir.is_dir() and not cat_dir.name.startswith('.'):
84
- print(f" - {cat_dir.name}")
85
- return
86
-
87
- entries = list(category_path.rglob('KB-*.md'))
88
-
89
- if not entries:
90
- print(f"{Colors.YELLOW}No entries found in category: {category}{Colors.RESET}")
91
- return
92
-
93
- print(f"{Colors.GREEN}Found {len(entries)} entries:{Colors.RESET}")
94
- print()
95
-
96
- for entry_path in sorted(entries, key=lambda x: x.name, reverse=True):
97
- try:
98
- content = entry_path.read_text(encoding='utf-8')
99
- metadata = parse_frontmatter(content)
100
-
101
- title = metadata.get('title', 'Unknown')
102
- priority = metadata.get('priority', 'unknown')
103
-
104
- priority_icon = get_priority_icon(priority)
105
- rel_path = entry_path.relative_to(config.root_dir)
106
-
107
- print(f" {priority_icon} {Colors.WHITE}{title}{Colors.RESET}")
108
- print(f" {Colors.GRAY}{rel_path}{Colors.RESET}")
109
- print()
110
- except:
111
- continue
112
-
113
-
114
- def list_recent_entries(config: KBConfig, count: int):
115
- """List recent entries"""
116
- print_header(f"📅 Recent {count} Entries", "Most recently modified")
117
-
118
- kb_path = config.get_kb_path()
119
- entries = get_kb_entries(kb_path)
120
-
121
- if not entries:
122
- print(f"{Colors.YELLOW}No entries found.{Colors.RESET}")
123
- return
124
-
125
- # Sort by modification time
126
- sorted_entries = sorted(entries, key=lambda x: x.stat().st_mtime, reverse=True)[:count]
127
-
128
- for entry_path in sorted_entries:
129
- try:
130
- content = entry_path.read_text(encoding='utf-8')
131
- metadata = parse_frontmatter(content)
132
-
133
- title = metadata.get('title', 'Unknown')
134
- category = metadata.get('category', 'unknown')
135
- priority = metadata.get('priority', 'unknown')
136
-
137
- time_ago = format_time_ago(entry_path)
138
- category_icon = get_category_icon(category)
139
-
140
- print(f" {category_icon} {Colors.WHITE}{title}{Colors.RESET}")
141
- print(f" Category: {category} | {Colors.GRAY}{time_ago}{Colors.RESET}")
142
- print()
143
- except:
144
- continue
@@ -1,121 +0,0 @@
1
- """
2
- KB Search Module
3
- Cross-platform search functionality
4
- """
5
-
6
- import re
7
- from pathlib import Path
8
- from typing import List, Dict
9
- from kb_common import (
10
- KBConfig, Colors, parse_frontmatter, get_kb_entries, get_all_kb_entries,
11
- print_header, print_success, print_warning, get_priority_icon
12
- )
13
-
14
-
15
- def search_kb(search_term: str):
16
- """Search knowledge base"""
17
- config = KBConfig()
18
- Colors.enable_windows()
19
-
20
- print_header(
21
- f"🔍 Searching Knowledge Base for: '{search_term}'",
22
- "File System Search"
23
- )
24
-
25
- # Search INDEX.md first
26
- results_from_index = search_index(config, search_term)
27
-
28
- # Search all KB files
29
- results_from_files = search_files(config, search_term)
30
-
31
- # Display results
32
- total_results = len(results_from_index) + len(results_from_files)
33
-
34
- if total_results == 0:
35
- print_warning(f"No results found for '{search_term}'")
36
- print()
37
- print(f"{Colors.CYAN}💡 Tips:{Colors.RESET}")
38
- print(f" - Try different keywords")
39
- print(f" - Use broader search terms")
40
- print(f" - Check spelling")
41
- print(f" - Try compound search: {Colors.MAGENTA}kb compound search '{search_term}'{Colors.RESET}")
42
- else:
43
- print()
44
- print(f"{Colors.GREEN}📊 Search Results: {total_results} entries found{Colors.RESET}")
45
-
46
- print()
47
-
48
-
49
- def search_index(config: KBConfig, search_term: str) -> List[str]:
50
- """Search INDEX.md"""
51
- if not config.get_index_path().exists():
52
- return []
53
-
54
- content = config.get_index_path().read_text(encoding='utf-8')
55
- results = []
56
-
57
- # Search for term in index
58
- pattern = re.compile(re.escape(search_term), re.IGNORECASE)
59
-
60
- for line in content.split('\n'):
61
- if pattern.search(line) and line.strip().startswith('-'):
62
- results.append(line.strip())
63
-
64
- if results:
65
- print(f"{Colors.GREEN}✅ Found in INDEX:{Colors.RESET}")
66
- for result in results[:5]: # Show first 5
67
- print(f" {result}")
68
- print()
69
-
70
- return results
71
-
72
-
73
- def search_files(config: KBConfig, search_term: str) -> List[Dict]:
74
- """Search all KB files (KB + docs)"""
75
- all_paths = config.get_all_kb_paths()
76
- entries = get_all_kb_entries(all_paths)
77
-
78
- results = []
79
- pattern = re.compile(re.escape(search_term), re.IGNORECASE)
80
-
81
- for entry_path in entries:
82
- try:
83
- content = entry_path.read_text(encoding='utf-8')
84
-
85
- # Check if term is in content
86
- if pattern.search(content):
87
- metadata = parse_frontmatter(content)
88
-
89
- # Extract context (line with match)
90
- context_lines = []
91
- for line in content.split('\n'):
92
- if pattern.search(line):
93
- context_lines.append(line.strip())
94
- if len(context_lines) >= 3:
95
- break
96
-
97
- results.append({
98
- 'path': entry_path,
99
- 'title': metadata.get('title', 'Unknown'),
100
- 'category': metadata.get('category', 'unknown'),
101
- 'priority': metadata.get('priority', 'unknown'),
102
- 'context': context_lines
103
- })
104
- except Exception as e:
105
- continue
106
-
107
- # Display file results
108
- if results:
109
- for i, result in enumerate(results, 1):
110
- icon = get_priority_icon(result['priority'])
111
- print(f"{Colors.GREEN}✅ Found: {result['title']}{Colors.RESET}")
112
- print(f" {icon} File: {result['path'].relative_to(config.root_dir)}")
113
- print(f" Category: {result['category']} | Priority: {result['priority']}")
114
-
115
- if result['context']:
116
- print(f" {Colors.CYAN}Context:{Colors.RESET}")
117
- for ctx in result['context'][:2]:
118
- print(f" {ctx[:80]}...")
119
- print()
120
-
121
- return results
@@ -1,153 +0,0 @@
1
- """
2
- KB Stats Module
3
- Cross-platform statistics display
4
- """
5
-
6
- from pathlib import Path
7
- from datetime import datetime
8
- from collections import defaultdict
9
- from kb_common import (
10
- KBConfig, Colors, parse_frontmatter, get_kb_entries, format_time_ago,
11
- print_header, get_priority_icon, get_category_icon
12
- )
13
-
14
-
15
- def show_stats():
16
- """Show KB statistics"""
17
- config = KBConfig()
18
- Colors.enable_windows()
19
-
20
- print_header("📊 Knowledge Base Statistics", "Analyzing entries...")
21
-
22
- kb_path = config.get_kb_path()
23
- entries = get_kb_entries(kb_path)
24
-
25
- if not entries:
26
- print(f"{Colors.YELLOW}No entries found in knowledge base.{Colors.RESET}")
27
- print()
28
- print(f"{Colors.CYAN}💡 Add your first entry:{Colors.RESET}")
29
- print(f" kb add")
30
- return
31
-
32
- # Parse entries
33
- parsed = []
34
- total_attempts = 0
35
- total_time_saved = 0
36
-
37
- by_category = defaultdict(int)
38
- by_priority = defaultdict(int)
39
- by_month = defaultdict(int)
40
-
41
- for entry_path in entries:
42
- try:
43
- content = entry_path.read_text(encoding='utf-8')
44
- metadata = parse_frontmatter(content)
45
-
46
- if metadata:
47
- metadata['path'] = entry_path
48
- parsed.append(metadata)
49
-
50
- # Count stats
51
- category = metadata.get('category', 'unknown')
52
- priority = metadata.get('priority', 'unknown')
53
- date = metadata.get('date', 'unknown')
54
-
55
- by_category[category] += 1
56
- by_priority[priority] += 1
57
-
58
- if date != 'unknown':
59
- month = date[:7] # YYYY-MM
60
- by_month[month] += 1
61
-
62
- # Attempts
63
- attempts = metadata.get('attempts', '0')
64
- try:
65
- total_attempts += int(attempts)
66
- except:
67
- pass
68
-
69
- # Time saved
70
- time_saved = metadata.get('time_saved', '0')
71
- if 'hour' in time_saved.lower():
72
- try:
73
- hours = float(time_saved.split()[0])
74
- total_time_saved += hours
75
- except:
76
- pass
77
- except:
78
- continue
79
-
80
- # Display stats
81
- print(f"{Colors.WHITE}{Colors.BOLD}📚 Total Entries: {len(parsed)}{Colors.RESET}")
82
- print()
83
-
84
- # By category
85
- if by_category:
86
- print(f"{Colors.YELLOW}{Colors.BOLD}📁 By Category:{Colors.RESET}")
87
- max_count = max(by_category.values())
88
- for category in sorted(by_category.keys()):
89
- count = by_category[category]
90
- percentage = (count / len(parsed)) * 100
91
- icon = get_category_icon(category)
92
- bar_length = int((count / max_count) * 30)
93
- bar = '█' * bar_length
94
-
95
- print(f" {icon} {category.ljust(15)} : {count} entries ({percentage:.1f}%)")
96
- print(f" {Colors.CYAN}{bar}{Colors.RESET}")
97
- print()
98
-
99
- # By priority
100
- if by_priority:
101
- print(f"{Colors.YELLOW}{Colors.BOLD}⚠️ By Priority:{Colors.RESET}")
102
- priority_order = ['critical', 'high', 'medium', 'low']
103
- for priority in priority_order:
104
- if priority in by_priority:
105
- count = by_priority[priority]
106
- percentage = (count / len(parsed)) * 100
107
- icon = get_priority_icon(priority)
108
- print(f" {icon} {priority.ljust(12)} : {count} entries ({percentage:.1f}%)")
109
- print()
110
-
111
- # Compound metrics
112
- print(f"{Colors.YELLOW}{Colors.BOLD}📈 Compound Learning Metrics:{Colors.RESET}")
113
- avg_attempts = total_attempts / len(parsed) if parsed else 0
114
- avg_time_saved = total_time_saved / len(parsed) if parsed else 0
115
- projected_time = total_time_saved * 2 # Assume 2x reuse
116
-
117
- print(f" Total Attempts: {total_attempts}")
118
- print(f" Avg Attempts per Entry: {avg_attempts:.1f}")
119
- print(f" Total Time Saved: ~{int(total_time_saved)} hours")
120
- print(f" Avg Time Saved per Entry: ~{avg_time_saved:.1f} hours")
121
- print(f" Projected Time Saved (2x reuse): ~{int(projected_time)} hours")
122
- print()
123
-
124
- # Recent activity
125
- print(f"{Colors.YELLOW}{Colors.BOLD}📅 Recent Activity:{Colors.RESET}")
126
- recent = sorted(parsed, key=lambda x: x.get('path').stat().st_mtime, reverse=True)[:5]
127
-
128
- for entry in recent:
129
- title = entry.get('title', 'Unknown')
130
- path = entry.get('path')
131
- time_ago = format_time_ago(path)
132
-
133
- print(f" - {title}")
134
- print(f" {Colors.GRAY}{time_ago}{Colors.RESET}")
135
- print()
136
-
137
- # Growth trend
138
- if by_month:
139
- print(f"{Colors.YELLOW}{Colors.BOLD}📊 Growth Trend:{Colors.RESET}")
140
- for month in sorted(by_month.keys(), reverse=True)[:6]:
141
- count = by_month[month]
142
- bar = '█' * count
143
- print(f" {month} : {count} entries")
144
- print(f" {Colors.CYAN}{bar}{Colors.RESET}")
145
- print()
146
-
147
- # Compound effect message
148
- print(f"{Colors.CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{Colors.RESET}")
149
- print(f"{Colors.GREEN}{Colors.BOLD}💡 Compound Effect:{Colors.RESET}")
150
- print(f" Each entry makes future work easier!")
151
- print(f" Keep documenting to compound your knowledge! 🚀")
152
- print(f"{Colors.CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━{Colors.RESET}")
153
- print()