skillware 0.2.7__tar.gz → 0.2.9__tar.gz
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.
- {skillware-0.2.7/skillware.egg-info → skillware-0.2.9}/PKG-INFO +32 -7
- {skillware-0.2.7 → skillware-0.2.9}/README.md +13 -2
- {skillware-0.2.7 → skillware-0.2.9}/pyproject.toml +28 -5
- skillware-0.2.9/skills/dev_tools/__init__.py +1 -0
- skillware-0.2.9/skills/dev_tools/issue_resolver/__init__.py +1 -0
- skillware-0.2.9/skills/dev_tools/issue_resolver/card.json +33 -0
- skillware-0.2.9/skills/dev_tools/issue_resolver/instructions.md +104 -0
- skillware-0.2.9/skills/dev_tools/issue_resolver/manifest.yaml +55 -0
- skillware-0.2.9/skills/dev_tools/issue_resolver/skill.py +138 -0
- skillware-0.2.9/skills/dev_tools/issue_resolver/test_skill.py +185 -0
- skillware-0.2.9/skillware/cli.py +162 -0
- {skillware-0.2.7 → skillware-0.2.9/skillware.egg-info}/PKG-INFO +32 -7
- {skillware-0.2.7 → skillware-0.2.9}/skillware.egg-info/SOURCES.txt +10 -0
- skillware-0.2.9/skillware.egg-info/entry_points.txt +2 -0
- skillware-0.2.9/skillware.egg-info/requires.txt +32 -0
- skillware-0.2.9/tests/test_cli.py +140 -0
- skillware-0.2.7/skillware.egg-info/requires.txt +0 -12
- {skillware-0.2.7 → skillware-0.2.9}/LICENSE +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/MANIFEST.in +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/setup.cfg +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/mica_module/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/mica_module/card.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/mica_module/instructions.md +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/mica_module/manifest.yaml +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/mica_module/mica_corpus.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/mica_module/skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/pii_masker/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/pii_masker/card.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/pii_masker/instructions.md +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/pii_masker/manifest.yaml +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/pii_masker/skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/tos_evaluator/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/tos_evaluator/card.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/tos_evaluator/instructions.md +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/tos_evaluator/manifest.yaml +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/tos_evaluator/skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/compliance/tos_evaluator/test_skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/data_engineering/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/data_engineering/synthetic_generator/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/data_engineering/synthetic_generator/card.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/data_engineering/synthetic_generator/instructions.md +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/data_engineering/synthetic_generator/manifest.yaml +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/data_engineering/synthetic_generator/skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/card.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/data/entities.ftm.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/data/malicious_scs_2025.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/data/normalized_fbi_lazarus_20250722_180019.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/data/normalized_israel_nbctf_20250722_180019.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/data/normalized_uniswap_trm.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/instructions.md +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/maintenance/normalization_tool.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/maintenance/normalize_uniswap_trm.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/manifest.yaml +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/finance/wallet_screening/skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/office/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/office/pdf_form_filler/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/office/pdf_form_filler/card.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/office/pdf_form_filler/instructions.md +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/office/pdf_form_filler/manifest.yaml +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/office/pdf_form_filler/skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/office/pdf_form_filler/utils.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/optimization/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/optimization/prompt_rewriter/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/optimization/prompt_rewriter/card.json +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/optimization/prompt_rewriter/instructions.md +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/optimization/prompt_rewriter/manifest.yaml +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skills/optimization/prompt_rewriter/skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skillware/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skillware/core/__init__.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skillware/core/base_skill.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skillware/core/env.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skillware/core/loader.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skillware.egg-info/dependency_links.txt +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/skillware.egg-info/top_level.txt +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/tests/test_loader.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/tests/test_mica_module.py +0 -0
- {skillware-0.2.7 → skillware-0.2.9}/tests/test_skill_issuer.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: skillware
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: A framework for modular, self-contained AI skills.
|
|
5
|
-
Author-email: ARPA Hellenic
|
|
5
|
+
Author-email: ARPA Hellenic Logical Systems <skillware-os@arpacorp.net>
|
|
6
6
|
License: MIT License
|
|
7
7
|
|
|
8
8
|
Copyright (c) 2026 ARPA Hellenic Logical Systems
|
|
@@ -35,15 +35,29 @@ Description-Content-Type: text/markdown
|
|
|
35
35
|
License-File: LICENSE
|
|
36
36
|
Requires-Dist: requests
|
|
37
37
|
Requires-Dist: pyyaml
|
|
38
|
-
Requires-Dist:
|
|
39
|
-
Requires-Dist: google-generativeai
|
|
40
|
-
Requires-Dist: pymupdf
|
|
38
|
+
Requires-Dist: python-dotenv
|
|
41
39
|
Requires-Dist: beautifulsoup4
|
|
42
40
|
Provides-Extra: dev
|
|
43
41
|
Requires-Dist: pytest; extra == "dev"
|
|
44
42
|
Requires-Dist: pytest-mock; extra == "dev"
|
|
45
43
|
Requires-Dist: flake8; extra == "dev"
|
|
46
44
|
Requires-Dist: black; extra == "dev"
|
|
45
|
+
Provides-Extra: cli
|
|
46
|
+
Requires-Dist: rich>=13.0; extra == "cli"
|
|
47
|
+
Provides-Extra: gemini
|
|
48
|
+
Requires-Dist: google-generativeai; extra == "gemini"
|
|
49
|
+
Provides-Extra: claude
|
|
50
|
+
Requires-Dist: anthropic; extra == "claude"
|
|
51
|
+
Provides-Extra: openai
|
|
52
|
+
Requires-Dist: openai; extra == "openai"
|
|
53
|
+
Provides-Extra: office
|
|
54
|
+
Requires-Dist: pymupdf; extra == "office"
|
|
55
|
+
Provides-Extra: all
|
|
56
|
+
Requires-Dist: rich>=13.0; extra == "all"
|
|
57
|
+
Requires-Dist: google-generativeai; extra == "all"
|
|
58
|
+
Requires-Dist: anthropic; extra == "all"
|
|
59
|
+
Requires-Dist: openai; extra == "all"
|
|
60
|
+
Requires-Dist: pymupdf; extra == "all"
|
|
47
61
|
Dynamic: license-file
|
|
48
62
|
|
|
49
63
|
<div align="center">
|
|
@@ -106,6 +120,7 @@ Skillware/
|
|
|
106
120
|
│ ├── instructions.md # Cognitive map for the LLM
|
|
107
121
|
│ └── test_skill.py # Unit tests & schema validation
|
|
108
122
|
├── skillware/ # Core Framework Package
|
|
123
|
+
│ ├── cli.py # Command-line interface
|
|
109
124
|
│ └── core/
|
|
110
125
|
│ ├── base_skill.py # Abstract Base Class for skills
|
|
111
126
|
│ ├── env.py # Environment Management
|
|
@@ -135,7 +150,16 @@ pip install -e .
|
|
|
135
150
|
|
|
136
151
|
> **Note**: Individual skills may have their own dependencies. The `SkillLoader` validates `manifest.yaml` and warns of missing packages (e.g., `requests`, `pandas`) upon loading a skill.
|
|
137
152
|
|
|
138
|
-
### 2.
|
|
153
|
+
### 2. Verify your installation
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
pip install "skillware[cli]"
|
|
157
|
+
skillware list
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This prints a table of all locally available skills and confirms the install and path resolution are working.
|
|
161
|
+
|
|
162
|
+
### 3. Configuration
|
|
139
163
|
|
|
140
164
|
Create a `.env` file with your API keys (e.g., Google Gemini API Key):
|
|
141
165
|
|
|
@@ -143,7 +167,7 @@ Create a `.env` file with your API keys (e.g., Google Gemini API Key):
|
|
|
143
167
|
GOOGLE_API_KEY="your_key"
|
|
144
168
|
```
|
|
145
169
|
|
|
146
|
-
###
|
|
170
|
+
### 4. Usage Example (Gemini)
|
|
147
171
|
|
|
148
172
|
```python
|
|
149
173
|
import google.generativeai as genai
|
|
@@ -184,6 +208,7 @@ print(response.text)
|
|
|
184
208
|
* **[Usage Guide: Ollama](docs/usage/ollama.md)**: Native integration for local models via Ollama.
|
|
185
209
|
* **[API Keys for Skills](docs/usage/api_keys.md)**: Environment variables, cloud/CI setup, and security for skills that call external APIs.
|
|
186
210
|
* **[Skill Library](docs/skills/README.md)**: Available capabilities.
|
|
211
|
+
* **[CLI Reference](docs/usage/cli.md)**: Discover and inspect locally installed skills from the terminal.
|
|
187
212
|
|
|
188
213
|
## Contributing
|
|
189
214
|
|
|
@@ -58,6 +58,7 @@ Skillware/
|
|
|
58
58
|
│ ├── instructions.md # Cognitive map for the LLM
|
|
59
59
|
│ └── test_skill.py # Unit tests & schema validation
|
|
60
60
|
├── skillware/ # Core Framework Package
|
|
61
|
+
│ ├── cli.py # Command-line interface
|
|
61
62
|
│ └── core/
|
|
62
63
|
│ ├── base_skill.py # Abstract Base Class for skills
|
|
63
64
|
│ ├── env.py # Environment Management
|
|
@@ -87,7 +88,16 @@ pip install -e .
|
|
|
87
88
|
|
|
88
89
|
> **Note**: Individual skills may have their own dependencies. The `SkillLoader` validates `manifest.yaml` and warns of missing packages (e.g., `requests`, `pandas`) upon loading a skill.
|
|
89
90
|
|
|
90
|
-
### 2.
|
|
91
|
+
### 2. Verify your installation
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pip install "skillware[cli]"
|
|
95
|
+
skillware list
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This prints a table of all locally available skills and confirms the install and path resolution are working.
|
|
99
|
+
|
|
100
|
+
### 3. Configuration
|
|
91
101
|
|
|
92
102
|
Create a `.env` file with your API keys (e.g., Google Gemini API Key):
|
|
93
103
|
|
|
@@ -95,7 +105,7 @@ Create a `.env` file with your API keys (e.g., Google Gemini API Key):
|
|
|
95
105
|
GOOGLE_API_KEY="your_key"
|
|
96
106
|
```
|
|
97
107
|
|
|
98
|
-
###
|
|
108
|
+
### 4. Usage Example (Gemini)
|
|
99
109
|
|
|
100
110
|
```python
|
|
101
111
|
import google.generativeai as genai
|
|
@@ -136,6 +146,7 @@ print(response.text)
|
|
|
136
146
|
* **[Usage Guide: Ollama](docs/usage/ollama.md)**: Native integration for local models via Ollama.
|
|
137
147
|
* **[API Keys for Skills](docs/usage/api_keys.md)**: Environment variables, cloud/CI setup, and security for skills that call external APIs.
|
|
138
148
|
* **[Skill Library](docs/skills/README.md)**: Available capabilities.
|
|
149
|
+
* **[CLI Reference](docs/usage/cli.md)**: Discover and inspect locally installed skills from the terminal.
|
|
139
150
|
|
|
140
151
|
## Contributing
|
|
141
152
|
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "skillware"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.9"
|
|
8
8
|
description = "A framework for modular, self-contained AI skills."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [
|
|
11
|
-
{ name = "ARPA Hellenic
|
|
11
|
+
{ name = "ARPA Hellenic Logical Systems", email = "skillware-os@arpacorp.net" },
|
|
12
12
|
]
|
|
13
13
|
urls = { "Homepage" = "https://arpacorp.net", "Repository" = "https://github.com/arpahls/skillware" }
|
|
14
14
|
license = { file = "LICENSE" }
|
|
@@ -20,13 +20,14 @@ classifiers = [
|
|
|
20
20
|
dependencies = [
|
|
21
21
|
"requests",
|
|
22
22
|
"pyyaml",
|
|
23
|
-
"
|
|
24
|
-
"google-generativeai",
|
|
25
|
-
"pymupdf",
|
|
23
|
+
"python-dotenv",
|
|
26
24
|
"beautifulsoup4",
|
|
27
25
|
]
|
|
28
26
|
requires-python = ">=3.10"
|
|
29
27
|
|
|
28
|
+
[project.scripts]
|
|
29
|
+
skillware = "skillware.cli:main"
|
|
30
|
+
|
|
30
31
|
[project.optional-dependencies]
|
|
31
32
|
dev = [
|
|
32
33
|
"pytest",
|
|
@@ -34,6 +35,28 @@ dev = [
|
|
|
34
35
|
"flake8",
|
|
35
36
|
"black",
|
|
36
37
|
]
|
|
38
|
+
cli = [
|
|
39
|
+
"rich>=13.0",
|
|
40
|
+
]
|
|
41
|
+
gemini = [
|
|
42
|
+
"google-generativeai",
|
|
43
|
+
]
|
|
44
|
+
claude = [
|
|
45
|
+
"anthropic",
|
|
46
|
+
]
|
|
47
|
+
openai = [
|
|
48
|
+
"openai",
|
|
49
|
+
]
|
|
50
|
+
office = [
|
|
51
|
+
"pymupdf",
|
|
52
|
+
]
|
|
53
|
+
all = [
|
|
54
|
+
"rich>=13.0",
|
|
55
|
+
"google-generativeai",
|
|
56
|
+
"anthropic",
|
|
57
|
+
"openai",
|
|
58
|
+
"pymupdf",
|
|
59
|
+
]
|
|
37
60
|
|
|
38
61
|
[tool.setuptools]
|
|
39
62
|
include-package-data = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# dev_tools skill category.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Issue Resolver skill package.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Issue Resolver",
|
|
3
|
+
"description": "Analyzes any GitHub issue against its target repository and produces a structured resolution plan with ranked implementation options, affected files, and caveats.",
|
|
4
|
+
"issuer": {
|
|
5
|
+
"name": "Ross Peili",
|
|
6
|
+
"email": "vpeilivanidis@gmail.com",
|
|
7
|
+
"github": "rosspeili",
|
|
8
|
+
"org": "ARPAHLS"
|
|
9
|
+
},
|
|
10
|
+
"icon": "git-pull-request",
|
|
11
|
+
"color": "#6E57E0",
|
|
12
|
+
"ui_schema": {
|
|
13
|
+
"type": "card",
|
|
14
|
+
"fields": [
|
|
15
|
+
{
|
|
16
|
+
"key": "status",
|
|
17
|
+
"label": "Status"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"key": "issue.number",
|
|
21
|
+
"label": "Issue"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"key": "issue.repo",
|
|
25
|
+
"label": "Repository"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"key": "auth.token_provided",
|
|
29
|
+
"label": "Authenticated"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Issue Resolver
|
|
2
|
+
|
|
3
|
+
You are using the `dev_tools/issue_resolver` skill.
|
|
4
|
+
|
|
5
|
+
Load this skill when the user provides a GitHub issue URL and asks you to understand, plan, or begin resolving it. The skill applies to any public GitHub repository. It is model-agnostic and does not assume any particular project's conventions.
|
|
6
|
+
|
|
7
|
+
## When to use this skill
|
|
8
|
+
|
|
9
|
+
- The user supplies a GitHub issue URL (with or without additional instructions).
|
|
10
|
+
- The user asks you to analyse an issue, understand its scope, or produce an implementation plan.
|
|
11
|
+
- The user wants to know which files will be affected before any code is written.
|
|
12
|
+
- The user wants ranked options and a recommended approach before committing to implementation.
|
|
13
|
+
|
|
14
|
+
## Workflow you must follow after receiving the skill payload
|
|
15
|
+
|
|
16
|
+
The skill's `execute()` call returns a `status: ready` payload containing pre-computed URLs. Use those URLs with your available tools to carry out the following stages in order. Do not skip stages.
|
|
17
|
+
|
|
18
|
+
### Stage 1 — Fetch the issue
|
|
19
|
+
|
|
20
|
+
Using the `issue.api_url` from the payload:
|
|
21
|
+
|
|
22
|
+
1. Fetch the issue via the GitHub API. If `auth.token_provided` is true, include the `Authorization: Bearer <token>` header.
|
|
23
|
+
2. Extract: title, body, labels, state, assignees, milestone.
|
|
24
|
+
3. Fetch any linked comments (`issue.api_url/comments`) and skim for decisions, constraints, or acceptance criteria that are not in the body.
|
|
25
|
+
4. Check for linked pull requests or referenced issues in the body.
|
|
26
|
+
|
|
27
|
+
### Stage 2 — Understand the repository
|
|
28
|
+
|
|
29
|
+
Using the `repository` URLs from the payload:
|
|
30
|
+
|
|
31
|
+
1. Fetch and read `repository.readme_url`. Identify: project purpose, tech stack, install instructions, any stated conventions.
|
|
32
|
+
2. Fetch and read `repository.contributing_url` if it exists (do not fail if it returns 404). Identify: contribution workflow, code style, PR requirements, any skill or module standards.
|
|
33
|
+
3. Fetch the directory tree via `repository.tree_api_url`. Identify the top-level structure: key source directories, test directories, docs directories, CI configuration, and any existing analogues to what the issue requests.
|
|
34
|
+
4. If the issue references specific files or directories, fetch and inspect their current contents.
|
|
35
|
+
|
|
36
|
+
### Stage 3 — Analyse
|
|
37
|
+
|
|
38
|
+
Produce a structured internal analysis covering:
|
|
39
|
+
|
|
40
|
+
- **Problem statement**: what the issue is actually asking for, including unstated implications.
|
|
41
|
+
- **Acceptance criteria**: verifiable bullets extracted or inferred from the issue body and comments.
|
|
42
|
+
- **Affected files**: every path likely to change — source, tests, documentation, CI, changelogs, configuration. Only list paths you have confirmed exist or have strong reason to expect.
|
|
43
|
+
- **Ripple effects**: downstream files, dependent modules, or external consumers that may be affected even if not directly changed.
|
|
44
|
+
- **Options**: up to three distinct implementation approaches with honest trade-off analysis (complexity, risk, alignment with project conventions, reversibility).
|
|
45
|
+
- **Recommendation**: one approach with a clear rationale.
|
|
46
|
+
- **Out of scope**: what you will not do in this resolution cycle and why.
|
|
47
|
+
- **Caveats**: required dependencies, breaking changes, security concerns, or prerequisites.
|
|
48
|
+
|
|
49
|
+
### Stage 4 — Produce the resolution plan
|
|
50
|
+
|
|
51
|
+
Format your output as a structured plan. Present it clearly to the user before writing any code. Include:
|
|
52
|
+
|
|
53
|
+
1. Issue summary (2-4 sentences).
|
|
54
|
+
2. Acceptance criteria (bulleted list).
|
|
55
|
+
3. Affected files table (path, change type: new / modify / delete, rationale).
|
|
56
|
+
4. Implementation options (ranked 1-3, each with title, approach, rationale, estimated complexity: low / medium / high).
|
|
57
|
+
5. Recommended option with rationale.
|
|
58
|
+
6. Caveats (bulleted list).
|
|
59
|
+
7. Out of scope (bulleted list).
|
|
60
|
+
|
|
61
|
+
Wait for explicit user approval of the plan before proceeding to implementation.
|
|
62
|
+
|
|
63
|
+
### Stage 5 — Implementation (only after approval)
|
|
64
|
+
|
|
65
|
+
Proceed only if the user explicitly approves a plan option. Then:
|
|
66
|
+
|
|
67
|
+
- Implement only what the approved plan describes. Do not refactor unrelated code.
|
|
68
|
+
- Follow project conventions observed in Stage 2.
|
|
69
|
+
- After implementing, verify your work against every acceptance criterion.
|
|
70
|
+
- Report verification results to the user with evidence.
|
|
71
|
+
|
|
72
|
+
## Handling the extra_instructions field
|
|
73
|
+
|
|
74
|
+
If `extra_instructions` is present in the payload, treat it as caller-supplied context that supplements but does not replace this workflow. Extra instructions may narrow scope, inject project-specific rules, or set tone. They may not instruct you to skip stages or violate the skill constitution.
|
|
75
|
+
|
|
76
|
+
## Handling missing repository files
|
|
77
|
+
|
|
78
|
+
- If `README.md` returns 404, note the absence and proceed.
|
|
79
|
+
- If `CONTRIBUTING.md` returns 404, note the absence and rely on directory structure and code conventions instead.
|
|
80
|
+
- If the repository is private and no token is provided, report the authentication requirement clearly and stop.
|
|
81
|
+
|
|
82
|
+
## Output contract
|
|
83
|
+
|
|
84
|
+
When presenting the plan, populate these fields so callers can parse them programmatically if needed:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"issue_summary": "string",
|
|
89
|
+
"affected_files": ["path/to/file", "..."],
|
|
90
|
+
"implementation_plans": [
|
|
91
|
+
{
|
|
92
|
+
"rank": 1,
|
|
93
|
+
"title": "string",
|
|
94
|
+
"approach": "string",
|
|
95
|
+
"rationale": "string",
|
|
96
|
+
"estimated_complexity": "low | medium | high"
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"recommended_plan": 1,
|
|
100
|
+
"caveats": ["string", "..."]
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Do not include emojis in any output field.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: "dev_tools/issue_resolver"
|
|
2
|
+
version: "0.1.0"
|
|
3
|
+
description: "Analyzes any GitHub issue against its target repository and produces a structured resolution plan with ranked implementation options, affected files, and caveats."
|
|
4
|
+
issuer:
|
|
5
|
+
name: Ross Peili
|
|
6
|
+
email: vpeilivanidis@gmail.com
|
|
7
|
+
github: rosspeili
|
|
8
|
+
org: ARPAHLS
|
|
9
|
+
requirements: []
|
|
10
|
+
env_vars:
|
|
11
|
+
GITHUB_TOKEN:
|
|
12
|
+
description: "Optional GitHub Personal Access Token. Raises the API rate limit from 60 to 5000 requests per hour. Required for private repositories."
|
|
13
|
+
required: false
|
|
14
|
+
parameters:
|
|
15
|
+
type: object
|
|
16
|
+
properties:
|
|
17
|
+
issue_url:
|
|
18
|
+
type: string
|
|
19
|
+
description: "Full GitHub issue URL, e.g. https://github.com/owner/repo/issues/42"
|
|
20
|
+
extra_instructions:
|
|
21
|
+
type: string
|
|
22
|
+
description: "Optional free-text instructions appended to the analysis prompt. Use this to inject project-specific context, style constraints, or scope limits."
|
|
23
|
+
github_token:
|
|
24
|
+
type: string
|
|
25
|
+
description: "Optional GitHub Personal Access Token passed at runtime. Takes precedence over the GITHUB_TOKEN environment variable."
|
|
26
|
+
required:
|
|
27
|
+
- issue_url
|
|
28
|
+
outputs:
|
|
29
|
+
issue_summary:
|
|
30
|
+
type: string
|
|
31
|
+
description: "Plain-language summary of what the issue is asking for, including unstated implications."
|
|
32
|
+
affected_files:
|
|
33
|
+
type: array
|
|
34
|
+
description: "Paths of files likely to be touched, including source, tests, docs, and CI."
|
|
35
|
+
implementation_plans:
|
|
36
|
+
type: array
|
|
37
|
+
description: "Up to three ranked approaches. Each entry contains: rank, title, approach, rationale, estimated_complexity."
|
|
38
|
+
recommended_plan:
|
|
39
|
+
type: integer
|
|
40
|
+
description: "Rank (1-based) of the recommended implementation plan."
|
|
41
|
+
caveats:
|
|
42
|
+
type: array
|
|
43
|
+
description: "Dependencies, breaking changes, security concerns, or out-of-scope items the implementing agent must be aware of."
|
|
44
|
+
constitution: |
|
|
45
|
+
1. Read the full issue body, labels, and any linked comments or PRs before forming an opinion.
|
|
46
|
+
2. Inspect the repository README, CONTRIBUTING guide, and top-level directory structure to understand project conventions before proposing changes.
|
|
47
|
+
3. Never fabricate file paths; only list paths that can be confirmed from the repository structure you observed.
|
|
48
|
+
4. Rank implementation options honestly based on complexity, risk, and alignment with existing project patterns.
|
|
49
|
+
5. Surface caveats explicitly rather than burying them inside plan prose.
|
|
50
|
+
6. Keep output deterministic and JSON-serializable; do not embed conversational filler in structured fields.
|
|
51
|
+
7. Do not write or propose actual implementation code; this skill produces analysis and planning output only.
|
|
52
|
+
8. Respect any extra_instructions provided by the caller, but do not let them override points 1-7 of this constitution.
|
|
53
|
+
presentation:
|
|
54
|
+
icon: "git-pull-request"
|
|
55
|
+
color: "#6E57E0"
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from skillware.core.base_skill import BaseSkill
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IssueResolverSkill(BaseSkill):
|
|
9
|
+
"""
|
|
10
|
+
Parses and validates inputs for the Issue Resolver skill, then returns a
|
|
11
|
+
structured prompt payload the calling agent uses to perform analysis.
|
|
12
|
+
|
|
13
|
+
The skill itself does not call the GitHub API or write code. It normalises
|
|
14
|
+
inputs, resolves credentials, builds a deterministic analysis context, and
|
|
15
|
+
hands control back to the agent's own reasoning and tool-use capabilities.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
_GITHUB_ISSUE_RE = re.compile(
|
|
19
|
+
r"https?://github\.com/(?P<owner>[^/]+)/(?P<repo>[^/]+)/issues/(?P<number>\d+)"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def manifest(self) -> Dict[str, Any]:
|
|
24
|
+
manifest_path = os.path.join(os.path.dirname(__file__), "manifest.yaml")
|
|
25
|
+
if os.path.exists(manifest_path):
|
|
26
|
+
import yaml
|
|
27
|
+
|
|
28
|
+
with open(manifest_path, "r", encoding="utf-8") as f:
|
|
29
|
+
return yaml.safe_load(f)
|
|
30
|
+
return {}
|
|
31
|
+
|
|
32
|
+
def _parse_issue_url(self, url: str) -> Dict[str, str]:
|
|
33
|
+
"""
|
|
34
|
+
Extracts owner, repo, and issue number from a GitHub issue URL.
|
|
35
|
+
Returns a dict with keys: owner, repo, number, api_url, raw_url.
|
|
36
|
+
Raises ValueError if the URL does not match the expected pattern.
|
|
37
|
+
"""
|
|
38
|
+
match = self._GITHUB_ISSUE_RE.match(url.strip())
|
|
39
|
+
if not match:
|
|
40
|
+
raise ValueError(
|
|
41
|
+
f"issue_url does not match the expected GitHub issue URL pattern: {url!r}. "
|
|
42
|
+
"Expected format: https://github.com/<owner>/<repo>/issues/<number>"
|
|
43
|
+
)
|
|
44
|
+
owner = match.group("owner")
|
|
45
|
+
repo = match.group("repo")
|
|
46
|
+
number = match.group("number")
|
|
47
|
+
return {
|
|
48
|
+
"owner": owner,
|
|
49
|
+
"repo": repo,
|
|
50
|
+
"number": number,
|
|
51
|
+
"api_url": f"https://api.github.com/repos/{owner}/{repo}/issues/{number}",
|
|
52
|
+
"raw_url": url.strip(),
|
|
53
|
+
"repo_api_url": f"https://api.github.com/repos/{owner}/{repo}",
|
|
54
|
+
"repo_html_url": f"https://github.com/{owner}/{repo}",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
def _resolve_token(self, params: Dict[str, Any]) -> str:
|
|
58
|
+
"""
|
|
59
|
+
Returns the GitHub token to use, preferring the runtime parameter over
|
|
60
|
+
the environment variable. Returns an empty string if neither is set.
|
|
61
|
+
"""
|
|
62
|
+
token = (params.get("github_token") or "").strip()
|
|
63
|
+
if not token:
|
|
64
|
+
token = (
|
|
65
|
+
self.config.get("GITHUB_TOKEN") or os.environ.get("GITHUB_TOKEN") or ""
|
|
66
|
+
)
|
|
67
|
+
return token
|
|
68
|
+
|
|
69
|
+
def execute(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
70
|
+
"""
|
|
71
|
+
Validates inputs and returns a structured analysis context.
|
|
72
|
+
|
|
73
|
+
The returned dict contains everything the calling agent needs to begin
|
|
74
|
+
the resolution workflow using its own tools (HTTP fetching, file
|
|
75
|
+
inspection, reasoning). The agent should follow the instructions in
|
|
76
|
+
instructions.md when interpreting this payload.
|
|
77
|
+
"""
|
|
78
|
+
issue_url = (params.get("issue_url") or "").strip()
|
|
79
|
+
if not issue_url:
|
|
80
|
+
return {
|
|
81
|
+
"status": "error",
|
|
82
|
+
"message": "issue_url is required and must not be empty.",
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
parsed = self._parse_issue_url(issue_url)
|
|
87
|
+
except ValueError as exc:
|
|
88
|
+
return {"status": "error", "message": str(exc)}
|
|
89
|
+
|
|
90
|
+
token = self._resolve_token(params)
|
|
91
|
+
extra_instructions = (params.get("extra_instructions") or "").strip()
|
|
92
|
+
|
|
93
|
+
auth_header_note = (
|
|
94
|
+
"Include the Authorization header: Bearer <GITHUB_TOKEN>."
|
|
95
|
+
if token
|
|
96
|
+
else (
|
|
97
|
+
"No GITHUB_TOKEN is configured. The GitHub API will apply the "
|
|
98
|
+
"unauthenticated rate limit (60 requests per hour). For private "
|
|
99
|
+
"repositories or high-volume usage, set GITHUB_TOKEN."
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
"status": "ready",
|
|
105
|
+
"issue": {
|
|
106
|
+
"url": parsed["raw_url"],
|
|
107
|
+
"api_url": parsed["api_url"],
|
|
108
|
+
"owner": parsed["owner"],
|
|
109
|
+
"repo": parsed["repo"],
|
|
110
|
+
"number": parsed["number"],
|
|
111
|
+
},
|
|
112
|
+
"repository": {
|
|
113
|
+
"html_url": parsed["repo_html_url"],
|
|
114
|
+
"api_url": parsed["repo_api_url"],
|
|
115
|
+
"readme_url": (
|
|
116
|
+
f"https://raw.githubusercontent.com/{parsed['owner']}"
|
|
117
|
+
f"/{parsed['repo']}/HEAD/README.md"
|
|
118
|
+
),
|
|
119
|
+
"contributing_url": (
|
|
120
|
+
f"https://raw.githubusercontent.com/{parsed['owner']}"
|
|
121
|
+
f"/{parsed['repo']}/HEAD/CONTRIBUTING.md"
|
|
122
|
+
),
|
|
123
|
+
"tree_api_url": (
|
|
124
|
+
f"https://api.github.com/repos/{parsed['owner']}/{parsed['repo']}"
|
|
125
|
+
"/git/trees/HEAD?recursive=1"
|
|
126
|
+
),
|
|
127
|
+
},
|
|
128
|
+
"auth": {
|
|
129
|
+
"token_provided": bool(token),
|
|
130
|
+
"note": auth_header_note,
|
|
131
|
+
},
|
|
132
|
+
"extra_instructions": extra_instructions or None,
|
|
133
|
+
"next_step": (
|
|
134
|
+
"Follow the workflow in instructions.md. Fetch the issue, "
|
|
135
|
+
"read the repository context, then produce the structured "
|
|
136
|
+
"resolution plan as described."
|
|
137
|
+
),
|
|
138
|
+
}
|