@codihaus/claude-skills 1.0.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 (46) hide show
  1. package/README.md +167 -0
  2. package/bin/cli.js +58 -0
  3. package/package.json +46 -0
  4. package/skills/_quality-attributes.md +392 -0
  5. package/skills/_registry.md +189 -0
  6. package/skills/debrief/SKILL.md +647 -0
  7. package/skills/debrief/references/change-request-template.md +124 -0
  8. package/skills/debrief/references/file-patterns.md +173 -0
  9. package/skills/debrief/references/group-codes.md +72 -0
  10. package/skills/debrief/references/research-queries.md +106 -0
  11. package/skills/debrief/references/use-case-template.md +141 -0
  12. package/skills/debrief/scripts/generate_questionnaire.py +195 -0
  13. package/skills/dev-arch/SKILL.md +747 -0
  14. package/skills/dev-changelog/SKILL.md +378 -0
  15. package/skills/dev-coding/SKILL.md +470 -0
  16. package/skills/dev-coding-backend/SKILL.md +361 -0
  17. package/skills/dev-coding-frontend/SKILL.md +534 -0
  18. package/skills/dev-coding-frontend/references/nextjs.md +477 -0
  19. package/skills/dev-review/SKILL.md +548 -0
  20. package/skills/dev-scout/SKILL.md +723 -0
  21. package/skills/dev-scout/references/feature-patterns.md +210 -0
  22. package/skills/dev-scout/references/file-patterns.md +252 -0
  23. package/skills/dev-scout/references/tech-detection.md +211 -0
  24. package/skills/dev-scout/scripts/scout-analyze.sh +280 -0
  25. package/skills/dev-specs/SKILL.md +577 -0
  26. package/skills/dev-specs/references/checklist.md +176 -0
  27. package/skills/dev-specs/references/spec-templates.md +460 -0
  28. package/skills/dev-test/SKILL.md +364 -0
  29. package/skills/utils/diagram/SKILL.md +205 -0
  30. package/skills/utils/diagram/references/common-errors.md +305 -0
  31. package/skills/utils/diagram/references/diagram-types.md +636 -0
  32. package/skills/utils/docs-graph/SKILL.md +204 -0
  33. package/skills/utils/gemini/SKILL.md +292 -0
  34. package/skills/utils/gemini/scripts/gemini-scan.py +340 -0
  35. package/skills/utils/gemini/scripts/setup.sh +169 -0
  36. package/src/commands/add.js +64 -0
  37. package/src/commands/doctor.js +179 -0
  38. package/src/commands/init.js +251 -0
  39. package/src/commands/list.js +88 -0
  40. package/src/commands/remove.js +60 -0
  41. package/src/commands/update.js +72 -0
  42. package/src/index.js +26 -0
  43. package/src/utils/config.js +272 -0
  44. package/src/utils/deps.js +599 -0
  45. package/src/utils/skills.js +253 -0
  46. package/templates/CLAUDE.md.template +58 -0
