python-skills 1.0.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.
- python_skills/__init__.py +10 -0
- python_skills/__main__.py +6 -0
- python_skills/adapters/__init__.py +48 -0
- python_skills/adapters/agent_skills.py +415 -0
- python_skills/adapters/aider_adapter.py +226 -0
- python_skills/adapters/base.py +153 -0
- python_skills/adapters/claude.py +474 -0
- python_skills/adapters/cline.py +332 -0
- python_skills/adapters/codex.py +24 -0
- python_skills/adapters/continue_adapter.py +198 -0
- python_skills/adapters/cursor.py +327 -0
- python_skills/adapters/gemini.py +26 -0
- python_skills/adapters/goose.py +26 -0
- python_skills/adapters/junie.py +25 -0
- python_skills/adapters/kiro.py +382 -0
- python_skills/adapters/opencode.py +27 -0
- python_skills/adapters/roo.py +25 -0
- python_skills/adapters/universal.py +203 -0
- python_skills/adapters/vscode.py +27 -0
- python_skills/adapters/windsurf.py +26 -0
- python_skills/adapters/zed.py +27 -0
- python_skills/cli.py +326 -0
- python_skills/config.py +160 -0
- python_skills/detector.py +152 -0
- python_skills/installer.py +163 -0
- python_skills/markers.py +115 -0
- python_skills/skills/__init__.py +14 -0
- python_skills/skills/loader.py +171 -0
- python_skills/skills/metadata.py +152 -0
- python_skills/skills/registry.py +101 -0
- python_skills/state.py +204 -0
- python_skills-1.0.0.dist-info/METADATA +99 -0
- python_skills-1.0.0.dist-info/RECORD +105 -0
- python_skills-1.0.0.dist-info/WHEEL +4 -0
- python_skills-1.0.0.dist-info/entry_points.txt +2 -0
- python_skills-1.0.0.dist-info/licenses/LICENSE +21 -0
- skills/advanced_python.md +239 -0
- skills/anti_patterns/index.md +406 -0
- skills/comprehensions.md +167 -0
- skills/control_flow.md +175 -0
- skills/data_structures.md +243 -0
- skills/debugging/common_bugs.md +222 -0
- skills/debugging/inspection_techniques.md +249 -0
- skills/debugging/root_cause.md +203 -0
- skills/engineering/application_logging.md +195 -0
- skills/engineering/cli_apps.md +207 -0
- skills/engineering/configuration.md +218 -0
- skills/engineering/database.md +240 -0
- skills/engineering/dependency_management.md +205 -0
- skills/engineering/http_clients.md +267 -0
- skills/engineering/modules_packages.md +211 -0
- skills/engineering/packaging.md +197 -0
- skills/engineering/project_structure.md +155 -0
- skills/engineering/pyproject_toml.md +302 -0
- skills/engineering/virtual_environments.md +206 -0
- skills/functions.md +244 -0
- skills/generation/async_concurrency.md +291 -0
- skills/generation/error_handling.md +276 -0
- skills/generation/protocols_generics.md +243 -0
- skills/generation/type_hints.md +290 -0
- skills/generation/validation_pipeline.md +274 -0
- skills/generation/workflow.md +190 -0
- skills/oop.md +228 -0
- skills/quality/abstractions.md +154 -0
- skills/quality/comments.md +177 -0
- skills/quality/documentation.md +176 -0
- skills/quality/duplication.md +137 -0
- skills/quality/maintainability.md +142 -0
- skills/quality/naming.md +171 -0
- skills/quality/quality_functions.md +245 -0
- skills/quality/readability.md +239 -0
- skills/quality/type_annotations.md +192 -0
- skills/refactoring/behavior_preservation.md +157 -0
- skills/refactoring/incremental.md +187 -0
- skills/refactoring/interface_stability.md +199 -0
- skills/refactoring/safe_refactoring.md +206 -0
- skills/security/auth_boundaries.md +200 -0
- skills/security/command_injection.md +207 -0
- skills/security/dependency_risks.md +282 -0
- skills/security/file_handling.md +156 -0
- skills/security/input_validation.md +190 -0
- skills/security/path_traversal.md +172 -0
- skills/security/secrets.md +171 -0
- skills/security/sql_injection.md +188 -0
- skills/security/unsafe_deserialization.md +164 -0
- skills/stdlib/argparse.md +178 -0
- skills/stdlib/collections.md +212 -0
- skills/stdlib/datetime.md +187 -0
- skills/stdlib/functools.md +238 -0
- skills/stdlib/itertools.md +183 -0
- skills/stdlib/json.md +162 -0
- skills/stdlib/logging.md +185 -0
- skills/stdlib/os_sys.md +184 -0
- skills/stdlib/pathlib.md +218 -0
- skills/stdlib/re.md +171 -0
- skills/stdlib/statistics.md +112 -0
- skills/stdlib/subprocess.md +211 -0
- skills/testing/async_tests.md +249 -0
- skills/testing/coverage.md +168 -0
- skills/testing/edge_cases.md +197 -0
- skills/testing/fixtures_mocks.md +203 -0
- skills/testing/organization.md +205 -0
- skills/testing/parameterized.md +174 -0
- skills/testing/regression_tests.md +165 -0
- skills/variables_types.md +107 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"""Cursor adapter for python-skills."""
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from ..adapters.base import (
|
|
7
|
+
AgentAdapter,
|
|
8
|
+
DetectionResult,
|
|
9
|
+
InstallResult,
|
|
10
|
+
StatusResult,
|
|
11
|
+
SyncResult,
|
|
12
|
+
UninstallResult,
|
|
13
|
+
)
|
|
14
|
+
from ..config import Target
|
|
15
|
+
from ..markers import BEGIN_MARKER, END_MARKER
|
|
16
|
+
from ..skills.registry import SkillRegistry
|
|
17
|
+
from ..state import LockManager
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CursorAdapter(AgentAdapter):
|
|
21
|
+
"""Adapter for Cursor."""
|
|
22
|
+
|
|
23
|
+
name = "Cursor"
|
|
24
|
+
target = Target.CURSOR.value
|
|
25
|
+
|
|
26
|
+
def __init__(self, project_root: Path, skills_registry: SkillRegistry, lock_manager: LockManager, config):
|
|
27
|
+
super().__init__(project_root, skills_registry, lock_manager, config)
|
|
28
|
+
|
|
29
|
+
def _get_global_path(self) -> Path:
|
|
30
|
+
"""Cursor global rules are stored in VS Code settings, not filesystem."""
|
|
31
|
+
return Path.home() / ".cursor" # Not actually used
|
|
32
|
+
|
|
33
|
+
def detect(self) -> DetectionResult:
|
|
34
|
+
"""Detect Cursor installation and configuration."""
|
|
35
|
+
# Check if cursor is in PATH
|
|
36
|
+
app_detected = shutil.which("cursor") is not None
|
|
37
|
+
|
|
38
|
+
# Check for project config
|
|
39
|
+
project_config = (self.project_root / ".cursor").exists() or (self.project_root / ".cursorrules").exists()
|
|
40
|
+
|
|
41
|
+
return DetectionResult(
|
|
42
|
+
application_detected=app_detected,
|
|
43
|
+
project_config_detected=project_config,
|
|
44
|
+
adapter_available=True,
|
|
45
|
+
details=f"App: {'yes' if app_detected else 'no'}, Project config: {'yes' if project_config else 'no'}, Global: N/A (UI only)"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def install(self, scope: str = "project", dry_run: bool = False) -> InstallResult:
|
|
49
|
+
"""Install python-skills for Cursor."""
|
|
50
|
+
result = InstallResult(success=True, target=self.target, scope=scope)
|
|
51
|
+
target_path = self._get_scope_path(scope)
|
|
52
|
+
|
|
53
|
+
if scope == "global":
|
|
54
|
+
result.success = False
|
|
55
|
+
result.errors.append("Cursor global installation not supported (User Rules are UI-only)")
|
|
56
|
+
return result
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
# Generate .cursor/rules/python-skills.mdc
|
|
60
|
+
rules_dir = target_path / ".cursor" / "rules"
|
|
61
|
+
rules_dir.mkdir(parents=True, exist_ok=True)
|
|
62
|
+
|
|
63
|
+
rule_path = rules_dir / "python-skills.mdc"
|
|
64
|
+
content = self._generate_cursor_rule()
|
|
65
|
+
|
|
66
|
+
if dry_run:
|
|
67
|
+
result.files_created.append(str(rule_path.relative_to(self.project_root)))
|
|
68
|
+
else:
|
|
69
|
+
self._safe_write_file(rule_path, content, dry_run)
|
|
70
|
+
result.files_created.append(str(rule_path.relative_to(self.project_root)))
|
|
71
|
+
self._record_file(self.target, scope, rule_path)
|
|
72
|
+
|
|
73
|
+
# Also generate AGENTS.md bootstrap
|
|
74
|
+
agents_md = self._generate_agents_md(target_path, dry_run)
|
|
75
|
+
if agents_md:
|
|
76
|
+
result.files_created.append(agents_md)
|
|
77
|
+
|
|
78
|
+
if not dry_run:
|
|
79
|
+
self._update_lock_state(scope)
|
|
80
|
+
|
|
81
|
+
except Exception as e:
|
|
82
|
+
result.success = False
|
|
83
|
+
result.errors.append(str(e))
|
|
84
|
+
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
def _generate_cursor_rule(self) -> str:
|
|
88
|
+
"""Generate Cursor rule with python-skills integration."""
|
|
89
|
+
# Get all skill names for reference
|
|
90
|
+
categories = {}
|
|
91
|
+
for skill in self.skills_registry.get_all_skills():
|
|
92
|
+
if skill.category not in categories:
|
|
93
|
+
categories[skill.category] = []
|
|
94
|
+
categories[skill.category].append(skill.name)
|
|
95
|
+
|
|
96
|
+
rule_parts = [
|
|
97
|
+
"---",
|
|
98
|
+
'description: "Python engineering skills and patterns"',
|
|
99
|
+
'globs: ["**/*.py"]',
|
|
100
|
+
"alwaysApply: false",
|
|
101
|
+
"---",
|
|
102
|
+
"",
|
|
103
|
+
"<!-- BEGIN PYTHON-SKILLS MANAGED -->",
|
|
104
|
+
"",
|
|
105
|
+
"# Python Skills Integration",
|
|
106
|
+
"",
|
|
107
|
+
"This project uses [python-skills](https://github.com/FoxPink-dev/python-skills) for Python engineering standards.",
|
|
108
|
+
"",
|
|
109
|
+
"## Available Skill Categories",
|
|
110
|
+
"",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
for category, skills in sorted(categories.items()):
|
|
114
|
+
category_parts = [f"### {category.title()}", ""]
|
|
115
|
+
for skill in sorted(skills):
|
|
116
|
+
category_parts.append(f"- `{skill}`")
|
|
117
|
+
category_parts.append("")
|
|
118
|
+
rule_parts.extend(category_parts)
|
|
119
|
+
|
|
120
|
+
rule_parts.extend([
|
|
121
|
+
"## Usage",
|
|
122
|
+
"",
|
|
123
|
+
"Reference relevant skills when working on Python code. Key patterns:",
|
|
124
|
+
"",
|
|
125
|
+
"- **Type hints**: Use built-in generics, `str | None`, `Protocol`",
|
|
126
|
+
"- **Async**: `asyncio.gather`, `Semaphore`, `TaskGroup` (3.11+)",
|
|
127
|
+
"- **HTTP**: `httpx` with retries, timeouts, connection pooling",
|
|
128
|
+
"- **Security**: Parameterized queries, `pathlib` for paths, `yaml.safe_load`",
|
|
129
|
+
"- **Testing**: `pytest` with parametrized tests, edge cases",
|
|
130
|
+
"- **CLI**: `click`/`typer`, config layering, secrets via env",
|
|
131
|
+
"",
|
|
132
|
+
"Reference: [python-skills repository](https://github.com/FoxPink-dev/python-skills)",
|
|
133
|
+
"",
|
|
134
|
+
"<!-- END PYTHON-SKILLS MANAGED -->",
|
|
135
|
+
])
|
|
136
|
+
|
|
137
|
+
return "\n".join(rule_parts)
|
|
138
|
+
|
|
139
|
+
def _generate_agents_md(self, target_path: Path, dry_run: bool) -> str | None:
|
|
140
|
+
agents_md = target_path / "AGENTS.md"
|
|
141
|
+
bootstrap = self._generate_agents_md_content()
|
|
142
|
+
|
|
143
|
+
if dry_run:
|
|
144
|
+
return str(agents_md.relative_to(self.project_root))
|
|
145
|
+
|
|
146
|
+
if agents_md.exists():
|
|
147
|
+
existing = agents_md.read_text(encoding="utf-8")
|
|
148
|
+
new_content, replaced = self._replace_managed_region(existing, bootstrap, agents_md)
|
|
149
|
+
if replaced:
|
|
150
|
+
self._safe_write_file(agents_md, new_content, dry_run)
|
|
151
|
+
self._record_file(self.target, "project", agents_md, (BEGIN_MARKER, END_MARKER))
|
|
152
|
+
else:
|
|
153
|
+
new_content = existing + "\n\n" + self._wrap_managed(bootstrap, agents_md)
|
|
154
|
+
self._safe_write_file(agents_md, new_content, dry_run)
|
|
155
|
+
self._record_file(self.target, "project", agents_md, (BEGIN_MARKER, END_MARKER))
|
|
156
|
+
else:
|
|
157
|
+
self._safe_write_file(agents_md, self._wrap_managed(bootstrap, agents_md), dry_run)
|
|
158
|
+
self._record_file(self.target, "project", agents_md, (BEGIN_MARKER, END_MARKER))
|
|
159
|
+
|
|
160
|
+
return str(agents_md.relative_to(self.project_root))
|
|
161
|
+
|
|
162
|
+
def _generate_agents_md_content(self) -> str:
|
|
163
|
+
return """<!-- BEGIN PYTHON-SKILLS MANAGED -->
|
|
164
|
+
# Python Skills Integration
|
|
165
|
+
|
|
166
|
+
This project uses [python-skills](https://github.com/FoxPink-dev/python-skills) for Python engineering standards.
|
|
167
|
+
|
|
168
|
+
## Available Skills
|
|
169
|
+
|
|
170
|
+
The canonical skill library is at `python-skills/skills/` with 69 skills across 10 categories.
|
|
171
|
+
|
|
172
|
+
### Core
|
|
173
|
+
- variables_types, control_flow, functions, data_structures, oop, comprehensions, advanced_python
|
|
174
|
+
|
|
175
|
+
### Stdlib
|
|
176
|
+
- argparse, collections, datetime, functools, itertools, json, logging, os_sys, pathlib, re, statistics, subprocess
|
|
177
|
+
|
|
178
|
+
### Generation
|
|
179
|
+
- type_hints, protocols_generics, async_concurrency, error_handling, validation_pipeline, workflow
|
|
180
|
+
|
|
181
|
+
### Engineering
|
|
182
|
+
- cli_apps, configuration, database, dependency_management, http_clients, logging, modules_packages, packaging, project_structure, pyproject_toml, virtual_environments
|
|
183
|
+
|
|
184
|
+
### Quality
|
|
185
|
+
- abstractions, comments, documentation, duplication, functions, maintainability, naming, readability, type_annotations
|
|
186
|
+
|
|
187
|
+
### Security
|
|
188
|
+
- auth_boundaries, command_injection, dependency_risks, file_handling, input_validation, path_traversal, secrets, sql_injection, unsafe_deserialization
|
|
189
|
+
|
|
190
|
+
### Testing
|
|
191
|
+
- async_tests, coverage, edge_cases, fixtures_mocks, organization, parameterized, regression_tests
|
|
192
|
+
|
|
193
|
+
### Refactoring
|
|
194
|
+
- behavior_preservation, incremental, interface_stability, safe_refactoring
|
|
195
|
+
|
|
196
|
+
### Debugging
|
|
197
|
+
- common_bugs, inspection_techniques, root_cause
|
|
198
|
+
|
|
199
|
+
### Anti-Patterns
|
|
200
|
+
- index
|
|
201
|
+
|
|
202
|
+
## Usage
|
|
203
|
+
Reference relevant skills when working on Python code. Skills are loaded on-demand based on task context.
|
|
204
|
+
<!-- END PYTHON-SKILLS MANAGED -->"""
|
|
205
|
+
|
|
206
|
+
def sync(self, scope: str = "project", dry_run: bool = False) -> SyncResult:
|
|
207
|
+
result = SyncResult(success=True, target=self.target, scope=scope)
|
|
208
|
+
|
|
209
|
+
if scope == "global":
|
|
210
|
+
result.success = False
|
|
211
|
+
result.errors.append("Cursor global scope not supported")
|
|
212
|
+
return result
|
|
213
|
+
|
|
214
|
+
try:
|
|
215
|
+
target_path = self._get_scope_path(scope)
|
|
216
|
+
rules_dir = target_path / ".cursor" / "rules"
|
|
217
|
+
|
|
218
|
+
if not rules_dir.exists():
|
|
219
|
+
result.success = False
|
|
220
|
+
result.errors.append("No .cursor/rules directory found")
|
|
221
|
+
return result
|
|
222
|
+
|
|
223
|
+
rule_path = rules_dir / "python-skills.mdc"
|
|
224
|
+
|
|
225
|
+
if not rule_path.exists():
|
|
226
|
+
result.success = False
|
|
227
|
+
result.errors.append("python-skills.mdc not found")
|
|
228
|
+
return result
|
|
229
|
+
|
|
230
|
+
# Read current rule
|
|
231
|
+
current = rule_path.read_text(encoding="utf-8")
|
|
232
|
+
|
|
233
|
+
# Generate new content
|
|
234
|
+
new_content = self._generate_cursor_rule()
|
|
235
|
+
|
|
236
|
+
# Check if different
|
|
237
|
+
if current.strip() != new_content.strip():
|
|
238
|
+
if not dry_run:
|
|
239
|
+
self._safe_write_file(rule_path, new_content, dry_run)
|
|
240
|
+
result.modified.append(str(rule_path.relative_to(self.project_root)))
|
|
241
|
+
else:
|
|
242
|
+
result.skipped.append(str(rule_path.relative_to(self.project_root)))
|
|
243
|
+
|
|
244
|
+
# Update AGENTS.md
|
|
245
|
+
agents_md = target_path / "AGENTS.md"
|
|
246
|
+
if agents_md.exists():
|
|
247
|
+
current = agents_md.read_text(encoding="utf-8")
|
|
248
|
+
new_agents = self._generate_agents_md_content()
|
|
249
|
+
new_content, replaced = self._replace_managed_region(current, new_agents, agents_md)
|
|
250
|
+
if replaced and not dry_run:
|
|
251
|
+
self._safe_write_file(agents_md, new_content, dry_run)
|
|
252
|
+
result.modified.append(str(agents_md.relative_to(self.project_root)))
|
|
253
|
+
|
|
254
|
+
if not dry_run:
|
|
255
|
+
self._update_lock_state(scope)
|
|
256
|
+
|
|
257
|
+
except Exception as e:
|
|
258
|
+
result.success = False
|
|
259
|
+
result.errors.append(str(e))
|
|
260
|
+
|
|
261
|
+
return result
|
|
262
|
+
|
|
263
|
+
def uninstall(self, scope: str = "project", dry_run: bool = False) -> UninstallResult:
|
|
264
|
+
result = UninstallResult(success=True, target=self.target, scope=scope)
|
|
265
|
+
|
|
266
|
+
if scope == "global":
|
|
267
|
+
result.success = False
|
|
268
|
+
result.errors.append("Cursor global scope not supported")
|
|
269
|
+
return result
|
|
270
|
+
|
|
271
|
+
try:
|
|
272
|
+
target_path = self._get_scope_path(scope)
|
|
273
|
+
rules_dir = target_path / ".cursor" / "rules"
|
|
274
|
+
rule_path = rules_dir / "python-skills.mdc"
|
|
275
|
+
|
|
276
|
+
if rule_path.exists() and self._has_ownership_marker(rule_path):
|
|
277
|
+
if not dry_run:
|
|
278
|
+
rule_path.unlink()
|
|
279
|
+
result.files_removed.append(str(rule_path.relative_to(self.project_root)))
|
|
280
|
+
|
|
281
|
+
# Clean AGENTS.md
|
|
282
|
+
agents_md = target_path / "AGENTS.md"
|
|
283
|
+
if agents_md.exists():
|
|
284
|
+
content = agents_md.read_text(encoding="utf-8")
|
|
285
|
+
new_content, removed = self._remove_managed_region(content, agents_md)
|
|
286
|
+
if removed and not dry_run:
|
|
287
|
+
self._safe_write_file(agents_md, new_content, dry_run)
|
|
288
|
+
result.regions_removed.append(str(agents_md.relative_to(self.project_root)))
|
|
289
|
+
|
|
290
|
+
if not dry_run:
|
|
291
|
+
self._update_lock_state(scope)
|
|
292
|
+
|
|
293
|
+
except Exception as e:
|
|
294
|
+
result.success = False
|
|
295
|
+
result.errors.append(str(e))
|
|
296
|
+
|
|
297
|
+
return result
|
|
298
|
+
|
|
299
|
+
def _has_ownership_marker(self, path: Path) -> bool:
|
|
300
|
+
if not path.exists():
|
|
301
|
+
return False
|
|
302
|
+
content = path.read_text(encoding="utf-8")
|
|
303
|
+
begin, end = self._get_markers(path)
|
|
304
|
+
return begin in content and end in content
|
|
305
|
+
|
|
306
|
+
def status(self, scope: str = "project") -> StatusResult:
|
|
307
|
+
target_path = self._get_scope_path(scope)
|
|
308
|
+
installed = False
|
|
309
|
+
files = []
|
|
310
|
+
|
|
311
|
+
if scope == "global":
|
|
312
|
+
return StatusResult(target=self.target, scope=scope, installed=False, files=[], version="1.0.0")
|
|
313
|
+
|
|
314
|
+
rule_path = target_path / ".cursor" / "rules" / "python-skills.mdc"
|
|
315
|
+
if rule_path.exists() and self._has_ownership_marker(rule_path):
|
|
316
|
+
installed = True
|
|
317
|
+
files.append(str(rule_path.relative_to(self.project_root)))
|
|
318
|
+
|
|
319
|
+
agents_md = target_path / "AGENTS.md"
|
|
320
|
+
if agents_md.exists() and self._has_ownership_marker(agents_md):
|
|
321
|
+
installed = True
|
|
322
|
+
files.append(str(agents_md.relative_to(self.project_root)))
|
|
323
|
+
|
|
324
|
+
return StatusResult(target=self.target, scope=scope, installed=installed, files=files, version="1.0.0")
|
|
325
|
+
|
|
326
|
+
def _update_lock_state(self, scope: str) -> None:
|
|
327
|
+
self.lock_manager.update_canonical_hash(self.skills_registry.skills_root)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Gemini CLI adapter for python-skills."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .agent_skills import AgentSkillsAdapter
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GeminiAdapter(AgentSkillsAdapter):
|
|
9
|
+
"""Adapter for Google Gemini CLI.
|
|
10
|
+
|
|
11
|
+
Gemini CLI discovers skills from:
|
|
12
|
+
- .gemini/skills/<name>/SKILL.md (native)
|
|
13
|
+
- .agents/skills/<name>/SKILL.md (cross-agent standard)
|
|
14
|
+
|
|
15
|
+
We install to .agents/skills/ (shared) and .gemini/skills/ (native).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
target_name = "gemini"
|
|
19
|
+
display_name = "Gemini CLI"
|
|
20
|
+
agent_skills_dir = ".agents/skills"
|
|
21
|
+
native_skills_dir = ".gemini/skills"
|
|
22
|
+
detection_app_command = "gemini"
|
|
23
|
+
detection_project_markers = [".gemini", "GEMINI.md"]
|
|
24
|
+
|
|
25
|
+
def _get_global_path(self) -> Path:
|
|
26
|
+
return Path.home() / ".gemini" / "skills"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Goose adapter for python-skills."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .agent_skills import AgentSkillsAdapter
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GooseAdapter(AgentSkillsAdapter):
|
|
9
|
+
"""Adapter for Goose (by Block/Square).
|
|
10
|
+
|
|
11
|
+
Goose discovers skills from:
|
|
12
|
+
- .agents/skills/<name>/SKILL.md (cross-agent standard)
|
|
13
|
+
- .goose/skills/<name>/SKILL.md (backward compat)
|
|
14
|
+
- .claude/skills/<name>/SKILL.md (backward compat)
|
|
15
|
+
|
|
16
|
+
We install to .agents/skills/ (shared).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
target_name = "goose"
|
|
20
|
+
display_name = "Goose"
|
|
21
|
+
agent_skills_dir = ".agents/skills"
|
|
22
|
+
detection_app_command = "goose"
|
|
23
|
+
detection_project_markers = [".goosehints", "AGENTS.md"]
|
|
24
|
+
|
|
25
|
+
def _get_global_path(self) -> Path:
|
|
26
|
+
return Path.home() / ".config" / "goose" / "skills"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""JetBrains / Junie adapter for python-skills."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .agent_skills import AgentSkillsAdapter
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class JunieAdapter(AgentSkillsAdapter):
|
|
9
|
+
"""Adapter for JetBrains AI / Junie.
|
|
10
|
+
|
|
11
|
+
Junie discovers skills from:
|
|
12
|
+
- .junie/skills/<name>/SKILL.md (native)
|
|
13
|
+
- .agents/skills/<name>/SKILL.md (cross-agent standard)
|
|
14
|
+
|
|
15
|
+
We install to .agents/skills/ (shared) and .junie/skills/ (native).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
target_name = "jetbrains"
|
|
19
|
+
display_name = "JetBrains / Junie"
|
|
20
|
+
agent_skills_dir = ".agents/skills"
|
|
21
|
+
native_skills_dir = ".junie/skills"
|
|
22
|
+
detection_project_markers = [".junie"]
|
|
23
|
+
|
|
24
|
+
def _get_global_path(self) -> Path:
|
|
25
|
+
return Path.home() / ".junie" / "skills"
|