lite-kits 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl
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.
- lite_kits/__init__.py +9 -9
- lite_kits/cli.py +170 -155
- lite_kits/core/__init__.py +13 -0
- lite_kits/core/banner.py +160 -0
- lite_kits/{installer.py → core/installer.py} +47 -27
- lite_kits/core/manifest.py +146 -0
- lite_kits/kits/README.md +9 -10
- lite_kits/kits/dev/README.md +241 -0
- lite_kits/kits/dev/claude/commands/audit.md +143 -0
- lite_kits/kits/dev/claude/commands/cleanup.md +361 -0
- lite_kits/kits/dev/claude/commands/commit.md +612 -0
- lite_kits/kits/dev/claude/commands/orient.md +146 -0
- lite_kits/kits/dev/claude/commands/pr.md +593 -0
- lite_kits/kits/dev/claude/commands/review.md +202 -0
- lite_kits/kits/dev/claude/commands/stats.md +162 -0
- lite_kits/kits/dev/github/prompts/audit.prompt.md +143 -0
- lite_kits/kits/dev/github/prompts/cleanup.prompt.md +382 -0
- lite_kits/kits/dev/github/prompts/commit.prompt.md +591 -0
- lite_kits/kits/dev/github/prompts/orient.prompt.md +150 -0
- lite_kits/kits/dev/github/prompts/pr.prompt.md +603 -0
- lite_kits/kits/dev/github/prompts/review.prompt.md +202 -0
- lite_kits/kits/dev/github/prompts/stats.prompt.md +163 -0
- lite_kits/kits/git/README.md +59 -68
- lite_kits/kits/git/claude/commands/review.md +202 -0
- lite_kits/kits/git/github/prompts/review.prompt.md +202 -0
- lite_kits/kits/kits.yaml +180 -0
- lite_kits/kits/multiagent/README.md +26 -15
- lite_kits/kits/multiagent/memory/pr-workflow-guide.md +1 -7
- lite_kits/kits/project/README.md +6 -22
- lite_kits/kits/project/claude/commands/audit.md +143 -0
- lite_kits/kits/project/claude/commands/orient.md +29 -46
- lite_kits/kits/project/claude/commands/review.md +112 -0
- lite_kits/kits/project/claude/commands/stats.md +162 -0
- lite_kits/kits/project/github/prompts/audit.prompt.md +143 -0
- lite_kits/kits/project/github/prompts/orient.prompt.md +33 -46
- lite_kits/kits/project/github/prompts/review.prompt.md +112 -0
- lite_kits/kits/project/github/prompts/stats.prompt.md +163 -0
- {lite_kits-0.1.0.dist-info → lite_kits-0.1.1.dist-info}/METADATA +98 -66
- lite_kits-0.1.1.dist-info/RECORD +58 -0
- lite_kits-0.1.0.dist-info/RECORD +0 -31
- {lite_kits-0.1.0.dist-info → lite_kits-0.1.1.dist-info}/WHEEL +0 -0
- {lite_kits-0.1.0.dist-info → lite_kits-0.1.1.dist-info}/entry_points.txt +0 -0
- {lite_kits-0.1.0.dist-info → lite_kits-0.1.1.dist-info}/licenses/LICENSE +0 -0
lite_kits/core/banner.py
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
from rich.console import Console
|
2
|
+
from rich.text import Text
|
3
|
+
from rich.live import Live
|
4
|
+
import time
|
5
|
+
import sys
|
6
|
+
|
7
|
+
console = Console()
|
8
|
+
|
9
|
+
BANNER = """
|
10
|
+
██╗ ██╗████████╗███████╗ ██╗ ██╗██╗████████╗███████╗
|
11
|
+
██║ ██║╚══██╔══╝██╔════╝ ██║ ██╔╝██║╚══██╔══╝██╔════╝
|
12
|
+
██║ ██║ ██║ █████╗ █████╗█████╔╝ ██║ ██║ ███████╗
|
13
|
+
██║ ██║ ██║ ██╔══╝ ╚════╝██╔═██╗ ██║ ██║ ╚════██║
|
14
|
+
███████╗██║ ██║ ███████╗ ██║ ██╗██║ ██║ ███████║
|
15
|
+
╚══════╝╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝
|
16
|
+
"""
|
17
|
+
|
18
|
+
TAGLINE = "Lightweight enhancement kits for spec-driven development."
|
19
|
+
|
20
|
+
RAINBOW_STOPS = [
|
21
|
+
(255, 0, 0), # Red
|
22
|
+
(255, 127, 0), # Orange
|
23
|
+
(255, 255, 0), # Yellow
|
24
|
+
(0, 255, 0), # Green
|
25
|
+
(0, 0, 255), # Blue
|
26
|
+
(75, 0, 130), # Indigo
|
27
|
+
(148, 0, 211), # Violet
|
28
|
+
(255, 105, 180), # Pink
|
29
|
+
]
|
30
|
+
|
31
|
+
def interpolate_multi_color(stops, steps):
|
32
|
+
gradient = []
|
33
|
+
n_segments = len(stops) - 1
|
34
|
+
steps_per_segment = steps // n_segments
|
35
|
+
for i in range(n_segments):
|
36
|
+
start = stops[i]
|
37
|
+
end = stops[i+1]
|
38
|
+
for j in range(steps_per_segment):
|
39
|
+
t = j / steps_per_segment
|
40
|
+
r = int(start[0] + (end[0] - start[0]) * t)
|
41
|
+
g = int(start[1] + (end[1] - start[1]) * t)
|
42
|
+
b = int(start[2] + (end[2] - start[2]) * t)
|
43
|
+
gradient.append(f"#{r:02X}{g:02X}{b:02X}")
|
44
|
+
gradient.append(f"#{stops[-1][0]:02X}{stops[-1][1]:02X}{stops[-1][2]:02X}")
|
45
|
+
return gradient
|
46
|
+
|
47
|
+
def get_diagonal_steps(text=BANNER):
|
48
|
+
lines = text.strip().split('\n')
|
49
|
+
height = len(lines)
|
50
|
+
width = max(len(line) for line in lines)
|
51
|
+
return height + width - 2
|
52
|
+
|
53
|
+
def apply_diagonal_gradient(text=BANNER, offset=0, steps_override=None):
|
54
|
+
lines = text.strip().split('\n')
|
55
|
+
height = len(lines)
|
56
|
+
width = max(len(line) for line in lines)
|
57
|
+
steps = steps_override if steps_override else height + width - 2
|
58
|
+
gradient = interpolate_multi_color(RAINBOW_STOPS, steps + 1)
|
59
|
+
result = Text()
|
60
|
+
for line_idx, line in enumerate(lines):
|
61
|
+
for char_idx, char in enumerate(line):
|
62
|
+
diag_idx = line_idx + char_idx + offset
|
63
|
+
color_idx = min(diag_idx, len(gradient) - 1)
|
64
|
+
color = gradient[color_idx]
|
65
|
+
result.append(char, style=f"bold {color}")
|
66
|
+
result.append('\n')
|
67
|
+
return result
|
68
|
+
|
69
|
+
def typewriter_effect(text=TAGLINE, delay=0.02, cursor_blink_rate=0.4, blink_cycles=2):
|
70
|
+
"""Display retro terminal typewriter animation with dim text via ANSI codes."""
|
71
|
+
DIM = '\033[2m'
|
72
|
+
RESET = '\033[0m'
|
73
|
+
for i in range(len(text) + 1):
|
74
|
+
sys.stdout.write('\r' + DIM + text[:i] + RESET)
|
75
|
+
sys.stdout.flush()
|
76
|
+
time.sleep(delay)
|
77
|
+
for _ in range(blink_cycles):
|
78
|
+
sys.stdout.write('\r' + DIM + text + '█' + RESET)
|
79
|
+
sys.stdout.flush()
|
80
|
+
time.sleep(cursor_blink_rate)
|
81
|
+
sys.stdout.write('\r' + DIM + text + ' ' + RESET)
|
82
|
+
sys.stdout.flush()
|
83
|
+
time.sleep(cursor_blink_rate)
|
84
|
+
sys.stdout.write('\n')
|
85
|
+
|
86
|
+
|
87
|
+
def diagonal_reveal_banner(text=BANNER, steps_override=None, fps=56):
|
88
|
+
"""Reveal the banner diagonally from top-left to bottom-right, with gradient following the reveal."""
|
89
|
+
console.print()
|
90
|
+
lines = text.strip().split('\n')
|
91
|
+
height = len(lines)
|
92
|
+
width = max(len(line) for line in lines)
|
93
|
+
steps = steps_override if steps_override else height + width - 2
|
94
|
+
gradient = interpolate_multi_color(RAINBOW_STOPS, steps + 1)
|
95
|
+
|
96
|
+
# Prepare a matrix of characters and their diagonal indices
|
97
|
+
char_matrix = []
|
98
|
+
diag_indices = []
|
99
|
+
for line_idx, line in enumerate(lines):
|
100
|
+
row = []
|
101
|
+
diag_row = []
|
102
|
+
for char_idx, char in enumerate(line):
|
103
|
+
row.append(char)
|
104
|
+
diag_row.append(line_idx + char_idx)
|
105
|
+
char_matrix.append(row)
|
106
|
+
diag_indices.append(diag_row)
|
107
|
+
|
108
|
+
# Reveal animation
|
109
|
+
try:
|
110
|
+
with Live(console=console, refresh_per_second=fps, transient=True) as live:
|
111
|
+
for reveal_diag in range(steps + 1):
|
112
|
+
result = Text()
|
113
|
+
for line_idx, row in enumerate(char_matrix):
|
114
|
+
for char_idx, char in enumerate(row):
|
115
|
+
diag_idx = diag_indices[line_idx][char_idx]
|
116
|
+
if diag_idx <= reveal_diag:
|
117
|
+
color = gradient[min(diag_idx, len(gradient)-1)]
|
118
|
+
result.append(char, style=f"bold {color}")
|
119
|
+
else:
|
120
|
+
result.append(" ")
|
121
|
+
result.append('\n')
|
122
|
+
live.update(result)
|
123
|
+
time.sleep(1.0 / fps)
|
124
|
+
except KeyboardInterrupt:
|
125
|
+
pass
|
126
|
+
|
127
|
+
# Show final static gradient
|
128
|
+
result = Text()
|
129
|
+
for line_idx, row in enumerate(char_matrix):
|
130
|
+
for char_idx, char in enumerate(row):
|
131
|
+
diag_idx = diag_indices[line_idx][char_idx]
|
132
|
+
color = gradient[min(diag_idx, len(gradient)-1)]
|
133
|
+
result.append(char, style=f"bold {color}")
|
134
|
+
result.append('\n')
|
135
|
+
console.print(result)
|
136
|
+
typewriter_effect()
|
137
|
+
|
138
|
+
def show_static_banner():
|
139
|
+
console.print()
|
140
|
+
steps = get_diagonal_steps()
|
141
|
+
gradient_text = apply_diagonal_gradient(offset=0, steps_override=steps)
|
142
|
+
console.print(gradient_text)
|
143
|
+
console.print(f"{TAGLINE}", style="dim")
|
144
|
+
|
145
|
+
def show_loading_spinner(message="Loading kits..."):
|
146
|
+
with console.status(f"[bold bright_cyan]{message}", spinner="dots"):
|
147
|
+
time.sleep(1.5)
|
148
|
+
console.print("[green]✓ Done![/green]")
|
149
|
+
|
150
|
+
if __name__ == "__main__":
|
151
|
+
console.clear()
|
152
|
+
console.print("[bold yellow]\nDemo 1: Loading Spinner[/bold yellow]\n")
|
153
|
+
show_loading_spinner()
|
154
|
+
time.sleep(1)
|
155
|
+
console.print("[bold yellow]Demo 2: Diagonal Reveal Animation[/bold yellow]\n")
|
156
|
+
diagonal_reveal_banner()
|
157
|
+
time.sleep(1)
|
158
|
+
console.print("[bold yellow]Demo 3: Status Banner[/bold yellow]\n")
|
159
|
+
show_static_banner()
|
160
|
+
console.print()
|
@@ -21,22 +21,16 @@ class Installer:
|
|
21
21
|
kits: List of kits to install (project, git, multiagent). Defaults to ['project']
|
22
22
|
"""
|
23
23
|
self.target_dir = Path(target_dir).resolve()
|
24
|
-
self.kits_dir = Path(__file__).parent / "kits"
|
25
|
-
self.kits = kits or ['
|
24
|
+
self.kits_dir = Path(__file__).parent.parent / "kits"
|
25
|
+
self.kits = kits or ['dev'] # Default to dev kit only
|
26
26
|
|
27
27
|
# Validate kit names
|
28
|
-
valid_kits = {'
|
28
|
+
valid_kits = {'dev', 'multiagent'}
|
29
29
|
invalid = set(self.kits) - valid_kits
|
30
30
|
if invalid:
|
31
31
|
raise ValueError(f"Invalid kit(s): {invalid}. Valid: {valid_kits}")
|
32
32
|
|
33
|
-
#
|
34
|
-
# multiagent requires both project and git
|
35
|
-
if 'multiagent' in self.kits:
|
36
|
-
if 'project' not in self.kits:
|
37
|
-
self.kits.append('project')
|
38
|
-
if 'git' not in self.kits:
|
39
|
-
self.kits.append('git')
|
33
|
+
# No auto-dependencies - all kits are independent
|
40
34
|
|
41
35
|
def is_spec_kit_project(self) -> bool:
|
42
36
|
"""
|
@@ -68,6 +62,7 @@ class Installer:
|
|
68
62
|
'git': [
|
69
63
|
self.target_dir / ".claude" / "commands" / "commit.md",
|
70
64
|
self.target_dir / ".github" / "prompts" / "commit.prompt.md",
|
65
|
+
self.target_dir / ".claude" / "commands" / "review.md",
|
71
66
|
],
|
72
67
|
'multiagent': [
|
73
68
|
self.target_dir / ".specify" / "memory" / "pr-workflow-guide.md",
|
@@ -101,18 +96,30 @@ class Installer:
|
|
101
96
|
# Project kit files
|
102
97
|
if 'project' in self.kits:
|
103
98
|
if has_claude:
|
104
|
-
changes["new_files"].
|
99
|
+
changes["new_files"].extend([
|
100
|
+
".claude/commands/orient.md",
|
101
|
+
".claude/commands/review.md",
|
102
|
+
".claude/commands/audit.md",
|
103
|
+
".claude/commands/stats.md",
|
104
|
+
])
|
105
105
|
if has_copilot:
|
106
|
-
changes["new_files"].
|
106
|
+
changes["new_files"].extend([
|
107
|
+
".github/prompts/orient.prompt.md",
|
108
|
+
".github/prompts/review.prompt.md",
|
109
|
+
".github/prompts/audit.prompt.md",
|
110
|
+
".github/prompts/stats.prompt.md",
|
111
|
+
])
|
107
112
|
|
108
113
|
# Git kit files
|
109
114
|
if 'git' in self.kits:
|
110
115
|
if has_claude:
|
111
116
|
changes["new_files"].append(".claude/commands/commit.md")
|
112
117
|
changes["new_files"].append(".claude/commands/pr.md")
|
118
|
+
changes["new_files"].append(".claude/commands/review.md")
|
113
119
|
if has_copilot:
|
114
120
|
changes["new_files"].append(".github/prompts/commit.prompt.md")
|
115
121
|
changes["new_files"].append(".github/prompts/pr.prompt.md")
|
122
|
+
changes["new_files"].append(".github/prompts/review.prompt.md")
|
116
123
|
|
117
124
|
# Multiagent kit files
|
118
125
|
if 'multiagent' in self.kits and (self.target_dir / ".specify").exists():
|
@@ -150,25 +157,33 @@ class Installer:
|
|
150
157
|
if 'project' in self.kits:
|
151
158
|
if has_claude:
|
152
159
|
self._install_file('project/claude/commands/orient.md', '.claude/commands/orient.md')
|
153
|
-
|
160
|
+
self._install_file('project/claude/commands/review.md', '.claude/commands/review.md')
|
161
|
+
self._install_file('project/claude/commands/audit.md', '.claude/commands/audit.md')
|
162
|
+
self._install_file('project/claude/commands/stats.md', '.claude/commands/stats.md')
|
163
|
+
result["installed"].append("project-kit (Claude): /orient, /review, /audit, /stats commands")
|
154
164
|
|
155
165
|
if has_copilot:
|
156
166
|
self._install_file('project/github/prompts/orient.prompt.md', '.github/prompts/orient.prompt.md')
|
157
|
-
|
167
|
+
self._install_file('project/github/prompts/review.prompt.md', '.github/prompts/review.prompt.md')
|
168
|
+
self._install_file('project/github/prompts/audit.prompt.md', '.github/prompts/audit.prompt.md')
|
169
|
+
self._install_file('project/github/prompts/stats.prompt.md', '.github/prompts/stats.prompt.md')
|
170
|
+
result["installed"].append("project-kit (Copilot): /orient, /review, /audit, /stats commands")
|
158
171
|
|
159
172
|
# Install git kit
|
160
173
|
if 'git' in self.kits:
|
161
174
|
if has_claude:
|
162
175
|
self._install_file('git/claude/commands/commit.md', '.claude/commands/commit.md')
|
163
176
|
self._install_file('git/claude/commands/pr.md', '.claude/commands/pr.md')
|
177
|
+
self._install_file('git/claude/commands/review.md', '.claude/commands/review.md')
|
164
178
|
self._install_file('git/claude/commands/cleanup.md', '.claude/commands/cleanup.md')
|
165
|
-
result["installed"].append("git-kit (Claude): /commit, /pr, /cleanup commands")
|
179
|
+
result["installed"].append("git-kit (Claude): /commit, /pr, /review, /cleanup commands")
|
166
180
|
|
167
181
|
if has_copilot:
|
168
182
|
self._install_file('git/github/prompts/commit.prompt.md', '.github/prompts/commit.prompt.md')
|
169
183
|
self._install_file('git/github/prompts/pr.prompt.md', '.github/prompts/pr.prompt.md')
|
184
|
+
self._install_file('git/github/prompts/review.prompt.md', '.github/prompts/review.prompt.md')
|
170
185
|
self._install_file('git/github/prompts/cleanup.prompt.md', '.github/prompts/cleanup.prompt.md')
|
171
|
-
result["installed"].append("git-kit (Copilot): /commit, /pr, /cleanup commands")
|
186
|
+
result["installed"].append("git-kit (Copilot): /commit, /pr, /review, /cleanup commands")
|
172
187
|
|
173
188
|
# Install multiagent kit
|
174
189
|
if 'multiagent' in self.kits and (self.target_dir / ".specify").exists():
|
@@ -225,12 +240,13 @@ class Installer:
|
|
225
240
|
# Check git-kit files
|
226
241
|
claude_commit = self.target_dir / ".claude" / "commands" / "commit.md"
|
227
242
|
claude_pr = self.target_dir / ".claude" / "commands" / "pr.md"
|
243
|
+
claude_review = self.target_dir / ".claude" / "commands" / "review.md"
|
228
244
|
claude_cleanup = self.target_dir / ".claude" / "commands" / "cleanup.md"
|
229
245
|
|
230
|
-
git_kit_installed = claude_commit.exists() or claude_pr.exists() or claude_cleanup.exists()
|
246
|
+
git_kit_installed = claude_commit.exists() or claude_pr.exists() or claude_review.exists() or claude_cleanup.exists()
|
231
247
|
checks["git_kit"] = {
|
232
248
|
"passed": git_kit_installed,
|
233
|
-
"message": "git-kit: /commit, /pr, /cleanup commands found" if git_kit_installed
|
249
|
+
"message": "git-kit: /commit, /pr, /review, /cleanup commands found" if git_kit_installed
|
234
250
|
else "git-kit not installed - run: lite-kits add --here --kit git",
|
235
251
|
}
|
236
252
|
|
@@ -326,17 +342,21 @@ class Installer:
|
|
326
342
|
# Remove project kit files
|
327
343
|
if 'project' in self.kits:
|
328
344
|
removed = []
|
345
|
+
project_commands = ['orient', 'review', 'audit', 'stats']
|
346
|
+
|
329
347
|
# Claude
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
348
|
+
for cmd in project_commands:
|
349
|
+
cmd_file = self.target_dir / ".claude" / "commands" / f"{cmd}.md"
|
350
|
+
if cmd_file.exists():
|
351
|
+
cmd_file.unlink()
|
352
|
+
removed.append(f".claude/commands/{cmd}.md")
|
334
353
|
|
335
354
|
# Copilot
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
355
|
+
for cmd in project_commands:
|
356
|
+
cmd_file = self.target_dir / ".github" / "prompts" / f"{cmd}.prompt.md"
|
357
|
+
if cmd_file.exists():
|
358
|
+
cmd_file.unlink()
|
359
|
+
removed.append(f".github/prompts/{cmd}.prompt.md")
|
340
360
|
|
341
361
|
if removed:
|
342
362
|
result["removed"].append(f"project-kit: {', '.join(removed)}")
|
@@ -344,7 +364,7 @@ class Installer:
|
|
344
364
|
# Remove git kit files
|
345
365
|
if 'git' in self.kits:
|
346
366
|
removed = []
|
347
|
-
git_commands = ['commit', 'pr', 'cleanup']
|
367
|
+
git_commands = ['commit', 'pr', 'review', 'cleanup']
|
348
368
|
|
349
369
|
# Claude
|
350
370
|
for cmd in git_commands:
|
@@ -0,0 +1,146 @@
|
|
1
|
+
"""
|
2
|
+
Kit manifest loader and utilities.
|
3
|
+
|
4
|
+
Loads kit definitions from kits.yaml and provides helpers for installation,
|
5
|
+
validation, and status checking.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from pathlib import Path
|
9
|
+
from typing import Dict, List, Optional
|
10
|
+
import yaml
|
11
|
+
|
12
|
+
|
13
|
+
class KitManifest:
|
14
|
+
"""Loads and provides access to kit definitions from kits.yaml"""
|
15
|
+
|
16
|
+
def __init__(self, kits_dir: Path):
|
17
|
+
"""
|
18
|
+
Initialize manifest loader.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
kits_dir: Path to kits directory containing kits.yaml
|
22
|
+
"""
|
23
|
+
self.kits_dir = kits_dir
|
24
|
+
self.manifest_path = kits_dir / "kits.yaml"
|
25
|
+
self._manifest = None
|
26
|
+
|
27
|
+
@property
|
28
|
+
def manifest(self) -> Dict:
|
29
|
+
"""Load and cache manifest data"""
|
30
|
+
if self._manifest is None:
|
31
|
+
with open(self.manifest_path) as f:
|
32
|
+
self._manifest = yaml.safe_load(f)
|
33
|
+
return self._manifest
|
34
|
+
|
35
|
+
def get_kit(self, kit_name: str) -> Optional[Dict]:
|
36
|
+
"""Get kit definition by name"""
|
37
|
+
return self.manifest['kits'].get(kit_name)
|
38
|
+
|
39
|
+
def get_all_kits(self) -> Dict[str, Dict]:
|
40
|
+
"""Get all kit definitions"""
|
41
|
+
return self.manifest['kits']
|
42
|
+
|
43
|
+
def get_kit_names(self) -> List[str]:
|
44
|
+
"""Get list of all kit names"""
|
45
|
+
return list(self.manifest['kits'].keys())
|
46
|
+
|
47
|
+
def get_recommended_kits(self) -> List[str]:
|
48
|
+
"""Get list of recommended kit names"""
|
49
|
+
return [
|
50
|
+
name for name, kit in self.manifest['kits'].items()
|
51
|
+
if kit.get('recommended', False)
|
52
|
+
]
|
53
|
+
|
54
|
+
def get_default_kit(self) -> str:
|
55
|
+
"""Get default kit name"""
|
56
|
+
return self.manifest['options']['default_kit']
|
57
|
+
|
58
|
+
def get_kit_files(self, kit_name: str, agent: Optional[str] = None) -> List[Dict]:
|
59
|
+
"""
|
60
|
+
Get list of files for a kit.
|
61
|
+
|
62
|
+
Args:
|
63
|
+
kit_name: Name of kit
|
64
|
+
agent: Optional agent filter ('claude', 'copilot', None for all)
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
List of file dicts with 'path', 'source', 'required' keys
|
68
|
+
"""
|
69
|
+
kit = self.get_kit(kit_name)
|
70
|
+
if not kit:
|
71
|
+
return []
|
72
|
+
|
73
|
+
files = []
|
74
|
+
file_groups = kit.get('files', {})
|
75
|
+
|
76
|
+
# Map agent names to file groups
|
77
|
+
agent_groups = {
|
78
|
+
'claude': ['claude'],
|
79
|
+
'copilot': ['copilot'],
|
80
|
+
None: list(file_groups.keys()) # All groups
|
81
|
+
}
|
82
|
+
|
83
|
+
groups_to_include = agent_groups.get(agent, [])
|
84
|
+
|
85
|
+
for group_name in groups_to_include:
|
86
|
+
if group_name in file_groups:
|
87
|
+
files.extend(file_groups[group_name])
|
88
|
+
|
89
|
+
return files
|
90
|
+
|
91
|
+
def get_kit_markers(self, kit_name: str) -> List[str]:
|
92
|
+
"""
|
93
|
+
Get marker files for kit detection.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
kit_name: Name of kit
|
97
|
+
|
98
|
+
Returns:
|
99
|
+
List of marker file paths
|
100
|
+
"""
|
101
|
+
kit = self.get_kit(kit_name)
|
102
|
+
return kit.get('markers', []) if kit else []
|
103
|
+
|
104
|
+
def get_kit_commands(self, kit_name: str) -> List[Dict]:
|
105
|
+
"""
|
106
|
+
Get list of commands for a kit.
|
107
|
+
|
108
|
+
Args:
|
109
|
+
kit_name: Name of kit
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
List of command dicts with 'name', 'description', 'status' keys
|
113
|
+
"""
|
114
|
+
kit = self.get_kit(kit_name)
|
115
|
+
return kit.get('commands', []) if kit else []
|
116
|
+
|
117
|
+
def get_agent_config(self, agent: str) -> Optional[Dict]:
|
118
|
+
"""
|
119
|
+
Get agent configuration.
|
120
|
+
|
121
|
+
Args:
|
122
|
+
agent: Agent name ('claude', 'copilot')
|
123
|
+
|
124
|
+
Returns:
|
125
|
+
Agent config dict or None
|
126
|
+
"""
|
127
|
+
return self.manifest.get('agents', {}).get(agent)
|
128
|
+
|
129
|
+
def validate_kit_name(self, kit_name: str) -> bool:
|
130
|
+
"""Check if kit name is valid"""
|
131
|
+
return kit_name in self.get_kit_names()
|
132
|
+
|
133
|
+
def get_kit_description(self, kit_name: str) -> str:
|
134
|
+
"""Get kit description"""
|
135
|
+
kit = self.get_kit(kit_name)
|
136
|
+
return kit.get('description', '') if kit else ''
|
137
|
+
|
138
|
+
def get_kit_icon(self, kit_name: str) -> str:
|
139
|
+
"""Get kit icon emoji"""
|
140
|
+
kit = self.get_kit(kit_name)
|
141
|
+
return kit.get('icon', '📦') if kit else '📦'
|
142
|
+
|
143
|
+
def is_recommended(self, kit_name: str) -> bool:
|
144
|
+
"""Check if kit is recommended"""
|
145
|
+
kit = self.get_kit(kit_name)
|
146
|
+
return kit.get('recommended', False) if kit else False
|
lite_kits/kits/README.md
CHANGED
@@ -7,10 +7,10 @@ This directory contains modular add-on kits that can be installed independently
|
|
7
7
|
### ✅ Recommended (Default Installation)
|
8
8
|
|
9
9
|
#### 1. **project-kit**
|
10
|
-
**Commands**: `/orient` ⭐, `/
|
10
|
+
**Commands**: `/orient` ⭐, `/audit`, `/stats`
|
11
11
|
**Scripts**: Enhanced feature creation with custom naming
|
12
12
|
|
13
|
-
Essential project-level utilities combining agent orientation,
|
13
|
+
Essential project-level utilities combining agent orientation, quality checks, and vanilla spec-kit enhancements.
|
14
14
|
|
15
15
|
**Installs to**:
|
16
16
|
- `.claude/commands/` (Claude Code)
|
@@ -22,9 +22,9 @@ Essential project-level utilities combining agent orientation, code quality chec
|
|
22
22
|
---
|
23
23
|
|
24
24
|
#### 2. **git-kit**
|
25
|
-
**Commands**: `/commit`, `/pr`, `/sync`, `/cleanup`
|
25
|
+
**Commands**: `/commit`, `/pr`, `/review`, `/sync`, `/cleanup`
|
26
26
|
|
27
|
-
Git workflow automation with smart commits, PR creation, sync status, and cleanup operations. Includes ASCII visualization for better readability.
|
27
|
+
Git workflow automation with smart commits, PR creation, code review, sync status, and cleanup operations. Includes ASCII visualization for better readability.
|
28
28
|
|
29
29
|
**Installs to**:
|
30
30
|
- `.claude/commands/` (Claude Code)
|
@@ -41,14 +41,14 @@ Git workflow automation with smart commits, PR creation, sync status, and cleanu
|
|
41
41
|
|
42
42
|
Multi-agent coordination structure for complex projects with multiple AI agents working in parallel.
|
43
43
|
|
44
|
-
**Dependencies**:
|
44
|
+
**Dependencies**: None (standalone)
|
45
45
|
|
46
46
|
**Installs to**:
|
47
47
|
- `.specify/memory/pr-workflow-guide.md`
|
48
48
|
- `.specify/memory/git-worktrees-protocol.md`
|
49
49
|
- `specs/*/collaboration/` (template, created per-feature)
|
50
50
|
|
51
|
-
**Use case**: Large projects with multiple AI agents collaborating (e.g., Claude Code + Copilot).
|
51
|
+
**Use case**: Large projects with multiple AI agents collaborating (e.g., Claude Code + Copilot). Works best when combined with project-kit and git-kit.
|
52
52
|
|
53
53
|
---
|
54
54
|
|
@@ -56,9 +56,9 @@ Multi-agent coordination structure for complex projects with multiple AI agents
|
|
56
56
|
|
57
57
|
| Kit | Default | Target Users | Adds | Dependencies |
|
58
58
|
|-----|---------|--------------|------|--------------|
|
59
|
-
| **project** | ✅ Yes | Everyone |
|
59
|
+
| **project** | ✅ Yes | Everyone | 3 commands + enhanced scripts | None |
|
60
60
|
| **git** | ✅ Yes | Everyone | 4 commands with ASCII viz | None |
|
61
|
-
| **multiagent** | ❌ No | Multi-agent projects | Collaboration structure |
|
61
|
+
| **multiagent** | ❌ No | Multi-agent projects | Collaboration structure + /sync | None |
|
62
62
|
|
63
63
|
## Kit Structure
|
64
64
|
|
@@ -144,7 +144,6 @@ lite-kits remove -Kit git,project
|
|
144
144
|
| Command | Description |
|
145
145
|
|---------|-------------|
|
146
146
|
| `/orient` | Agent orientation (read docs, check git, determine role) |
|
147
|
-
| `/review` | Code review against constitution and best practices |
|
148
147
|
| `/audit` | Security and quality audit |
|
149
148
|
| `/stats` | Project statistics (LOC, test coverage, complexity) |
|
150
149
|
|
@@ -154,7 +153,7 @@ lite-kits remove -Kit git,project
|
|
154
153
|
|---------|-------------|
|
155
154
|
| `/commit` | Smart commit with agent attribution |
|
156
155
|
| `/pr` | Create pull request with auto-generated description |
|
157
|
-
| `/
|
156
|
+
| `/review` | Code review of staged changes against best practices |
|
158
157
|
| `/cleanup` | Clean merged branches, stale worktrees |
|
159
158
|
|
160
159
|
### project-kit Enhancements
|