-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathinstall_skill.py
More file actions
95 lines (77 loc) · 2.76 KB
/
Copy pathinstall_skill.py
File metadata and controls
95 lines (77 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python3
"""Install the bundled streamdeck-designer skill into ~/.claude/skills/.
The skill teaches Claude how to use the streamdeck-mcp tools to author complete,
themed Stream Deck layouts. Once installed, Claude Code auto-loads it when the
user's request matches its description (themed decks, service integrations,
per-hardware layouts).
Usage:
uv run python -m install_skill [--force]
streamdeck-mcp-install-skill [--force]
"""
from __future__ import annotations
import argparse
import shutil
import sys
from pathlib import Path
SKILL_NAME = "streamdeck-designer"
BUNDLED_SKILL_DIR = Path(__file__).parent / "streamdeck_assets" / "skill" / SKILL_NAME
SKILLS_ROOT = Path.home() / ".claude" / "skills"
def install(force: bool = False) -> dict[str, str | bool]:
"""Copy the bundled skill to ~/.claude/skills/streamdeck-designer/.
Returns a dict describing the action taken.
"""
if not BUNDLED_SKILL_DIR.is_dir():
return {
"installed": False,
"error": f"bundled skill not found at {BUNDLED_SKILL_DIR}",
}
target = SKILLS_ROOT / SKILL_NAME
if target.exists() and not force:
return {
"installed": False,
"path": str(target),
"message": (
f"{SKILL_NAME} already installed at {target}. "
"Pass --force (or force=True) to overwrite."
),
}
overwrote = False
if target.exists():
overwrote = True
shutil.rmtree(target)
SKILLS_ROOT.mkdir(parents=True, exist_ok=True)
shutil.copytree(BUNDLED_SKILL_DIR, target)
message = f"Installed {SKILL_NAME} to {target}."
if overwrote:
message = (
f"Overwrote existing {SKILL_NAME} at {target} with the bundled "
"version — any local edits to that directory are gone."
)
message += " Restart Claude Code (or start a new session) for the skill to load."
return {
"installed": True,
"path": str(target),
"overwrote": overwrote,
"message": message,
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument(
"--force",
action="store_true",
help=(
"Overwrite an existing installation. DESTRUCTIVE: removes the "
"target directory and replaces it with the bundled skill. Any "
"local edits you made under ~/.claude/skills/streamdeck-designer/ "
"will be lost."
),
)
args = parser.parse_args()
result = install(force=args.force)
if "error" in result:
print(f"error: {result['error']}", file=sys.stderr)
return 1
print(result["message"])
return 0
if __name__ == "__main__":
sys.exit(main())