You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
system for registering safe callable access in sandboxed environments.
22
-
Skills can be installed as regular packages with entry points, or
23
-
dropped into an XDG data directory for quick local use.
24
-
25
-
pyskills shares the progressive disclosure philosophy of the [Agent
26
-
Skills](https://agentskills.io/specification) specification: both
27
-
separate lightweight discovery metadata from full instructions loaded on
28
-
demand. However, where Agent Skills uses a file-system convention
29
-
(`SKILL.md` with YAML frontmatter, `scripts/`, `references/`
30
-
directories), pyskills takes a Python-native approach: pyskills are
31
-
regular Python modules discovered via standard entry points, documented
32
-
with docstrings, and loaded with `import`. This means pyskills are
33
-
directly executable, come with auto-generated structured documentation
34
-
via [`doc()`](https://AnswerDotAI.github.io/pyskills/core.html#doc), and
35
-
include a sandboxing layer via
36
-
[`allow()`](https://AnswerDotAI.github.io/pyskills/core.html#allow) for
37
-
safe execution. This makes pyskills a superset that covers discovery,
38
-
documentation, execution, and security in one system.
6
+
pyskills is a plugin system that lets Python packages register “skills” (units of LLM-usable functionality) via standard [entry points](https://packaging.python.org/en/latest/specifications/entry-points/). An LLM host (e.g. solveit) discovers available pyskills without importing them, reads lightweight descriptions via AST inspection, and selectively loads chosen pyskills into context using standard imports.
7
+
8
+
It includes [`list_pyskills()`](https://AnswerDotAI.github.io/pyskills/core.html#list_pyskills) for discovery, [`doc()`](https://AnswerDotAI.github.io/pyskills/core.html#doc) for rendering module/class/function documentation in LLM-friendly format, [`xdir()`](https://AnswerDotAI.github.io/pyskills/core.html#xdir) for listing a module or class’s public symbols, and an [`allow()`](https://AnswerDotAI.github.io/pyskills/core.html#allow) system for registering safe callable access in sandboxed environments. Skills can be installed as regular packages with entry points, or dropped into an XDG data directory for quick local use.
9
+
10
+
pyskills shares the progressive disclosure philosophy of the [Agent Skills](https://agentskills.io/specification) specification: both separate lightweight discovery metadata from full instructions loaded on demand. However, where Agent Skills uses a file-system convention (`SKILL.md` with YAML frontmatter, `scripts/`, `references/` directories), pyskills takes a Python-native approach: pyskills are regular Python modules discovered via standard entry points, documented with docstrings, and loaded with `import`. This means pyskills are directly executable, come with auto-generated structured documentation via [`doc()`](https://AnswerDotAI.github.io/pyskills/core.html#doc), and include a sandboxing layer via [`allow()`](https://AnswerDotAI.github.io/pyskills/core.html#allow) for safe execution. This makes pyskills a superset that covers discovery, documentation, execution, and security in one system.
39
11
40
12
## Usage
41
13
@@ -53,8 +25,7 @@ $ pip install pyskills
53
25
from pyskills import*
54
26
```
55
27
56
-
Discover what pyskills are available. This works without importing any
57
-
pyskill modules:
28
+
Discover what pyskills are available. This works without importing any pyskill modules:
58
29
59
30
```python
60
31
list_pyskills()
@@ -68,38 +39,28 @@ list_pyskills()
68
39
'dialoghelper.termskill': 'Read and edit Solveit dialog (or Jupyter) .ipynb files from a CLI / script. Solveit is an online notebook application (like Jupyter with AI integration) where each notebook is called a "dialog" and is stored as an `.ipynb` file containing `code`, `note` (markdown), and `prompt` (markdown with a special delimiter) messages (aka "cells"). The `dialoghelper` package provides tools for reading, searching, adding, updating, and deleting those messages.',
69
40
'ghapi.skill': 'GitHub REST API access via `GhApi`, plus local git operations via `fastgit.Git`. Use this for day-to-day GitHub work: reading/creating issues and PRs, checking CI status, managing releases/branches/gists, and repo-local git operations -- all from Python, no shelling out to `gh`/`git` needed.',
70
41
'rgapi.skill': 'Fast and flexible file discovery and search for Python. Use this when code needs `fd`-style file finding or `rg`-style searching.',
42
+
'exhash.skill': 'Universal hash-verified text editing for local files. Use this when an LLM needs one safe editing interface for reading, previewing, and modifying text files.',
71
43
'cordslite.skill': 'Load this skill when an agent needs to search, summarize, or find information in Discord using cordslite. It covers read-only workflows for connecting to Discord, opening a guild, orienting through channels, searching messages, reading threads, and fetching attachments.',
72
44
'bgtmux.skill': 'Use tmux-backed background terminal sessions from Solveit. Useful to have a persistent terminal session that both you and the user can inspect and edit, and that you can send input to from Solveit.',
73
-
'clikernel.skill': 'Use the persistent `clikernel` MCP session as the default workspace for any task advanced through live Python execution -- stateful inspection, file-editing workflows, debugging, experiments, API probes, data transforms, or notebook-style work. Read this before writing, running, or debugging Python code in a session with `clikernel` connected.',
74
-
'exhash.skill': 'Universal hash-verified text editing for local files. Use this when an LLM needs one safe editing interface for reading, previewing, and modifying text files.'}
45
+
'clikernel.skill': 'Use the persistent `clikernel` MCP session as the default workspace for any task advanced through live Python execution -- stateful inspection, file-editing workflows, debugging, experiments, API probes, data transforms, or notebook-style work. Read this before writing, running, or debugging Python code in a session with `clikernel` connected.'}
75
46
76
47
### The [`doc`](https://AnswerDotAI.github.io/pyskills/core.html#doc) and [`xdir`](https://AnswerDotAI.github.io/pyskills/core.html#xdir) functions
77
48
78
-
Once you’ve found a pyskill you want to use, import its module using
79
-
standard python syntax:
49
+
Once you’ve found a pyskill you want to use, import its module using standard python syntax:
80
50
81
51
```python
82
52
import pyskills.skill
83
53
```
84
54
85
-
Use [`doc()`](https://AnswerDotAI.github.io/pyskills/core.html#doc) to
86
-
read its full documentation.
87
-
[`doc()`](https://AnswerDotAI.github.io/pyskills/core.html#doc) works on
88
-
modules, classes, and functions, rendering LLM-friendly output in each
89
-
case.
55
+
Use [`doc()`](https://AnswerDotAI.github.io/pyskills/core.html#doc) to read its full documentation. [`doc()`](https://AnswerDotAI.github.io/pyskills/core.html#doc) works on modules, classes, and functions, rendering LLM-friendly output in each case.
90
56
91
-
For a **module**,
92
-
[`doc`](https://AnswerDotAI.github.io/pyskills/core.html#doc) shows all
93
-
public classes and functions with their signatures and first docstring
For a **module**, [`doc`](https://AnswerDotAI.github.io/pyskills/core.html#doc) shows all public classes and functions with their signatures and first docstring line, submodules, and any [`allow()`](https://AnswerDotAI.github.io/pyskills/core.html#allow) calls:
[`doc`](https://AnswerDotAI.github.io/pyskills/core.html#doc) shows the
134
-
class hierarchy, docstring, `__init__` signature, and all public methods
135
-
with their first docstring line:
91
+
For a **class**, [`doc`](https://AnswerDotAI.github.io/pyskills/core.html#doc) shows the class hierarchy, docstring, `__init__` signature, and all public methods with their first docstring line:
function is how pyskills register their trusted callables.
107
+
When pyskills run in a sandboxed environment like [safepyrun](https://github.com/AnswerDotAI/safepyrun), they need to declare which callables are trusted to perform otherwise-denied operations (filesystem writes, subprocesses, network access). safepyrun uses [fastaudit](https://github.com/AnswerDotAI/fastaudit) to deny those effects unless they happen inside a callable registered in the `__pytools__` registry. The [`allow()`](https://AnswerDotAI.github.io/pyskills/core.html#allow) function is how pyskills register their trusted callables.
160
108
161
-
You can allow individual functions, methods, all public methods of a
162
-
type, or one specific callable instance:
109
+
You can allow individual functions, methods, all public methods of a type, or one specific callable instance:
163
110
164
111
```python
165
112
# Allow specific methods on a type
@@ -175,27 +122,11 @@ allow(list_pyskills)
175
122
allow(client.images.create_image)
176
123
```
177
124
178
-
An object can also define `__allow__`, returning a list of items to
An object can also define `__allow__`, returning a list of items to register in its place; [`allow`](https://AnswerDotAI.github.io/pyskills/core.html#allow) recurses into the result, so a container (such as a fastspec client or op group) can register all its callables at once.
126
+
127
+
Skill modules typically call [`allow()`](https://AnswerDotAI.github.io/pyskills/core.html#allow) at module level, so permissions are registered automatically when the pyskill is imported. When `safepyrun`’s `RunPython` executes LLM-generated code, pure computation just runs; an operation with side effects is only permitted when it happens inside a registered callable.
128
+
129
+
The `pyskills.skill` module used in the examples above is itself registered as a pyskill entry point. It ships with pyskills both as a working sample and as a self-documenting pyskill that explains the system itself. Its docstring’s “Creating pyskills” section cross-references `pyskills.createskill`, a companion module (not registered as an entry point, so not shown in [`list_pyskills()`](https://AnswerDotAI.github.io/pyskills/core.html#list_pyskills)) that documents how to build your own pyskills:
the rest is the detailed documentation the LLM reads after loading.
154
+
-**A docstring**: the first paragraph is the short description shown during discovery via [`list_pyskills()`](https://AnswerDotAI.github.io/pyskills/core.html#list_pyskills); the rest is the detailed documentation the LLM reads after loading.
229
155
-**`__all__`**: lists the symbols available to the LLM.
The key is an arbitrary name; the value is the module path. After installing the package, [`list_pyskills()`](https://AnswerDotAI.github.io/pyskills/core.html#list_pyskills) will include your pyskill automatically.
270
190
271
-
For full details on creating pyskills, including allow policies for
272
-
write-guarded operations, see `doc(createskill)` after importing it as
273
-
shown above.
191
+
For full details on creating pyskills, including allow policies for write-guarded operations, see `doc(createskill)` after importing it as shown above.
274
192
275
193
### Local pyskills without packaging
276
194
277
-
The entry point approach above requires installing a package. But
278
-
sometimes you want to create pyskills quickly without a full package:
279
-
personal utility pyskills, or pyskills shared across multiple projects
pyskills directory for this. When you first `import pyskills`, it
286
-
creates a directory at your platform’s XDG data home (typically
287
-
`~/.local/share/pyskills/`) and writes a `.pth` file into
288
-
`site-packages`. This `.pth` file tells Python to add the pyskills
289
-
directory to `sys.path` on startup, so any modules placed there are
290
-
importable as standard Python modules without any special import
291
-
machinery. This works across all Python environments on your system,
292
-
even separate uv projects with isolated venvs.
293
-
294
-
You can check where this directory is (although you can use the
295
-
functions below without needing to know):
195
+
The entry point approach above requires installing a package. But sometimes you want to create pyskills quickly without a full package: personal utility pyskills, or pyskills shared across multiple projects that each use isolated environments (like [uv](https://docs.astral.sh/uv/) venvs).
196
+
197
+
pyskills provides an [XDG](https://specifications.freedesktop.org/basedir-spec/latest/)-based pyskills directory for this. When you first `import pyskills`, it creates a directory at your platform’s XDG data home (typically `~/.local/share/pyskills/`) and writes a `.pth` file into `site-packages`. This `.pth` file tells Python to add the pyskills directory to `sys.path` on startup, so any modules placed there are importable as standard Python modules without any special import machinery. This works across all Python environments on your system, even separate uv projects with isolated venvs.
198
+
199
+
You can check where this directory is (although you can use the functions below without needing to know):
296
200
297
201
```python
298
202
pyskills_dir()
299
203
```
300
204
301
205
Path('/Users/jhoward/.local/share/pyskills')
302
206
303
-
You can drop pyskill modules directly into this directory, or use
You can drop pyskill modules directly into this directory, or use [`register_pyskill`](https://AnswerDotAI.github.io/pyskills/core.html#register_pyskill) to create one programmatically:
306
208
307
209
```python
308
210
register_pyskill('my_local.skill', docstr='A quick local pyskill.', code='''
@@ -318,14 +220,6 @@ allow(hello)
318
220
''')
319
221
```
320
222
321
-
This writes the module file into the XDG pyskills directory and creates
322
-
a minimal entry point, so the pyskill immediately appears in
This writes the module file into the XDG pyskills directory and creates a minimal entry point, so the pyskill immediately appears in [`list_pyskills()`](https://AnswerDotAI.github.io/pyskills/core.html#list_pyskills).
224
+
225
+
You can also manage pyskills with [`enable_pyskill`](https://AnswerDotAI.github.io/pyskills/core.html#enable_pyskill) and [`disable_pyskill`](https://AnswerDotAI.github.io/pyskills/core.html#disable_pyskill) to toggle their visibility without deleting files, or use [`disable_pyskill`](https://AnswerDotAI.github.io/pyskills/core.html#disable_pyskill) to remove one entirely.
0 commit comments