skillware 0.3.2__tar.gz → 0.3.3__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.3.2/skillware.egg-info → skillware-0.3.3}/PKG-INFO +22 -24
- {skillware-0.3.2 → skillware-0.3.3}/README.md +20 -23
- {skillware-0.3.2 → skillware-0.3.3}/pyproject.toml +2 -1
- {skillware-0.3.2 → skillware-0.3.3}/skills/dev_tools/issue_resolver/card.json +1 -1
- skillware-0.3.3/skills/dev_tools/issue_resolver/instructions.md +80 -0
- skillware-0.3.3/skills/dev_tools/issue_resolver/manifest.yaml +63 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/dev_tools/issue_resolver/skill.py +96 -27
- {skillware-0.3.2 → skillware-0.3.3}/skills/dev_tools/issue_resolver/test_skill.py +62 -1
- skillware-0.3.3/skills/dev_tools/issue_resolver/workflow.py +293 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/skill.py +74 -15
- {skillware-0.3.2 → skillware-0.3.3}/skillware/cli.py +3 -0
- skillware-0.3.3/skillware/version_policy.py +63 -0
- {skillware-0.3.2 → skillware-0.3.3/skillware.egg-info}/PKG-INFO +22 -24
- {skillware-0.3.2 → skillware-0.3.3}/skillware.egg-info/SOURCES.txt +4 -1
- {skillware-0.3.2 → skillware-0.3.3}/skillware.egg-info/requires.txt +1 -0
- skillware-0.3.3/tests/test_version_policy.py +96 -0
- skillware-0.3.2/skills/dev_tools/issue_resolver/instructions.md +0 -104
- skillware-0.3.2/skills/dev_tools/issue_resolver/manifest.yaml +0 -56
- {skillware-0.3.2 → skillware-0.3.3}/LICENSE +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/MANIFEST.in +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/setup.cfg +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/mica_module/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/mica_module/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/mica_module/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/mica_module/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/mica_module/mica_corpus.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/mica_module/skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/pii_masker/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/pii_masker/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/pii_masker/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/pii_masker/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/pii_masker/skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/tos_evaluator/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/tos_evaluator/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/tos_evaluator/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/tos_evaluator/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/tos_evaluator/skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/compliance/tos_evaluator/test_skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/novelty_extractor/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/novelty_extractor/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/novelty_extractor/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/novelty_extractor/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/novelty_extractor/skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/novelty_extractor/test_skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/synthetic_generator/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/synthetic_generator/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/synthetic_generator/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/synthetic_generator/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/data_engineering/synthetic_generator/skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/dev_tools/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/dev_tools/issue_resolver/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/data/entities.ftm.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/data/malicious_scs_2025.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/data/normalized_fbi_lazarus_20250722_180019.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/data/normalized_israel_nbctf_20250722_180019.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/data/normalized_uniswap_trm.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/maintenance/normalization_tool.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/maintenance/normalize_uniswap_trm.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/finance/wallet_screening/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/office/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/office/pdf_form_filler/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/office/pdf_form_filler/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/office/pdf_form_filler/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/office/pdf_form_filler/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/office/pdf_form_filler/skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/office/pdf_form_filler/utils.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/optimization/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/optimization/prompt_rewriter/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/optimization/prompt_rewriter/card.json +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/optimization/prompt_rewriter/instructions.md +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/optimization/prompt_rewriter/manifest.yaml +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skills/optimization/prompt_rewriter/skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware/core/__init__.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware/core/base_skill.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware/core/env.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware/core/loader.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware.egg-info/dependency_links.txt +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware.egg-info/entry_points.txt +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/skillware.egg-info/top_level.txt +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/tests/test_cli.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/tests/test_loader.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/tests/test_mica_module.py +0 -0
- {skillware-0.3.2 → skillware-0.3.3}/tests/test_skill_issuer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: skillware
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: A framework for modular, self-contained AI skills.
|
|
5
5
|
Author-email: ARPA Hellenic Logical Systems <skillware-os@arpacorp.net>
|
|
6
6
|
License: MIT License
|
|
@@ -37,6 +37,7 @@ Requires-Dist: requests
|
|
|
37
37
|
Requires-Dist: pyyaml
|
|
38
38
|
Requires-Dist: python-dotenv
|
|
39
39
|
Requires-Dist: beautifulsoup4
|
|
40
|
+
Requires-Dist: packaging
|
|
40
41
|
Provides-Extra: dev
|
|
41
42
|
Requires-Dist: pytest; extra == "dev"
|
|
42
43
|
Requires-Dist: pytest-mock; extra == "dev"
|
|
@@ -81,9 +82,9 @@ Dynamic: license-file
|
|
|
81
82
|
<a href="#architecture">Architecture</a> •
|
|
82
83
|
<a href="#quick-start">Quick Start</a> •
|
|
83
84
|
<a href="#documentation">Documentation</a> •
|
|
84
|
-
<a href="CHANGELOG.md">Changelog</a> •
|
|
85
85
|
<a href="#contributing">Contributing</a> •
|
|
86
86
|
<a href="#comparison">Comparison</a> •
|
|
87
|
+
<a href="CHANGELOG.md">Changelog</a> •
|
|
87
88
|
<a href="#contact">Contact</a>
|
|
88
89
|
</div>
|
|
89
90
|
|
|
@@ -95,18 +96,18 @@ Dynamic: license-file
|
|
|
95
96
|
|
|
96
97
|
## Mission
|
|
97
98
|
|
|
98
|
-
The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**.
|
|
99
|
+
The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained, installable units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**. For the full story and roadmap, see our **[Vision](docs/vision.md)**.
|
|
99
100
|
|
|
100
101
|
A **Skill** in this framework provides everything an Agent needs to master a domain:
|
|
101
102
|
|
|
102
|
-
1.
|
|
103
|
-
2.
|
|
104
|
-
3.
|
|
105
|
-
4.
|
|
103
|
+
1. **Logic**: Executable Python so agents run real work, not guess it.
|
|
104
|
+
2. **Cognition**: System instructions and cognitive maps so any logical system uses the capability as intended.
|
|
105
|
+
3. **Governance**: Constitution, safety boundaries, and hard limits baked into the bundle.
|
|
106
|
+
4. **Interface**: Standardized tool schemas for any LLM or agent runtime.
|
|
106
107
|
|
|
107
108
|
### Skill library
|
|
108
109
|
|
|
109
|
-
Browse capabilities by category in the [Skill library](docs/skills/README.md).
|
|
110
|
+
Browse capabilities by category in the [Skill library](docs/skills/README.md) or on our <a href="https://skillware.site/skills" target="_blank" rel="noopener noreferrer">site ↗</a>.
|
|
110
111
|
|
|
111
112
|
## Architecture
|
|
112
113
|
|
|
@@ -238,30 +239,23 @@ For other providers and shared integration patterns, see the [usage guides index
|
|
|
238
239
|
|
|
239
240
|
## Documentation
|
|
240
241
|
|
|
241
|
-
| Topic |
|
|
242
|
+
| Topic | Links |
|
|
242
243
|
| :--- | :--- |
|
|
243
|
-
| Introduction | [docs/introduction.md](docs/
|
|
244
|
-
|
|
|
245
|
-
|
|
|
246
|
-
| Skill library | [docs/skills/README.md](docs/skills/README.md) |
|
|
247
|
-
| Usage guides | [index](docs/usage/README.md) — [Gemini](docs/usage/gemini.md) · [Claude](docs/usage/claude.md) · [OpenAI](docs/usage/openai.md) · [DeepSeek](docs/usage/deepseek.md) · [Ollama](docs/usage/ollama.md); [agent loops](docs/usage/agent_loops.md); [API keys](docs/usage/api_keys.md) |
|
|
248
|
-
| Examples index | [examples/README.md](examples/README.md) |
|
|
249
|
-
| CLI | [docs/usage/cli.md](docs/usage/cli.md) |
|
|
250
|
-
| Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) · [agent workflow](docs/contributing/ai_native_workflow.md) |
|
|
244
|
+
| **Introduction** | [Introduction](docs/introduction.md) · [Vision](docs/vision.md) · [Comparison](COMPARISON.md) |
|
|
245
|
+
| **Usage guides** | [Skill Library](docs/skills/README.md) · [Usage Guide](docs/usage/README.md) · [Examples](examples/README.md) · [Agent Loops](docs/usage/agent_loops.md) · [API Keys](docs/usage/api_keys.md) · [CLI](docs/usage/cli.md) |
|
|
246
|
+
| **Contributing** | [Contributing](CONTRIBUTING.md) · [Agent Native Workflow](docs/contributing/ai_native_workflow.md) · [Testing](docs/TESTING.md) · [Changelog](CHANGELOG.md) |
|
|
251
247
|
|
|
252
248
|
## Contributing
|
|
253
249
|
|
|
254
|
-
We are building the "App Store" for Agents
|
|
250
|
+
We are building the "App Store" for Agents. Skills are the main contribution, but documentation, tests, and framework fixes are welcome too. Human operators and supervised agents follow the same standards: scoped PRs, deterministic behavior, and verified tests.
|
|
255
251
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
* **[TESTING.md](docs/TESTING.md)** — Local linting and pytest before you open a PR.
|
|
260
|
-
* **[Pull request template](.github/PULL_REQUEST_TEMPLATE.md)** — Checklists for skills, docs, and framework changes (complete only the sections that apply).
|
|
252
|
+
See the **Contributing** row in [Documentation](#documentation) for the full path, [Contributing](CONTRIBUTING.md) (types, skill standard, PR process), [Agent Native Workflow](docs/contributing/ai_native_workflow.md) (for autonomous and semi-autonomous agents), [Testing](docs/TESTING.md) (Black, Flake8, framework and skill pytest, pre-PR checklist), and [Changelog](CHANGELOG.md) (user-facing entries under `[Unreleased]`).
|
|
253
|
+
|
|
254
|
+
Also read the [Agent Code of Conduct](CODE_OF_CONDUCT.md). Open PRs with the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) and complete only the sections that apply.
|
|
261
255
|
|
|
262
256
|
## Comparison
|
|
263
257
|
|
|
264
|
-
Skillware differs from the Model Context Protocol (MCP)
|
|
258
|
+
Skillware differs from the Model Context Protocol (MCP), and Anthropic's Skills repository in several ways:
|
|
265
259
|
|
|
266
260
|
* **Model Agnostic**: Native adapters for Gemini, Claude, Ollama, and OpenAI.
|
|
267
261
|
* **Code-First**: Skills are executable Python packages, not just server specs.
|
|
@@ -274,8 +268,12 @@ Skillware differs from the Model Context Protocol (MCP) or Anthropic's Skills re
|
|
|
274
268
|
For questions, suggestions, or contributions, please open an issue or reach out to us:
|
|
275
269
|
|
|
276
270
|
* **Email**: [skillware-os@arpacorp.net](mailto:skillware-os@arpacorp.net)
|
|
271
|
+
* **Enterprise**: [skills@arpacorp.net](mailto:skills@arpacorp.net) — enterprise skills, chaining, and forward deployed engineering
|
|
272
|
+
* **Security**: [security@arpacorp.net](mailto:security@arpacorp.net) — report bugs, vulnerabilities, or other sensitive issues (see [SECURITY.md](SECURITY.md))
|
|
277
273
|
* **Issues**: [GitHub Issues](https://github.com/arpahls/skillware/issues)
|
|
278
274
|
|
|
275
|
+
For skill-specific questions or reaching a skill's maintainer, check issuer and author details on the skill card, in the repo [Skill Library](docs/skills/README.md), or on our website's <a href="https://skillware.site/skills" target="_blank" rel="noopener noreferrer">skills catalog ↗</a>.
|
|
276
|
+
|
|
279
277
|
---
|
|
280
278
|
|
|
281
279
|
<div align="center">
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
<a href="#architecture">Architecture</a> •
|
|
20
20
|
<a href="#quick-start">Quick Start</a> •
|
|
21
21
|
<a href="#documentation">Documentation</a> •
|
|
22
|
-
<a href="CHANGELOG.md">Changelog</a> •
|
|
23
22
|
<a href="#contributing">Contributing</a> •
|
|
24
23
|
<a href="#comparison">Comparison</a> •
|
|
24
|
+
<a href="CHANGELOG.md">Changelog</a> •
|
|
25
25
|
<a href="#contact">Contact</a>
|
|
26
26
|
</div>
|
|
27
27
|
|
|
@@ -33,18 +33,18 @@
|
|
|
33
33
|
|
|
34
34
|
## Mission
|
|
35
35
|
|
|
36
|
-
The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**.
|
|
36
|
+
The AI ecosystem is fragmented. Developers often re-invent tool definitions, system prompts, and safety rules for every project. **Skillware** supplies a standard to package capabilities into self-contained, installable units that work across **Gemini**, **Claude**, **Ollama**, **GPT**, and **Llama**. For the full story and roadmap, see our **[Vision](docs/vision.md)**.
|
|
37
37
|
|
|
38
38
|
A **Skill** in this framework provides everything an Agent needs to master a domain:
|
|
39
39
|
|
|
40
|
-
1.
|
|
41
|
-
2.
|
|
42
|
-
3.
|
|
43
|
-
4.
|
|
40
|
+
1. **Logic**: Executable Python so agents run real work, not guess it.
|
|
41
|
+
2. **Cognition**: System instructions and cognitive maps so any logical system uses the capability as intended.
|
|
42
|
+
3. **Governance**: Constitution, safety boundaries, and hard limits baked into the bundle.
|
|
43
|
+
4. **Interface**: Standardized tool schemas for any LLM or agent runtime.
|
|
44
44
|
|
|
45
45
|
### Skill library
|
|
46
46
|
|
|
47
|
-
Browse capabilities by category in the [Skill library](docs/skills/README.md).
|
|
47
|
+
Browse capabilities by category in the [Skill library](docs/skills/README.md) or on our <a href="https://skillware.site/skills" target="_blank" rel="noopener noreferrer">site ↗</a>.
|
|
48
48
|
|
|
49
49
|
## Architecture
|
|
50
50
|
|
|
@@ -176,30 +176,23 @@ For other providers and shared integration patterns, see the [usage guides index
|
|
|
176
176
|
|
|
177
177
|
## Documentation
|
|
178
178
|
|
|
179
|
-
| Topic |
|
|
179
|
+
| Topic | Links |
|
|
180
180
|
| :--- | :--- |
|
|
181
|
-
| Introduction | [docs/introduction.md](docs/
|
|
182
|
-
|
|
|
183
|
-
|
|
|
184
|
-
| Skill library | [docs/skills/README.md](docs/skills/README.md) |
|
|
185
|
-
| Usage guides | [index](docs/usage/README.md) — [Gemini](docs/usage/gemini.md) · [Claude](docs/usage/claude.md) · [OpenAI](docs/usage/openai.md) · [DeepSeek](docs/usage/deepseek.md) · [Ollama](docs/usage/ollama.md); [agent loops](docs/usage/agent_loops.md); [API keys](docs/usage/api_keys.md) |
|
|
186
|
-
| Examples index | [examples/README.md](examples/README.md) |
|
|
187
|
-
| CLI | [docs/usage/cli.md](docs/usage/cli.md) |
|
|
188
|
-
| Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) · [agent workflow](docs/contributing/ai_native_workflow.md) |
|
|
181
|
+
| **Introduction** | [Introduction](docs/introduction.md) · [Vision](docs/vision.md) · [Comparison](COMPARISON.md) |
|
|
182
|
+
| **Usage guides** | [Skill Library](docs/skills/README.md) · [Usage Guide](docs/usage/README.md) · [Examples](examples/README.md) · [Agent Loops](docs/usage/agent_loops.md) · [API Keys](docs/usage/api_keys.md) · [CLI](docs/usage/cli.md) |
|
|
183
|
+
| **Contributing** | [Contributing](CONTRIBUTING.md) · [Agent Native Workflow](docs/contributing/ai_native_workflow.md) · [Testing](docs/TESTING.md) · [Changelog](CHANGELOG.md) |
|
|
189
184
|
|
|
190
185
|
## Contributing
|
|
191
186
|
|
|
192
|
-
We are building the "App Store" for Agents
|
|
187
|
+
We are building the "App Store" for Agents. Skills are the main contribution, but documentation, tests, and framework fixes are welcome too. Human operators and supervised agents follow the same standards: scoped PRs, deterministic behavior, and verified tests.
|
|
193
188
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
* **[TESTING.md](docs/TESTING.md)** — Local linting and pytest before you open a PR.
|
|
198
|
-
* **[Pull request template](.github/PULL_REQUEST_TEMPLATE.md)** — Checklists for skills, docs, and framework changes (complete only the sections that apply).
|
|
189
|
+
See the **Contributing** row in [Documentation](#documentation) for the full path, [Contributing](CONTRIBUTING.md) (types, skill standard, PR process), [Agent Native Workflow](docs/contributing/ai_native_workflow.md) (for autonomous and semi-autonomous agents), [Testing](docs/TESTING.md) (Black, Flake8, framework and skill pytest, pre-PR checklist), and [Changelog](CHANGELOG.md) (user-facing entries under `[Unreleased]`).
|
|
190
|
+
|
|
191
|
+
Also read the [Agent Code of Conduct](CODE_OF_CONDUCT.md). Open PRs with the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) and complete only the sections that apply.
|
|
199
192
|
|
|
200
193
|
## Comparison
|
|
201
194
|
|
|
202
|
-
Skillware differs from the Model Context Protocol (MCP)
|
|
195
|
+
Skillware differs from the Model Context Protocol (MCP), and Anthropic's Skills repository in several ways:
|
|
203
196
|
|
|
204
197
|
* **Model Agnostic**: Native adapters for Gemini, Claude, Ollama, and OpenAI.
|
|
205
198
|
* **Code-First**: Skills are executable Python packages, not just server specs.
|
|
@@ -212,8 +205,12 @@ Skillware differs from the Model Context Protocol (MCP) or Anthropic's Skills re
|
|
|
212
205
|
For questions, suggestions, or contributions, please open an issue or reach out to us:
|
|
213
206
|
|
|
214
207
|
* **Email**: [skillware-os@arpacorp.net](mailto:skillware-os@arpacorp.net)
|
|
208
|
+
* **Enterprise**: [skills@arpacorp.net](mailto:skills@arpacorp.net) — enterprise skills, chaining, and forward deployed engineering
|
|
209
|
+
* **Security**: [security@arpacorp.net](mailto:security@arpacorp.net) — report bugs, vulnerabilities, or other sensitive issues (see [SECURITY.md](SECURITY.md))
|
|
215
210
|
* **Issues**: [GitHub Issues](https://github.com/arpahls/skillware/issues)
|
|
216
211
|
|
|
212
|
+
For skill-specific questions or reaching a skill's maintainer, check issuer and author details on the skill card, in the repo [Skill Library](docs/skills/README.md), or on our website's <a href="https://skillware.site/skills" target="_blank" rel="noopener noreferrer">skills catalog ↗</a>.
|
|
213
|
+
|
|
217
214
|
---
|
|
218
215
|
|
|
219
216
|
<div align="center">
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "skillware"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "A framework for modular, self-contained AI skills."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [
|
|
@@ -22,6 +22,7 @@ dependencies = [
|
|
|
22
22
|
"pyyaml",
|
|
23
23
|
"python-dotenv",
|
|
24
24
|
"beautifulsoup4",
|
|
25
|
+
"packaging",
|
|
25
26
|
]
|
|
26
27
|
requires-python = ">=3.10"
|
|
27
28
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "Issue Resolver",
|
|
3
|
-
"description": "
|
|
3
|
+
"description": "Guides an agent through resolving a GitHub issue on any repository: validates the issue URL, returns GitHub API endpoints, and provides sequential stage checklists with verify, commit, and pull request gates.",
|
|
4
4
|
"issuer": {
|
|
5
5
|
"name": "Ross Peili",
|
|
6
6
|
"email": "vpeilivanidis@gmail.com",
|
|
@@ -0,0 +1,80 @@
|
|
|
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 resolve it. The skill applies to any public or authenticated GitHub repository. It is model-agnostic and does not assume any particular project's conventions, language, or directory layout.
|
|
6
|
+
|
|
7
|
+
The skill does **not** call GitHub, run git, or write code. It returns URLs, ordered stage checklists with conditional rules, and commit-message gates. **You** fetch issue data, inspect the repository, and execute each stage with your own tools.
|
|
8
|
+
|
|
9
|
+
## When to use this skill
|
|
10
|
+
|
|
11
|
+
- The user supplies a GitHub issue URL (with or without additional instructions).
|
|
12
|
+
- The user asks you to analyse an issue, understand its scope, or produce an implementation plan.
|
|
13
|
+
- The user wants to know which files will be affected before any code is written.
|
|
14
|
+
- The user wants ranked options and a recommended approach before committing to implementation.
|
|
15
|
+
- The user wants end-to-end guidance through verify, commit, and pull request — with gates before each advance.
|
|
16
|
+
|
|
17
|
+
## Skill actions
|
|
18
|
+
|
|
19
|
+
Call `execute()` with an `action`:
|
|
20
|
+
|
|
21
|
+
| action | When |
|
|
22
|
+
|--------|------|
|
|
23
|
+
| `prepare` (default) | Start: requires `issue_url`; returns GitHub API and raw content URLs |
|
|
24
|
+
| `workflow_overview` | List all stages in order |
|
|
25
|
+
| `stage_checklist` | Requires `stage`; returns steps and conditionals for that stage |
|
|
26
|
+
| `validate_commit_message` | Requires `message`; gate before commit |
|
|
27
|
+
|
|
28
|
+
## Workflow you must follow
|
|
29
|
+
|
|
30
|
+
1. Call `prepare` with the issue URL.
|
|
31
|
+
2. Call `workflow_overview` or proceed directly to stages in order.
|
|
32
|
+
3. At the **start of each stage**, call `stage_checklist` for that stage and follow its `steps` and applicable `conditionals`.
|
|
33
|
+
4. Do not advance while blockers remain or required conditionals for this repository are unaddressed.
|
|
34
|
+
|
|
35
|
+
**Stage order (mandatory):**
|
|
36
|
+
|
|
37
|
+
`discover_issue` → `discover_repository` → `analyze` → `plan` → `implement` → `verify` → `pre_commit` → `commit` → `pull_request`
|
|
38
|
+
|
|
39
|
+
Per-stage steps and conditionals live in the skill (`stage_checklist` responses), not in this file. Apply only conditionals that match what you observed in **discover_repository**; skip irrelevant ones and document ambiguous skips.
|
|
40
|
+
|
|
41
|
+
**Key rules:**
|
|
42
|
+
|
|
43
|
+
- Wait for explicit user approval after **plan** before **implement**.
|
|
44
|
+
- If verification fails, return to **implement**; do not advance to **pre_commit**.
|
|
45
|
+
- Call `validate_commit_message` before commit; do not commit until it returns `"ok": true` and the operator authorized push.
|
|
46
|
+
|
|
47
|
+
## Handling the extra_instructions field
|
|
48
|
+
|
|
49
|
+
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.
|
|
50
|
+
|
|
51
|
+
## Handling missing repository files
|
|
52
|
+
|
|
53
|
+
- If `README.md` returns 404, note the absence and proceed using the tree and code.
|
|
54
|
+
- If `CONTRIBUTING.md` returns 404, note the absence and rely on directory structure, CI, and code conventions instead.
|
|
55
|
+
- If the repository is private and no token is provided, report the authentication requirement clearly and stop.
|
|
56
|
+
|
|
57
|
+
## Plan output contract
|
|
58
|
+
|
|
59
|
+
When presenting the plan (stage **plan**), populate these fields so callers can parse them programmatically if needed:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"issue_summary": "string",
|
|
64
|
+
"affected_files": ["path/to/file"],
|
|
65
|
+
"implementation_plans": [
|
|
66
|
+
{
|
|
67
|
+
"rank": 1,
|
|
68
|
+
"title": "string",
|
|
69
|
+
"approach": "string",
|
|
70
|
+
"rationale": "string",
|
|
71
|
+
"estimated_complexity": "low | medium | high"
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"recommended_plan": 1,
|
|
75
|
+
"caveats": ["string"],
|
|
76
|
+
"out_of_scope": ["string"]
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Do not include emojis in any structured output field.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: "dev_tools/issue_resolver"
|
|
2
|
+
version: "0.2.0"
|
|
3
|
+
description: "Guides an agent through resolving a GitHub issue on any repository: validates the issue URL, returns GitHub API endpoints, and provides sequential stage checklists with conditional verify, commit, and pull request gates."
|
|
4
|
+
short_description: "GitHub issue resolver: URL prep, staged checklists, and commit-message gate."
|
|
5
|
+
issuer:
|
|
6
|
+
name: Ross Peili
|
|
7
|
+
email: vpeilivanidis@gmail.com
|
|
8
|
+
github: rosspeili
|
|
9
|
+
org: ARPAHLS
|
|
10
|
+
requirements: []
|
|
11
|
+
env_vars:
|
|
12
|
+
GITHUB_TOKEN:
|
|
13
|
+
description: "Optional GitHub Personal Access Token. Raises the API rate limit from 60 to 5000 requests per hour. Required for private repositories."
|
|
14
|
+
required: false
|
|
15
|
+
parameters:
|
|
16
|
+
type: object
|
|
17
|
+
properties:
|
|
18
|
+
action:
|
|
19
|
+
type: string
|
|
20
|
+
description: "Workflow action: prepare (default), workflow_overview, stage_checklist, validate_commit_message."
|
|
21
|
+
enum:
|
|
22
|
+
- prepare
|
|
23
|
+
- workflow_overview
|
|
24
|
+
- stage_checklist
|
|
25
|
+
- validate_commit_message
|
|
26
|
+
issue_url:
|
|
27
|
+
type: string
|
|
28
|
+
description: "Required for action prepare. Full GitHub issue URL."
|
|
29
|
+
stage:
|
|
30
|
+
type: string
|
|
31
|
+
description: "Required for action stage_checklist. One of discover_issue, discover_repository, analyze, plan, implement, verify, pre_commit, commit, pull_request."
|
|
32
|
+
message:
|
|
33
|
+
type: string
|
|
34
|
+
description: "Required for action validate_commit_message. Proposed git commit message body."
|
|
35
|
+
allow_ai_coauthor:
|
|
36
|
+
type: boolean
|
|
37
|
+
description: "When true, allow Co-authored-by trailers that credit AI tools. Default false."
|
|
38
|
+
extra_instructions:
|
|
39
|
+
type: string
|
|
40
|
+
description: "Optional caller context. Supplements but does not override the workflow or constitution."
|
|
41
|
+
github_token:
|
|
42
|
+
type: string
|
|
43
|
+
description: "Optional GitHub token at runtime. Takes precedence over GITHUB_TOKEN env var."
|
|
44
|
+
required: []
|
|
45
|
+
outputs:
|
|
46
|
+
status:
|
|
47
|
+
type: string
|
|
48
|
+
description: "ready, rejected, or error."
|
|
49
|
+
workflow_version:
|
|
50
|
+
type: string
|
|
51
|
+
description: "Workflow schema version (0.2)."
|
|
52
|
+
constitution: |
|
|
53
|
+
1. Apply to any public or authenticated GitHub repository; do not assume Skillware or fixed directory layouts.
|
|
54
|
+
2. Follow workflow stages in order; use stage_checklist conditionals that apply to the target repository.
|
|
55
|
+
3. Never fabricate file paths; list only paths confirmed from the issue or repository tree.
|
|
56
|
+
4. Wait for explicit approval after plan before implementation.
|
|
57
|
+
5. Run validate_commit_message before commit unless the operator explicitly skips commit stages.
|
|
58
|
+
6. Keep skill output deterministic and JSON-serializable; the skill does not call GitHub, run git, or write code.
|
|
59
|
+
7. Respect extra_instructions unless they conflict with points 1-6.
|
|
60
|
+
8. Do not add AI agent Co-authored-by trailers in commit messages unless allow_ai_coauthor is true.
|
|
61
|
+
presentation:
|
|
62
|
+
icon: "git-pull-request"
|
|
63
|
+
color: "#6E57E0"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import importlib.util
|
|
1
2
|
import os
|
|
2
3
|
import re
|
|
3
4
|
from typing import Any, Dict
|
|
@@ -5,20 +6,50 @@ from typing import Any, Dict
|
|
|
5
6
|
from skillware.core.base_skill import BaseSkill
|
|
6
7
|
|
|
7
8
|
|
|
9
|
+
def _import_workflow():
|
|
10
|
+
try:
|
|
11
|
+
from . import workflow as wf # type: ignore[import-not-found]
|
|
12
|
+
except ImportError:
|
|
13
|
+
wf_path = os.path.join(os.path.dirname(__file__), "workflow.py")
|
|
14
|
+
spec = importlib.util.spec_from_file_location(
|
|
15
|
+
"issue_resolver_workflow", wf_path
|
|
16
|
+
)
|
|
17
|
+
if spec is None or spec.loader is None:
|
|
18
|
+
raise ImportError(f"Cannot load workflow module from {wf_path}")
|
|
19
|
+
wf = importlib.util.module_from_spec(spec)
|
|
20
|
+
spec.loader.exec_module(wf)
|
|
21
|
+
return wf
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
_wf = _import_workflow()
|
|
25
|
+
WORKFLOW_VERSION = _wf.WORKFLOW_VERSION
|
|
26
|
+
get_stage_checklist = _wf.get_stage_checklist
|
|
27
|
+
get_workflow_overview = _wf.get_workflow_overview
|
|
28
|
+
validate_commit_message = _wf.validate_commit_message
|
|
29
|
+
|
|
30
|
+
|
|
8
31
|
class IssueResolverSkill(BaseSkill):
|
|
9
32
|
"""
|
|
10
|
-
|
|
11
|
-
structured prompt payload the calling agent uses to perform analysis.
|
|
33
|
+
Universal GitHub issue resolution assistant for any repository.
|
|
12
34
|
|
|
13
|
-
The skill
|
|
14
|
-
|
|
15
|
-
|
|
35
|
+
The skill does not call GitHub, run git, or write code. It returns
|
|
36
|
+
deterministic workflow payloads, stage checklists with conditional logic,
|
|
37
|
+
and commit-message gates for the calling agent to execute in order.
|
|
16
38
|
"""
|
|
17
39
|
|
|
18
40
|
_GITHUB_ISSUE_RE = re.compile(
|
|
19
41
|
r"https?://github\.com/(?P<owner>[^/]+)/(?P<repo>[^/]+)/issues/(?P<number>\d+)"
|
|
20
42
|
)
|
|
21
43
|
|
|
44
|
+
_VALID_ACTIONS = frozenset(
|
|
45
|
+
{
|
|
46
|
+
"prepare",
|
|
47
|
+
"workflow_overview",
|
|
48
|
+
"stage_checklist",
|
|
49
|
+
"validate_commit_message",
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
22
53
|
@property
|
|
23
54
|
def manifest(self) -> Dict[str, Any]:
|
|
24
55
|
manifest_path = os.path.join(os.path.dirname(__file__), "manifest.yaml")
|
|
@@ -30,11 +61,6 @@ class IssueResolverSkill(BaseSkill):
|
|
|
30
61
|
return {}
|
|
31
62
|
|
|
32
63
|
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
64
|
match = self._GITHUB_ISSUE_RE.match(url.strip())
|
|
39
65
|
if not match:
|
|
40
66
|
raise ValueError(
|
|
@@ -55,10 +81,6 @@ class IssueResolverSkill(BaseSkill):
|
|
|
55
81
|
}
|
|
56
82
|
|
|
57
83
|
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
84
|
token = (params.get("github_token") or "").strip()
|
|
63
85
|
if not token:
|
|
64
86
|
token = (
|
|
@@ -66,20 +88,18 @@ class IssueResolverSkill(BaseSkill):
|
|
|
66
88
|
)
|
|
67
89
|
return token
|
|
68
90
|
|
|
69
|
-
def
|
|
70
|
-
"""
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
instructions.md when interpreting this payload.
|
|
77
|
-
"""
|
|
91
|
+
def _action(self, params: Dict[str, Any]) -> str:
|
|
92
|
+
action = (params.get("action") or "prepare").strip().lower()
|
|
93
|
+
if action not in self._VALID_ACTIONS:
|
|
94
|
+
return "__invalid__"
|
|
95
|
+
return action
|
|
96
|
+
|
|
97
|
+
def _prepare(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
78
98
|
issue_url = (params.get("issue_url") or "").strip()
|
|
79
99
|
if not issue_url:
|
|
80
100
|
return {
|
|
81
101
|
"status": "error",
|
|
82
|
-
"message": "issue_url is required
|
|
102
|
+
"message": "issue_url is required for action prepare.",
|
|
83
103
|
}
|
|
84
104
|
|
|
85
105
|
try:
|
|
@@ -102,6 +122,8 @@ class IssueResolverSkill(BaseSkill):
|
|
|
102
122
|
|
|
103
123
|
return {
|
|
104
124
|
"status": "ready",
|
|
125
|
+
"action": "prepare",
|
|
126
|
+
"workflow_version": WORKFLOW_VERSION,
|
|
105
127
|
"issue": {
|
|
106
128
|
"url": parsed["raw_url"],
|
|
107
129
|
"api_url": parsed["api_url"],
|
|
@@ -131,8 +153,55 @@ class IssueResolverSkill(BaseSkill):
|
|
|
131
153
|
},
|
|
132
154
|
"extra_instructions": extra_instructions or None,
|
|
133
155
|
"next_step": (
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"resolution plan as described."
|
|
156
|
+
"Call action workflow_overview or stage_checklist for discover_issue. "
|
|
157
|
+
"Follow instructions.md stages in order; do not skip gates."
|
|
137
158
|
),
|
|
138
159
|
}
|
|
160
|
+
|
|
161
|
+
def _stage_checklist(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
162
|
+
stage = (params.get("stage") or "").strip().lower()
|
|
163
|
+
if not stage:
|
|
164
|
+
return {
|
|
165
|
+
"status": "error",
|
|
166
|
+
"message": "stage is required for action stage_checklist.",
|
|
167
|
+
}
|
|
168
|
+
payload = get_stage_checklist(stage)
|
|
169
|
+
if payload is None:
|
|
170
|
+
return {
|
|
171
|
+
"status": "error",
|
|
172
|
+
"message": f"Unknown stage {stage!r}. Call workflow_overview for valid names.",
|
|
173
|
+
}
|
|
174
|
+
payload["action"] = "stage_checklist"
|
|
175
|
+
return payload
|
|
176
|
+
|
|
177
|
+
def _validate_commit_message(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
178
|
+
message = params.get("message")
|
|
179
|
+
if message is None or not str(message).strip():
|
|
180
|
+
return {
|
|
181
|
+
"status": "error",
|
|
182
|
+
"message": "message is required for action validate_commit_message.",
|
|
183
|
+
}
|
|
184
|
+
allow = bool(params.get("allow_ai_coauthor", False))
|
|
185
|
+
result = validate_commit_message(str(message), allow_ai_coauthor=allow)
|
|
186
|
+
result["action"] = "validate_commit_message"
|
|
187
|
+
return result
|
|
188
|
+
|
|
189
|
+
def execute(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
190
|
+
action = self._action(params)
|
|
191
|
+
if action == "__invalid__":
|
|
192
|
+
allowed = ", ".join(sorted(self._VALID_ACTIONS))
|
|
193
|
+
return {
|
|
194
|
+
"status": "error",
|
|
195
|
+
"message": f"Unknown action. Supported actions: {allowed}.",
|
|
196
|
+
}
|
|
197
|
+
if action == "prepare":
|
|
198
|
+
return self._prepare(params)
|
|
199
|
+
if action == "workflow_overview":
|
|
200
|
+
overview = get_workflow_overview()
|
|
201
|
+
overview["action"] = "workflow_overview"
|
|
202
|
+
return overview
|
|
203
|
+
if action == "stage_checklist":
|
|
204
|
+
return self._stage_checklist(params)
|
|
205
|
+
if action == "validate_commit_message":
|
|
206
|
+
return self._validate_commit_message(params)
|
|
207
|
+
return {"status": "error", "message": "Unhandled action."}
|
|
@@ -43,6 +43,7 @@ def test_manifest_name(skill, manifest):
|
|
|
43
43
|
def test_manifest_version(skill, manifest):
|
|
44
44
|
"""Skill internal manifest version must match manifest.yaml."""
|
|
45
45
|
assert skill.manifest["version"] == manifest["version"]
|
|
46
|
+
assert manifest["version"] == "0.2.0"
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
def test_manifest_has_real_issuer(manifest):
|
|
@@ -68,11 +69,14 @@ def test_card_issuer_matches_manifest(manifest, card):
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
def test_missing_issue_url_returns_error(skill):
|
|
71
|
-
"""
|
|
72
|
+
"""prepare requires issue_url."""
|
|
72
73
|
result = skill.execute({})
|
|
73
74
|
assert result["status"] == "error"
|
|
74
75
|
assert "issue_url" in result["message"].lower()
|
|
75
76
|
|
|
77
|
+
result = skill.execute({"action": "prepare"})
|
|
78
|
+
assert result["status"] == "error"
|
|
79
|
+
|
|
76
80
|
|
|
77
81
|
def test_empty_issue_url_returns_error(skill):
|
|
78
82
|
"""execute() must return a structured error when issue_url is empty string."""
|
|
@@ -183,3 +187,60 @@ def test_next_step_present(skill):
|
|
|
183
187
|
assert "next_step" in result
|
|
184
188
|
assert isinstance(result["next_step"], str)
|
|
185
189
|
assert len(result["next_step"]) > 0
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def test_prepare_includes_workflow_version(skill):
|
|
193
|
+
result = skill.execute({"issue_url": VALID_URL})
|
|
194
|
+
assert result["workflow_version"] == "0.2"
|
|
195
|
+
assert result["action"] == "prepare"
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def test_workflow_overview(skill):
|
|
199
|
+
result = skill.execute({"action": "workflow_overview"})
|
|
200
|
+
assert result["status"] == "ready"
|
|
201
|
+
assert result["action"] == "workflow_overview"
|
|
202
|
+
assert len(result["stage_order"]) == 9
|
|
203
|
+
assert result["stage_order"][0] == "discover_issue"
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_stage_checklist_discover_issue(skill):
|
|
207
|
+
result = skill.execute({"action": "stage_checklist", "stage": "discover_issue"})
|
|
208
|
+
assert result["status"] == "ready"
|
|
209
|
+
assert result["stage"] == "discover_issue"
|
|
210
|
+
assert result["steps"]
|
|
211
|
+
assert result["conditionals"]
|
|
212
|
+
assert result["next_stage"] == "discover_repository"
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def test_stage_checklist_unknown_stage(skill):
|
|
216
|
+
result = skill.execute({"action": "stage_checklist", "stage": "not_a_stage"})
|
|
217
|
+
assert result["status"] == "error"
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def test_validate_commit_message_rejects_ai_coauthor(skill):
|
|
221
|
+
result = skill.execute(
|
|
222
|
+
{
|
|
223
|
+
"action": "validate_commit_message",
|
|
224
|
+
"message": "Fix bug\n\nCo-authored-by: Cursor <cursoragent@cursor.com>",
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
assert result["status"] == "rejected"
|
|
228
|
+
assert result["ok"] is False
|
|
229
|
+
assert result["violations"]
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def test_validate_commit_message_accepts_clean_message(skill):
|
|
233
|
+
result = skill.execute(
|
|
234
|
+
{
|
|
235
|
+
"action": "validate_commit_message",
|
|
236
|
+
"message": "Fix null handling in parser\n\nFixes #143",
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
assert result["status"] == "ready"
|
|
240
|
+
assert result["ok"] is True
|
|
241
|
+
assert result["violations"] == []
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def test_unknown_action(skill):
|
|
245
|
+
result = skill.execute({"action": "fly"})
|
|
246
|
+
assert result["status"] == "error"
|