agr 0.4.0__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.
- agr/__init__.py +3 -0
- agr/cli/__init__.py +5 -0
- agr/cli/add.py +132 -0
- agr/cli/common.py +1085 -0
- agr/cli/init.py +292 -0
- agr/cli/main.py +34 -0
- agr/cli/remove.py +125 -0
- agr/cli/run.py +385 -0
- agr/cli/sync.py +263 -0
- agr/cli/update.py +140 -0
- agr/config.py +187 -0
- agr/exceptions.py +33 -0
- agr/fetcher.py +781 -0
- agr/github.py +95 -0
- agr/scaffold.py +194 -0
- agr-0.4.0.dist-info/METADATA +17 -0
- agr-0.4.0.dist-info/RECORD +19 -0
- agr-0.4.0.dist-info/WHEEL +4 -0
- agr-0.4.0.dist-info/entry_points.txt +3 -0
agr/github.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""GitHub CLI integration for creating and pushing repositories."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def check_gh_cli() -> bool:
|
|
8
|
+
"""Check if GitHub CLI is available and authenticated.
|
|
9
|
+
|
|
10
|
+
Returns True if gh CLI is installed and authenticated, False otherwise.
|
|
11
|
+
"""
|
|
12
|
+
try:
|
|
13
|
+
result = subprocess.run(
|
|
14
|
+
["gh", "auth", "status"],
|
|
15
|
+
capture_output=True,
|
|
16
|
+
text=True,
|
|
17
|
+
timeout=30,
|
|
18
|
+
)
|
|
19
|
+
return result.returncode == 0
|
|
20
|
+
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
21
|
+
return False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_github_username() -> str | None:
|
|
25
|
+
"""Get the authenticated GitHub username.
|
|
26
|
+
|
|
27
|
+
Returns the username if authenticated, None otherwise.
|
|
28
|
+
"""
|
|
29
|
+
try:
|
|
30
|
+
result = subprocess.run(
|
|
31
|
+
["gh", "api", "user", "--jq", ".login"],
|
|
32
|
+
capture_output=True,
|
|
33
|
+
text=True,
|
|
34
|
+
check=True,
|
|
35
|
+
timeout=30,
|
|
36
|
+
)
|
|
37
|
+
return result.stdout.strip()
|
|
38
|
+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def create_github_repo(path: Path, repo_name: str = "agent-resources") -> str | None:
|
|
43
|
+
"""Create a GitHub repository and push the local repo.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
path: Path to the local git repository
|
|
47
|
+
repo_name: Name for the GitHub repository (default: agent-resources)
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
The GitHub repo URL if successful, None otherwise.
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
# Create repo on GitHub (public by default)
|
|
54
|
+
subprocess.run(
|
|
55
|
+
[
|
|
56
|
+
"gh",
|
|
57
|
+
"repo",
|
|
58
|
+
"create",
|
|
59
|
+
repo_name,
|
|
60
|
+
"--public",
|
|
61
|
+
"--source",
|
|
62
|
+
str(path),
|
|
63
|
+
"--push",
|
|
64
|
+
],
|
|
65
|
+
capture_output=True,
|
|
66
|
+
text=True,
|
|
67
|
+
check=True,
|
|
68
|
+
timeout=120,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Construct URL from username
|
|
72
|
+
username = get_github_username()
|
|
73
|
+
if username:
|
|
74
|
+
return f"https://github.com/{username}/{repo_name}"
|
|
75
|
+
|
|
76
|
+
return None
|
|
77
|
+
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def repo_exists(repo_name: str = "agent-resources") -> bool:
|
|
82
|
+
"""Check if a repository with the given name already exists.
|
|
83
|
+
|
|
84
|
+
Returns True if the repo exists, False otherwise.
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
result = subprocess.run(
|
|
88
|
+
["gh", "repo", "view", repo_name],
|
|
89
|
+
capture_output=True,
|
|
90
|
+
text=True,
|
|
91
|
+
timeout=30,
|
|
92
|
+
)
|
|
93
|
+
return result.returncode == 0
|
|
94
|
+
except (FileNotFoundError, subprocess.TimeoutExpired):
|
|
95
|
+
return False
|
agr/scaffold.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Scaffolding functions for creating agent-resources repository structure."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
HELLO_SKILL = """\
|
|
7
|
+
---
|
|
8
|
+
name: hello-world
|
|
9
|
+
description: A simple example skill that demonstrates Claude Code skill structure
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Hello World Skill
|
|
13
|
+
|
|
14
|
+
This is a demonstration skill showing how skills work.
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
Apply this skill when the user asks you to say hello or demonstrate skills.
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
Respond with a friendly greeting explaining this came from a skill.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
HELLO_COMMAND = """\
|
|
26
|
+
---
|
|
27
|
+
description: Say hello - example slash command
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
When the user runs /hello, respond with a friendly greeting.
|
|
31
|
+
Explain that this is an example command from their agent-resources repo.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
HELLO_AGENT = """\
|
|
35
|
+
---
|
|
36
|
+
description: Example subagent that greets users
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
You are a friendly greeter subagent.
|
|
40
|
+
When invoked, introduce yourself and explain that you're an example agent
|
|
41
|
+
from the user's agent-resources repository.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
README_TEMPLATE = """\
|
|
45
|
+
# agent-resources
|
|
46
|
+
|
|
47
|
+
My personal collection of Claude Code skills, commands, and agents.
|
|
48
|
+
|
|
49
|
+
## Structure
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
.claude/
|
|
53
|
+
├── skills/ # Skill directories with SKILL.md
|
|
54
|
+
├── commands/ # Slash command .md files
|
|
55
|
+
└── agents/ # Subagent .md files
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
Others can install my resources using:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Install a skill
|
|
64
|
+
agr add skill {username}/hello-world
|
|
65
|
+
|
|
66
|
+
# Install a command
|
|
67
|
+
agr add command {username}/hello
|
|
68
|
+
|
|
69
|
+
# Install an agent
|
|
70
|
+
agr add agent {username}/hello-agent
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Adding Resources
|
|
74
|
+
|
|
75
|
+
- **Skills**: Create a directory in `.claude/skills/<name>/` with a `SKILL.md` file
|
|
76
|
+
- **Commands**: Create a `.md` file in `.claude/commands/`
|
|
77
|
+
- **Agents**: Create a `.md` file in `.claude/agents/`
|
|
78
|
+
|
|
79
|
+
## Learn More
|
|
80
|
+
|
|
81
|
+
- [agent-resources documentation](https://github.com/kasperjunge/agent-resources)
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
GITIGNORE = """\
|
|
85
|
+
# Python
|
|
86
|
+
__pycache__/
|
|
87
|
+
*.py[cod]
|
|
88
|
+
*$py.class
|
|
89
|
+
.env
|
|
90
|
+
.venv/
|
|
91
|
+
venv/
|
|
92
|
+
|
|
93
|
+
# OS
|
|
94
|
+
.DS_Store
|
|
95
|
+
Thumbs.db
|
|
96
|
+
|
|
97
|
+
# IDE
|
|
98
|
+
.idea/
|
|
99
|
+
.vscode/
|
|
100
|
+
*.swp
|
|
101
|
+
*.swo
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def scaffold_repo(path: Path) -> None:
|
|
106
|
+
"""Create the complete agent-resources directory structure."""
|
|
107
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
108
|
+
|
|
109
|
+
# Create .claude directory structure
|
|
110
|
+
claude_dir = path / ".claude"
|
|
111
|
+
(claude_dir / "skills" / "hello-world").mkdir(parents=True, exist_ok=True)
|
|
112
|
+
(claude_dir / "commands").mkdir(parents=True, exist_ok=True)
|
|
113
|
+
(claude_dir / "agents").mkdir(parents=True, exist_ok=True)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def write_starter_skill(path: Path) -> None:
|
|
117
|
+
"""Write the hello-world example skill."""
|
|
118
|
+
skill_path = path / ".claude" / "skills" / "hello-world" / "SKILL.md"
|
|
119
|
+
skill_path.write_text(HELLO_SKILL)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def write_starter_command(path: Path) -> None:
|
|
123
|
+
"""Write the hello example command."""
|
|
124
|
+
command_path = path / ".claude" / "commands" / "hello.md"
|
|
125
|
+
command_path.write_text(HELLO_COMMAND)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def write_starter_agent(path: Path) -> None:
|
|
129
|
+
"""Write the hello-agent example agent."""
|
|
130
|
+
agent_path = path / ".claude" / "agents" / "hello-agent.md"
|
|
131
|
+
agent_path.write_text(HELLO_AGENT)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def write_readme(path: Path, username: str = "<username>", overwrite: bool = False) -> bool:
|
|
135
|
+
"""Write the README.md file.
|
|
136
|
+
|
|
137
|
+
Returns True if file was written, False if skipped.
|
|
138
|
+
"""
|
|
139
|
+
readme_path = path / "README.md"
|
|
140
|
+
if readme_path.exists() and not overwrite:
|
|
141
|
+
return False
|
|
142
|
+
readme_path.write_text(README_TEMPLATE.format(username=username))
|
|
143
|
+
return True
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def write_gitignore(path: Path, overwrite: bool = False) -> bool:
|
|
147
|
+
"""Write the .gitignore file.
|
|
148
|
+
|
|
149
|
+
Returns True if file was written, False if skipped.
|
|
150
|
+
"""
|
|
151
|
+
gitignore_path = path / ".gitignore"
|
|
152
|
+
if gitignore_path.exists() and not overwrite:
|
|
153
|
+
return False
|
|
154
|
+
gitignore_path.write_text(GITIGNORE)
|
|
155
|
+
return True
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def init_git(path: Path) -> bool:
|
|
159
|
+
"""Initialize git repository and create initial commit.
|
|
160
|
+
|
|
161
|
+
Returns True if successful, False otherwise.
|
|
162
|
+
"""
|
|
163
|
+
try:
|
|
164
|
+
subprocess.run(
|
|
165
|
+
["git", "init"],
|
|
166
|
+
cwd=path,
|
|
167
|
+
check=True,
|
|
168
|
+
capture_output=True,
|
|
169
|
+
)
|
|
170
|
+
subprocess.run(
|
|
171
|
+
["git", "add", "."],
|
|
172
|
+
cwd=path,
|
|
173
|
+
check=True,
|
|
174
|
+
capture_output=True,
|
|
175
|
+
)
|
|
176
|
+
subprocess.run(
|
|
177
|
+
["git", "commit", "-m", "Initial commit: agent-resources repo scaffold"],
|
|
178
|
+
cwd=path,
|
|
179
|
+
check=True,
|
|
180
|
+
capture_output=True,
|
|
181
|
+
)
|
|
182
|
+
return True
|
|
183
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def create_agent_resources_repo(path: Path, username: str = "<username>") -> None:
|
|
188
|
+
"""Create a complete agent-resources repository with all starter content."""
|
|
189
|
+
scaffold_repo(path)
|
|
190
|
+
write_starter_skill(path)
|
|
191
|
+
write_starter_command(path)
|
|
192
|
+
write_starter_agent(path)
|
|
193
|
+
write_readme(path, username)
|
|
194
|
+
write_gitignore(path)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agr
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Agent Resources - A package and project manager for AI agents.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: httpx>=0.27
|
|
8
|
+
Requires-Dist: rich>=13.0
|
|
9
|
+
Requires-Dist: tomlkit>=0.12
|
|
10
|
+
Requires-Dist: typer>=0.12
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# agr
|
|
14
|
+
|
|
15
|
+
Agent resources for Claude Code.
|
|
16
|
+
|
|
17
|
+
See [agent-resources](https://github.com/kasperjunge/agent-resources) for full documentation.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
agr/__init__.py,sha256=fYcMcp7MndFbZQ-2FMd1zbDp3BdXJusC77WGZeVl-n4,113
|
|
2
|
+
agr/config.py,sha256=V5VZzGFLkgxz_SyFzgHOW4OKBEow-Ehpqji9kHk7CZY,5090
|
|
3
|
+
agr/exceptions.py,sha256=CljTHgTAz1H8OzGnP_F1sceqwfUwOdPoFquGQ5bPZ28,836
|
|
4
|
+
agr/fetcher.py,sha256=-rEyhOInf4nhnP_-vZBPvkUQnyJDYdQdrGfA9P0o3lM,25493
|
|
5
|
+
agr/github.py,sha256=IMh5Hd0dc8etxlZC-0bp5i_Hz6UBz1l-KW2VdX_9QMA,2671
|
|
6
|
+
agr/scaffold.py,sha256=kJGUJbxEYZnk0KzGs24ZOj4mOk5Jv7xNdhmeFefaFVI,4805
|
|
7
|
+
agr/cli/__init__.py,sha256=WHqEa_48pzU8CxERRx-6I6pZNPVACq5kf03UwB6BCTc,75
|
|
8
|
+
agr/cli/add.py,sha256=Vt7x8Pj7n7kumcDCoFbav6HOpTDI3voL21pKojyvn9k,4307
|
|
9
|
+
agr/cli/common.py,sha256=cu89nI1-3UjQxrAljdPxoJzdkdv5lV8rE0iHPc_io6M,36835
|
|
10
|
+
agr/cli/init.py,sha256=_nINLB1VlEzlEUoVjCiyNmM0yrnLdq0Z0MAygA-UZfA,8113
|
|
11
|
+
agr/cli/main.py,sha256=Dv-e9STwHKSctaFqd7CHIrs4W9jzBAVH-t1uN-FYE7Q,778
|
|
12
|
+
agr/cli/remove.py,sha256=RSrUT01RbMFfS8ROsnZz3w07nu7tLVuRQGS4sF6PXKQ,4075
|
|
13
|
+
agr/cli/run.py,sha256=RZGnNnCcvYycZShAAkt-pJbe8MhIQo7znCgmiFDHuHk,13353
|
|
14
|
+
agr/cli/sync.py,sha256=PiOBYEC5IcUs9gm3te1rARAkhIdWGLtFaCTECN-RMfo,8276
|
|
15
|
+
agr/cli/update.py,sha256=pvdY9ojC7B6kb8nREBvHrEGTOrjquNxvRjPzL6Fj8zo,4119
|
|
16
|
+
agr-0.4.0.dist-info/METADATA,sha256=61fy56UUsEjJs9I3yafsMtK29VnHSMfr2DuMsusYfBs,452
|
|
17
|
+
agr-0.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
18
|
+
agr-0.4.0.dist-info/entry_points.txt,sha256=uaxLTUZsmwId9vBBeKWQoqIxS6gnpYxyBX2TfncEqIg,64
|
|
19
|
+
agr-0.4.0.dist-info/RECORD,,
|