Welcome to Skillware. We are building an open registry of modular, deterministic agent capabilities—skills that any compatible runtime can load. Most contributors add or improve skills, but documentation, framework fixes, tests, and good first issues are equally welcome.
This document is the single entry point for how to contribute. If you are an AI agent working on this repository, read Agent Contribution Workflow first. Human operators may use the same guide to supervise agent work.
| Section | Description |
|---|---|
| Ways to contribute | Choose your contribution type |
| Getting started | Fork, branch, install, open issues |
| Universal expectations | Standards that apply to every PR |
| Pull request process | From issue to merge |
| Skill Package Standard | Required layout for registry skills |
| Skill categories | Folder taxonomy under skills/ |
| What to avoid | Anti-patterns |
| Safety and security | High-risk skills |
| Related documents | Code of conduct, testing, templates |
Pick the path that matches your issue. Only the skill row requires the full bundle under Skill Package Standard.
| Type | What you change | Typical issue label | Before coding | Verify locally |
|---|---|---|---|---|
| New skill | skills/<category>/<name>/, docs/skills/, templates |
skill request, enhancement |
New Skill Proposal or approved issue | Bundle test + pytest tests/test_skill_issuer.py (see TESTING.md) |
| Skill upgrade | Existing bundle under skills/ |
skill upgrade, enhancement |
Skill Upgrade issue | Bundle test + catalog/docs as needed |
| Documentation | docs/, README.md, CONTRIBUTING.md |
documentation |
Documentation Fix issue | Links valid; tone consistent |
| Core framework | skillware/core/, framework tests/ |
core framework, enhancement |
Framework Feature issue | pytest tests/; update usage docs if API changes |
| CLI | skillware/cli.py, docs/usage/cli.md |
cli |
CLI issue | pytest tests/test_cli.py when relevant (list, doctor, test, paths, examples, menu); pytest tests/test_config.py when config paths or .skillware.yaml persistence changes |
| Examples | examples/*.py, agent loops, examples index |
examples |
Examples issue | Script runs; pytest tests/test_registry_docs.py when index changes |
| Packaging | pyproject.toml, MANIFEST.in, wheel |
packaging |
Packaging issue | scripts/wheel_smoke_test.py after wheel build (see TESTING.md) |
| Bug fix | Paths named in issue | bug |
Bug Report | Reproduction or failing test |
| Good first issue | Usually docs, tests, or small fixes | good first issue |
Read acceptance criteria literally | Checklist for underlying type above |
| RFC / large change | Architecture, manifest contract | discussion, core framework |
RFC issue | Per RFC scope |
Skills remain the primary contribution we expect, but every type above should follow Getting started, Universal expectations, and Pull request process.
Check existing issues before starting work.
| Intent | Issue template |
|---|---|
| New capability in the registry | New Skill Proposal |
| Upgrade an existing skill | Skill Upgrade |
Loader, adapters, base_skill |
Framework Feature |
CLI (list, test, doctor, examples, menu) |
CLI |
| Runnable examples / agent loops | Examples |
| PyPI wheel / install packaging | Packaging |
| Docs only | Documentation Fix |
| Incorrect behavior | Bug Report |
| Large or breaking design | RFC |
Issue chooser links: CONTRIBUTING, good first issues, Skill Library. Labels are defined in .github/labels.json and synced automatically on merge to main (see sync-labels workflow).
Label taxonomy: Repo-wide labels describe contribution type or area (bug, cli, security, …). Registry category labels use the cat: prefix (cat: office, cat: security, …) so they never collide with repo-wide names — for example security is for vulnerabilities and trust-model work, while cat: security filters issues about skills under skills/security/. All cat: labels share one pastel color (#E6D9F5). Maintainers may add a cat: label when triaging skill issues and PRs.
Wait for maintainer feedback on non-trivial work before investing in a large PR.
Fork ARPAHLS/skillware to your GitHub account, then clone your fork:
git clone https://github.com/<your-username>/skillware.git
cd skillware
git remote add upstream https://github.com/ARPAHLS/skillware.gitgit fetch upstream
git checkout main
git pull upstream main
git checkout -b feat/issue-<number>-short-descriptionpip install -e ".[dev,all]"For documentation-only PRs, pip install -e ".[dev]" is sufficient. For skill or framework work, use [dev,all] to match CI (optional [agents] for SDK examples — see Install extras).
See TESTING.md for the bundle / framework / maintainer / example model and pytest usage.
Follow the table in Ways to contribute, then Pull request process.
These apply to all contributions, regardless of type.
Follow the Agent Code of Conduct: deterministic skill outputs, documented dependencies, no malicious or deceptive code.
- No emojis in source code, documentation, commit messages, or PR titles.
- Use Black for formatting (CI runs
black --check) and Flake8 for linting (see TESTING.md). - Match existing naming, structure, and documentation tone in the files you touch.
- Change only what the issue requires. Avoid unrelated refactors or drive-by edits.
- Do not bump the package version in
pyproject.toml(orCITATION.cffversion/date-released) unless the issue or a maintainer explicitly requests it (skill-only PRs typically do not version the framework). See Maintainer: cutting a framework release. - When a PR changes user-visible behavior (framework features, new or changed skills, breaking fixes, CLI or documentation users rely on), add entries under
[Unreleased]in CHANGELOG.md in the same PR (Keep a Changelog sections: Added / Changed / Fixed / Removed). Do not add version headers or publish releases; maintainers cut releases. - Skill-only PRs that will not ship in the next PyPI release may omit a CHANGELOG entry; ask on the issue or use maintainer judgment.
-
Add or update tests in the correct layer when behavior changes (see TESTING.md).
-
Skill bundle test —
skills/<category>/<name>/test_skill.py(required for new skills; ships in the wheel; runs in CI viapytest skills/). -
Framework test —
tests/test_*.pyat repo root (loader, CLI, issuer rules, doc-drift guards). -
Maintainer skill test — optional
tests/skills/<category>/test_<name>.pyfor extra loader or edge-case coverage. -
Usage examples —
examples/*.pyare not tests and are not run in CI. -
GitHub Actions runs two jobs on every PR (see
.github/workflows/ci.yml):build— editable installpip install -e ".[dev,all]", thenpython -m black --check .,flake8 .,pytest skills/(bundle tests),pytest tests/(framework + maintainer tests).wheel-smoke— builds a wheel, installs it in a fresh venv (base deps only), runsscripts/wheel_smoke_test.pyto verify every bundled registry skill ships correctly. See Packaging smoke test.
-
Do not add per-skill pip lines or hardcoded skill paths to
.github/workflows/ci.yml. -
Run locally before opening a PR:
python -m black --check . python -m flake8 . python -m pytest skills/ python -m pytest tests/
Bundle tests can also be run with
skillware test(see CLI reference); requires[dev]or[dev,all].For a single skill:
python -m pytest skills/<category>/<skill_name>/test_skill.py
Or:
skillware test <category>/<skill_name>. -
Install packages from that skill's
manifest.yamlrequirementswhen they are not covered by[all]. After adding a skill with new third-party deps, runpython scripts/sync_extras.py(see Install extras). -
Wait for GitHub Actions CI to pass before requesting review.
Use the pull request template. Complete the New or updated skill section only when this PR adds or changes files under skills/.
Before requesting review, verify your PR template checklist:
- Select the correct change type (skill, documentation, framework, bug fix).
- Confirm local
flake8,blackandpytestpass (bothpytest skills/andpytest tests/). - Add a CHANGELOG entry under
[Unreleased]when the change is user-visible. - Fill only the checkboxes that truthfully apply; do not leave unchecked defaults.
Agents must follow Agent Contribution Workflow. Human operators: approve the agent's plan before implementation, verify tests, and own the fork, commit, and PR. The operator remains responsible for the merged diff.
-
Link an issue — Reference it in the PR description (
Fixes #123orRefs #123). -
Fork and branch — Work on a feature branch, not
mainof the upstream repo. -
Implement — Use the checklist for your contribution type (Ways to contribute).
-
Verify locally:
python -m black --check . python -m flake8 . pytest skills/ pytest tests/
Or
skillware testfor bundle tests (see CLI reference).For skill work, also run:
pytest skills/<category>/<skill_name>/test_skill.py pytest tests/test_skill_issuer.py
Or
skillware test <category>/<skill_name>for the bundle test only. -
Commit — Clear imperative message, no emojis; include issue reference when appropriate. Do not add AI tools in
Co-authored-by:trailers (see Agent Code of Conduct). -
Changelog — If the PR is user-visible, add lines under
[Unreleased]in CHANGELOG.md before opening the PR. -
Push to your fork and open a PR into
ARPAHLS/skillwaremain. -
CI — Ensure checks pass; address review feedback on the same branch.
- Copy or align with
templates/python_skill/. - Create
skills/<category>/<skill_name>/with the full bundle (see Skill Package Standard). - Add
docs/skills/<skill_name>.mdand a row in docs/skills/README.md. - When adding or renaming a runnable script under
examples/, update examples/README.md in the same PR. - Confirm
SkillLoader.load_skill("<category>/<skill_name>")works or document required packages and environment variables.
Skills you submit are reviewed for origin and quality, not sandboxed at runtime — operators run them in their own process. Understand the skill trust model before designing a skill's behavior.
Every registry skill lives in skills/<category>/<skill_name>/ and must include the files below. This is the detailed standard for the skill contribution type.
Checklists below use file names; each file implements a role. The README Mission summarizes the core roles; full reference: docs/introduction.md — Skill anatomy.
| Role | v0 file(s) | Required |
|---|---|---|
| Contract | manifest.yaml |
Yes |
| Effect | skill.py (+ effect modules in the same folder) |
Yes |
| Directive | instructions.md |
Yes |
| Assurance | test_skill.py |
Yes (registry) |
| Presentation | card.json |
Recommended |
| Corpus | kb/, data/, bundled knowledge files |
Optional |
| Reference | schemas/, maps, in-bundle spec fixtures |
Optional |
| Interface | skillware/core/loader.py adapters |
Framework (not in bundle) |
Effect modules (for example workflow.py, budget.py) are imported by skill.py—implementation detail, not a separate required file. Corpus tooling (for example maintenance/) refreshes Corpus offline and is not loaded by execute().
Defines the tool interface, safety constitution, dependencies, and issuer attribution.
Required fields and sections:
name— registry skill ID incategory/skill_nameform; must match the folder path underskills/(same string asSkillLoader.load_skill(...)and the CLIIDcolumn). Do not use a short name alone (for examplepdf_form_fillerwithout theoffice/prefix). The loader emitsSkillwareIdentityWarningwhen a registry-layout skill (<skill_root>/<category>/<skill_name>/) has a missing or mismatchedname(warn-only in v1; may become an error later). Flat private layouts (<skill_root>/<skill_name>/) skip this check. Enforced in CI viatests/test_registry_identity.py— mismatched or duplicatemanifest.nameblocks merge (#280).version,descriptionissuer— see Issuer attribution;nameandemailrequired,githubandorgoptionalshort_description— optional one-line summary (~80 chars) shown inskillware listwhen presentparameters— valid JSON Schema for LLM tool callingconstitution— safety boundaries enforced at the prompt levelrequirements— when external packages are needed (for examplerequests,pandas). Use PEP 508 strings; add version specifiers (for exampleweb3>=6.0.0) when the skill depends on a minimum package version —SkillLoader.load_skill()validates pins at load time (see Install extras).
Optional but common:
env_vars— API keys and configuration (never hardcode secrets inskill.py); document the same names on the skill catalog page and link to API keys for skillscategory,outputs,presentation— when they clarify the skill contract. Useoutputs:with named keys (never legacy singularoutput:).
Example:
name: category/generic_hello
version: 1.0.0
description: A friendly greeting skill.
issuer:
name: Your Name
email: you@example.com
github: your_github_username
org: YOUR ORG
parameters:
type: object
properties:
name:
type: string
required:
- name
constitution: |
1. Do not greet offensive names.
2. Always maintain a polite tone.
requirements:
- requests- Define exactly one concrete subclass of
BaseSkillper skill file.SkillLoader.load_skill()discovers it automatically asbundle["class"](seeSkillLoader.get_skill_class()). - Implement deterministic Python logic; inherit from
BaseSkill. - Accept a dictionary of inputs; return a JSON-serializable dictionary.
- Catch internal errors and return a structured error report; do not crash the host agent.
- Do not print to stdout or stderr for normal operation.
- Do not embed open-ended LLM code generation as the skill implementation.
- When you change the JSON shape returned by
execute(), updatecard.jsonoutput fields (if present) and the matching fixture undertests/fixtures/card_ui_schema/in the same PR.
The primary guide for the host LLM. Skill instructions should be a concise, append-only block focusing on this skill's context rather than assigning an overarching persona (host agents and LLMs already have their own system prompts).
- Prefer skill context: Open with what the skill does, its registry ID (
category/skill_name), deterministic behavior, and key limits. - When to invoke / when not to invoke: Clearly explain primary use cases and anti-patterns.
- Outputs and errors: Detail how to interpret returned fields (
image_base64, paths, structured dicts) and handle error states. - Avoid persona starters: Avoid opening with "You are an agent equipped with...", "You are an expert...", or narrative personality instructions that can conflict when multiple skills are appended to context.
- Keep prompts and persona here, not in
skill.py.
- Recommended for every registry skill; all bundled skills under
skills/ship one. - Describes UI presentation (
name,description,icon,ui_schema, and similar). - When present, include an
issuerobject that matchesmanifest.yaml(nameandemailat minimum; copygithubandorgwhen used). - For output cards (
ui_schema.type=card), eachui_schema.fields[].keymust be a dot path into the JSON returned byexecute()(for examplemetadata.wallet_address,preview.you_pay). Updatecard.jsonin the same PR when you change the output shape. - Add or refresh a representative output fixture at
tests/fixtures/card_ui_schema/<category>__<skill_name>.json(one object or a{"samples": [...]}list when multiple execute paths surface different fields). CI validates keys viatests/test_card_ui_schema.py(#199).
- Required for every new registry skill (template:
templates/python_skill/test_skill.py; enforced bytests/test_skill_issuer.py). - Unit tests for schema compliance and deterministic execution paths (offline; mock externals).
- Ships inside the skill bundle via
pip install skillware. - Run:
pytest skills/<category>/<skill_name>/test_skill.pyorskillware test <category>/<skill_name> - Optional extra depth for maintainers:
tests/skills/<category>/test_<skill_name>.py— see TESTING.md. - Mock network calls and first-run model downloads in bundle tests.
Not required for every skill. When present, document them on the catalog page under Bundle layout (see skill usage template).
- Corpus —
kb/,data/, or other versioned knowledge files the Effect reads at runtime. - Reference —
schemas/, terminology maps, or in-bundle fixtures that define the public contract or demos. - Effect modules — additional
.pyfiles imported only byskill.py(not separate registry roles). - Corpus tooling — offline maintenance scripts (not loaded by
execute()); keep out of the Effect import path unless intentional.
Registry skills are shipped inside the skillware wheel. Per-skill layout uses manifest.yaml and packaging hooks below — not per-skill edits to CI.
- Add an empty
__init__.pyinskills/<category>/when you introduce a new category, and inskills/<category>/<skill_name>/for each new skill directory (enforced bytests/test_skill_issuer.py). - Non-Python files (
manifest.yaml,instructions.md,card.json, data files) are included automatically viaMANIFEST.inand[tool.setuptools.package-data](skills = ["**/*"]). - Confirm
SkillLoader.load_skill("<category>/<skill_name>")works from the repo root. CI wheel-smoke verifies every bundled skill from a cleanpip installof the built wheel; runscripts/wheel_smoke_test.pylocally when changing packaging,MANIFEST.in, or skill bundle layout (see TESTING.md).
Manifest requirements and optional extras
- List runtime packages in the skill's
manifest.yamlrequirements(source of truth for loaders and docs). - Unpinned entries (for example
requests) — loader checks the importable module exists. - Pinned entries (for example
rembg>=2.0.0) — loader also verifies the installed distribution satisfies the specifier beforeskill.pyruns. Pin when API or behavior breaks across versions; unpinned is fine for stable deps. - Run
python scripts/sync_extras.pyafter changing manifests — it regenerates category, per-skill, and[all]rows inpyproject.toml(see Install extras). - Core already includes
requests,pyyaml, andbeautifulsoup4(manifests may saybs4); the sync script omits core packages from extras automatically. - Hand-maintained extras (
dev,gemini,claude,openai,agents) stay above the generated block inpyproject.toml. - Contributors and CI install skill runtime deps with
pip install -e ".[dev,all]"; add[agents]when running SDK examples locally.
- Human-readable documentation linked from the Skill Library.
- Include ID, Issuer, Version (from
manifest.yaml), and Recommended install (pip install "skillware[<category>_<skill>]"— see install_extras.md) near the top. - Describe capabilities, prerequisites, arguments, and limitations.
- If the skill calls external services, list its environment variables in a short table and link to API keys for skills. Do not duplicate the full setup guide on the skill page.
- Add a Usage Examples section with runnable snippets for Gemini, Claude, OpenAI, DeepSeek, and Ollama (prompt mode). Follow skill usage example template and link to usage guides and agent loops.
- Add a Skill history section before the enterprise disclaimer: a table of notable commits that touched the skill bundle or catalog page. Link each commit SHA and list contributors as linked GitHub usernames (
[@username](https://github.com/username)). Append a row when you ship a skill update in the same PR.
- Add or update the skill table in docs/skills/README.md (Skill, ID, Version, Issuer, Description). Set Version to
`x.y.z` (DD Mon YYYY)from the manifest and the release/merge date.
The manifest is the source of truth for issuer data. Use real contact details in everything under skills/—not template placeholders (Your Name, you@example.com, YOUR ORG, and similar).
| Field | Required | Notes |
|---|---|---|
issuer.name |
Yes | Display name of the contributor or maintainer |
issuer.email |
Yes | Contact email for the skill author |
issuer.github |
No | GitHub username without @ |
issuer.org |
No | Optional affiliation / design-ownership org (see Issuer org) |
Registry-wide issuer rules are enforced in tests/test_skill_issuer.py (skills under skills/ only; templates are excluded).
issuer.org is an optional single string for affiliation or design ownership — not necessarily who wrote every line of code. Individual credit stays in issuer.name, email, and github. Omit org when no org applies. Use comma-separated values when multiple orgs apply (for example ARPAHLS, AO).
| Situation | issuer.org |
Catalog Issuer line |
|---|---|---|
| ARPA-maintainer / ARPA-audited skill | ARPAHLS |
[@author](…) ([@ARPAHLS](…)) |
| Third-party–driven skill | contributor org or omit | [@author](…) ([AO](https://github.com/0x-AO-Protocol)) or author only |
| Co-affiliation (e.g. ARPAHLS + AO) | ARPAHLS, AO |
[@author](…) ([@ARPAHLS](…), [AO](https://github.com/0x-AO-Protocol)) |
Separate multiple orgs with a comma in the single org string (for example org: ARPAHLS, AO). Match the catalog Issuer line to the manifest value.
Place each skill under one top-level directory under skills/. Use an existing category when it fits.
| Category | Purpose | Examples in registry |
|---|---|---|
creative |
Image processing, media editing, and creative utilities | bg_remover |
compliance |
Privacy, policy, regulatory guardrails | pii_masker, mica_module, tos_evaluator |
data_engineering |
Datasets, generation, ETL-style tooling | synthetic_generator, novelty_extractor |
defi |
On-chain trading and agent wallet execution | evm_tx_handler |
dev_tools |
Developer workflows, issue resolution, repo tooling | issue_resolver |
finance |
Blockchain, risk, financial analysis | wallet_screening, uk_companies_house_handler |
office |
Documents, productivity, email | pdf_form_filler, gmail_handler |
optimization |
Middleware, compression, efficiency | prompt_rewriter |
monitoring |
Agent loop observability, budget gates, task control | token_limiter |
security |
Offline, local-first defenses for untrusted input reaching agents | prompt_injection_firewall, deceptive_ui_guard |
wellness |
Coaching guardrails, mental health support | mental_coach |
The table above is illustrative, not a closed list. When contributing a new skill, pick the category whose purpose best matches the skill's primary function.
Registry IDs are always category/skill_name from the folder path and must match the name field in manifest.yaml (same string as SkillLoader.load_skill(...) and the CLI ID column). For the live registry, see Skill Library.
New top-level category? Open an issue and discuss with maintainers before adding a folder — do not create skills/<new_category>/ in a pull request without that agreement.
When a new top-level category lands under skills/, update this table and the category dropdown in .github/ISSUE_TEMPLATE/01_skill_proposal.yml in the same PR. Add a matching cat: <category> entry to .github/labels.json (same pastel color as other cat: labels; never use the bare folder name as a repo-wide label). Update REGISTRY_CATEGORIES in tests/test_github_labels.py in the same PR. Labels sync via CI on merge to main.
- God skills — One skill that does everything; split into focused capabilities.
- Hardcoded models — Do not hide prompts in
skill.py; useinstructions.md. - Vendor lock-in — Prefer standard Python over framework-specific wrappers in skill logic.
- Environment leaks — No API keys in source; document
env_varsin the manifest. - Placeholder issuers — No template names or emails in committed registry skills.
- Unrequested version bumps — Do not change
pyproject.tomlversion in routine skill PRs.
- Skills that touch real-world assets (wallets, email, production APIs) should support a dry run or read-only mode when feasible. High-risk skills (on-chain transfers, wallet operations) should use preview and confirmation flows before sending transactions; read each skill's instructions before enabling live keys.
- Sanitize inputs in
skill.pybefore external calls. - Respect the skill
constitutionin both code and documentation. - Malicious or deceptive contributions may be rejected and blocked from the project.
- Registry review is not runtime isolation. Passing maintainer review means a skill's origin is trusted; it does not sandbox the skill. All skills run in the host process regardless of tier. See the skill trust model.
| Document | Purpose |
|---|---|
| API keys for skills | Configuring credentials for skills that call external services |
| Agent Contribution Workflow | Workflow written for contributing agents; operators supervise |
| TESTING.md | Black, Flake8, Pytest, local CI parity |
| Agent Code of Conduct | Behavioral expectations for humans and agents |
| docs/introduction.md | Skill anatomy: Contract / Effect / Directive (+ Assurance, Corpus, Interface) |
| docs/vision.md | Project story, roadmap, and agent discoverability |
| docs/skills/README.md | Published skill catalog |
| templates/python_skill/ | Boilerplate for new skills |
| Pull request template | PR checklist |
| Issue templates | Bug, docs, skills, CLI, examples, RFC chooser |
.github/labels.json |
Repo-wide and cat: <category> label taxonomy (synced via CI) |
| CHANGELOG.md | Release history; contributors add under [Unreleased] |
| CITATION.cff | Preferred software citation (Zenodo concept DOI 10.5281/zenodo.21552745) |
| Security policy | Reporting vulnerabilities |
Routine contributor PRs must not bump the package version. Maintainers cut releases (chore / release PR or direct maintainer commit) and should keep version surfaces in sync:
| Touch | Every framework release? | Notes |
|---|---|---|
pyproject.toml → [project].version |
Yes | Source of truth for PyPI / importlib.metadata / skillware --version |
CHANGELOG.md |
Yes | Move [Unreleased] into ## [X.Y.Z] - YYYY-MM-DD; leave a fresh empty [Unreleased] |
CITATION.cff → version, date-released |
Yes | Match the release tag/date. Keep the Zenodo concept DOI in identifiers stable — do not swap it for a version DOI |
GitHub Release + tag (vX.Y.Z) |
Yes | Triggers Zenodo archive when GitHub–Zenodo is linked (#269). Paste release notes from CHANGELOG.md in the GitHub Releases UI — do not commit maintainer draft files such as .github/RELEASE_*.md to the public tree. |
| PyPI upload | Yes | After tag / CI as usual |
README.md Citing example version |
Optional | Only if an example pin (e.g. 0.4.7) is present; otherwise “record the version you used” is enough |
skillware/version_policy.py + SECURITY.md |
Only when support windows change | Not every release |
| CLI / loader code | Usually no | Version is read from installed package metadata |
Skill manifest.yaml version |
No (unless that skill changed) | Skill versions are independent of the framework version |
docs/contributing/ai_native_workflow.md / CODE_OF_CONDUCT.md |
No | Not version bump surfaces |
README Citing badge and pyproject.toml [project.urls] DOI already point at the concept DOI. Do not add .zenodo.json unless a Zenodo-only field is required (it would override CFF).
Thank you for helping make agent capabilities portable, safe, and reusable.