@@ -0,0 +1,195 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Generate dynamic questionnaire based on debrief gaps.
4
+ Called at end of debrief with identified open questions.
5
+
6
+ Usage:
7
+ python generate_questionnaire.py output.xlsx questions.json
8
+
9
+ questions.json format:
10
+ {
11
+ "project_name": "Project Name",
12
+ "date": "2024-01-20",
13
+ "questions": [
14
+ {
15
+ "category": "Requirements",
16
+ "question": "What is the expected user load?",
17
+ "priority": "Required",
18
+ "context": "Needed for infrastructure planning",
19
+ "source": "UC-PAY-003"
20
+ }
21
+ ]
22
+ }
23
+ """
24
+
25
+ import sys
26
+ import json
27
+ from openpyxl import Workbook
28
+ from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
29
+ from openpyxl.utils import get_column_letter
30
+
31
+
32
+ def create_questionnaire(output_path: str, questions_data: dict):
33
+ wb = Workbook()
34
+ ws = wb.active
35
+ ws.title = "Questions"
36
+
37
+ # Styles
38
+ header_font = Font(bold=True, color="FFFFFF", size=12)
39
+ header_fill = PatternFill("solid", fgColor="4472C4")
40
+ required_fill = PatternFill("solid", fgColor="FCE4D6")
41
+ optional_fill = PatternFill("solid", fgColor="E2EFDA")
42
+ border = Border(
43
+ left=Side(style='thin'),
44
+ right=Side(style='thin'),
45
+ top=Side(style='thin'),
46
+ bottom=Side(style='thin')
47
+ )
48
+ wrap_alignment = Alignment(wrap_text=True, vertical='top')
49
+
50
+ # Title row
51
+ ws.merge_cells('A1:E1')
52
+ title_cell = ws['A1']
53
+ title_cell.value = f"Questions for: {questions_data.get('project_name', 'Project')}"
54
+ title_cell.font = Font(bold=True, size=14)
55
+ title_cell.alignment = Alignment(horizontal='center')
56
+
57
+ # Date row
58
+ ws.merge_cells('A2:E2')
59
+ ws['A2'] = f"Generated: {questions_data.get('date', '')}"
60
+ ws['A2'].font = Font(italic=True, color="666666")
61
+ ws['A2'].alignment = Alignment(horizontal='center')
62
+
63
+ # Headers
64
+ headers = ["Category", "Question", "Priority", "Answer", "Context/Source"]
65
+ col_widths = [15, 45, 12, 40, 25]
66
+
67
+ for col, (header, width) in enumerate(zip(headers, col_widths), 1):
68
+ cell = ws.cell(row=4, column=col, value=header)
69
+ cell.font = header_font
70
+ cell.fill = header_fill
71
+ cell.alignment = Alignment(horizontal='center', vertical='center')
72
+ cell.border = border
73
+ ws.column_dimensions[get_column_letter(col)].width = width
74
+
75
+ # Questions
76
+ questions = questions_data.get('questions', [])
77
+
78
+ for row_idx, q in enumerate(questions, 5):
79
+ category = q.get('category', 'General')
80
+ question = q.get('question', '')
81
+ priority = q.get('priority', 'Optional')
82
+ context = q.get('context', '')
83
+ source = q.get('source', '')
84
+
85
+ # Combine context and source
86
+ context_text = context
87
+ if source:
88
+ context_text = f"{context}\n[Source: {source}]" if context else f"[Source: {source}]"
89
+
90
+ ws.cell(row=row_idx, column=1, value=category).border = border
91
+
92
+ q_cell = ws.cell(row=row_idx, column=2, value=question)
93
+ q_cell.border = border
94
+ q_cell.alignment = wrap_alignment
95
+
96
+ priority_cell = ws.cell(row=row_idx, column=3, value=priority)
97
+ priority_cell.border = border
98
+ priority_cell.alignment = Alignment(horizontal='center')
99
+ if priority == "Required":
100
+ priority_cell.fill = required_fill
101
+ else:
102
+ priority_cell.fill = optional_fill
103
+
104
+ ws.cell(row=row_idx, column=4, value="").border = border
105
+
106
+ ctx_cell = ws.cell(row=row_idx, column=5, value=context_text)
107
+ ctx_cell.border = border
108
+ ctx_cell.alignment = wrap_alignment
109
+ ctx_cell.font = Font(italic=True, color="666666", size=10)
110
+
111
+ # Set row heights
112
+ ws.row_dimensions[1].height = 25
113
+ ws.row_dimensions[4].height = 25
114
+ for row in range(5, len(questions) + 5):
115
+ ws.row_dimensions[row].height = 35
116
+
117
+ # Freeze header row
118
+ ws.freeze_panes = 'A5'
119
+
120
+ # Summary sheet
121
+ ws_summary = wb.create_sheet("Summary", 0)
122
+ summary_data = [
123
+ ("Project Questionnaire", ""),
124
+ ("", ""),
125
+ ("Project:", questions_data.get('project_name', '')),
126
+ ("Generated:", questions_data.get('date', '')),
127
+ ("Total Questions:", len(questions)),
128
+ ("", ""),
129
+ ("Priority Breakdown:", ""),
130
+ ]
131
+
132
+ # Count priorities
133
+ required_count = sum(1 for q in questions if q.get('priority') == 'Required')
134
+ optional_count = len(questions) - required_count
135
+
136
+ summary_data.extend([
137
+ ("Required:", required_count),
138
+ ("Optional:", optional_count),
139
+ ("", ""),
140
+ ("Categories:", ""),
141
+ ])
142
+
143
+ # Count categories
144
+ categories = {}
145
+ for q in questions:
146
+ cat = q.get('category', 'General')
147
+ categories[cat] = categories.get(cat, 0) + 1
148
+
149
+ for cat, count in sorted(categories.items()):
150
+ summary_data.append((f" {cat}:", count))
151
+
152
+ summary_data.extend([
153
+ ("", ""),
154
+ ("Instructions:", ""),
155
+ ("1.", "Fill in the 'Answer' column for each question"),
156
+ ("2.", "Required questions must be answered before proceeding"),
157
+ ("3.", "Context/Source shows where this question originated"),
158
+ ("4.", "Save and return this file when complete"),
159
+ ])
160
+
161
+ for row, (col1, col2) in enumerate(summary_data, 1):
162
+ ws_summary.cell(row=row, column=1, value=col1)
163
+ ws_summary.cell(row=row, column=2, value=col2)
164
+ if row == 1:
165
+ ws_summary.cell(row=row, column=1).font = Font(bold=True, size=14)
166
+ elif col1.endswith(':') and col2 != "":
167
+ ws_summary.cell(row=row, column=1).font = Font(bold=True)
168
+
169
+ ws_summary.column_dimensions['A'].width = 25
170
+ ws_summary.column_dimensions['B'].width = 40
171
+
172
+ # Save
173
+ wb.save(output_path)
174
+ print(f"Created: {output_path}")
175
+ print(f" - {len(questions)} questions")
176
+ print(f" - {required_count} required, {optional_count} optional")
177
+ return output_path
178
+
179
+
180
+ if __name__ == "__main__":
181
+ if len(sys.argv) < 3:
182
+ print("Usage: python generate_questionnaire.py output.xlsx questions.json")
183
+ print("\nOr pipe JSON: echo '{...}' | python generate_questionnaire.py output.xlsx -")
184
+ sys.exit(1)
185
+
186
+ output = sys.argv[1]
187
+ json_source = sys.argv[2]
188
+
189
+ if json_source == "-":
190
+ data = json.load(sys.stdin)
191
+ else:
192
+ with open(json_source, 'r') as f:
193
+ data = json.load(f)
194
+
195
+ create_questionnaire(output, data)