Skip to content

Commit 5dcd067

Browse files
committed
feat: SKILL.md
1 parent 059225b commit 5dcd067

4 files changed

Lines changed: 541 additions & 0 deletions

File tree

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
name: interfacy
3+
description: High-level guidance for using Interfacy for creating CLIs.
4+
---
5+
6+
# Interfacy
7+
8+
Interfacy is a Python CLI framework that builds command-line interfaces from existing typed functions, classes, class instances, signatures, defaults, and docstrings.
9+
10+
Use it when a project needs a CLI without maintaining a separate parser tree. The normal workflow is to reuse or lightly shape ordinary Python callables, then pass them to `Interfacy`.
11+
12+
## Installation
13+
14+
### From PyPI
15+
16+
```bash
17+
pip install interfacy
18+
```
19+
20+
```bash
21+
uv add interfacy
22+
```
23+
24+
## Basic Usage
25+
26+
```python
27+
from interfacy import Interfacy
28+
29+
def greet(name: str, times: int = 1) -> str:
30+
"""Return a greeting.
31+
32+
Args:
33+
name: Person to greet.
34+
times: Number of greetings.
35+
36+
Returns:
37+
Greeting text.
38+
"""
39+
return " ".join(f"Hello, {name}!" for _ in range(times))
40+
41+
if __name__ == "__main__":
42+
Interfacy(print_result=True).run(greet)
43+
```
44+
45+
```text
46+
$ python app.py Ada --times 2
47+
Hello, Ada! Hello, Ada!
48+
```
49+
50+
## Usage Strategy
51+
52+
1. Choose the shape that matches the user's CLI:
53+
- One action: a typed function.
54+
- Several related actions sharing setup: a class.
55+
- Existing service object or injected dependencies: a class instance.
56+
- A manually composed command tree: `CommandGroup`.
57+
2. Reuse existing typed functions, classes, or instances when they already express the command behavior. Do not create new wrapper functions just to satisfy Interfacy.
58+
3. Make the callable signature describe the CLI:
59+
- Required inputs are positional parameters.
60+
- Options are keyword/defaulted parameters, often keyword-only.
61+
- Choices are `Literal[...]` or `Enum`.
62+
- Repeated values are `list[T]` or variadic parameters.
63+
- Grouped settings are small dataclasses, Pydantic models, or typed config classes.
64+
- Domain-specific scalar values can use `Interfacy.add_type_parser(...)` when a plain annotation is not enough.
65+
4. Put user-facing help in docstrings. The first line should read like command help, not implementation notes. Do not duplicate default values in docstrings; Interfacy can show defaults from signatures.
66+
5. Wire with the public API:
67+
68+
```python
69+
from interfacy import Interfacy
70+
71+
Interfacy(print_result=True).run(command)
72+
```
73+
74+
## What Good Interfacy Code Looks Like
75+
76+
- The command function can be called normally from Python tests.
77+
- Existing functions/classes are reused directly when their signatures and docstrings are already CLI-ready.
78+
- The CLI does not duplicate parameter names, defaults, choices, or help in a second parser definition.
79+
- Parsing concerns stay at the boundary; business logic stays in ordinary Python functions/classes.
80+
- Return values are meaningful Python values. Use `print_result=True` when the CLI should display them.
81+
- Return values, including integers, are command results, not process exit codes.
82+
- Existing printed output, file writes, network calls, and exit behavior are preserved intentionally.
83+
84+
## What To Avoid
85+
86+
- Do not recreate parser trees by hand when Interfacy can infer them.
87+
- Use the public `Interfacy` API for normal application code.
88+
- Do not add manual printing just to show a returned value.
89+
- Do not add thin wrappers around existing callables unless adapting names, validation, parser-specific inputs, or user-facing behavior actually requires it.
90+
- Do not wrap Interfacy entrypoints in `raise SystemExit(main())` patterns that reinterpret command results as exit codes.
91+
- Do not run `.run(...)` at import time; guard executable entrypoints with `if __name__ == "__main__":`.
92+
- Do not hide parse or runtime failures with broad `except Exception` or `except SystemExit` wrappers.
93+
- Do not hide CLI-only transformations in decorators or global state; put them in the callable body or a small adapter.
94+
- Do not expose every method or field of a domain object just because Interfacy can. Design the CLI surface deliberately.
95+
96+
## References
97+
98+
- Read `references/api-patterns.md` when choosing between functions, classes, decorators, command groups, custom type parsers, entrypoints, result display, or tests.
99+
- Read `references/structured-parameters.md` when a command has grouped/nested inputs or config objects.
100+
- For large CLIs with many commands, use `CommandGroup` for real command namespaces and `help_group` constants for readable top-level help sections.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
interface:
2+
display_name: "Interfacy"
3+
short_description: "Build typed Python CLIs with Interfacy"
4+
default_prompt: "Use $interfacy to build or refactor a typed Python CLI with Interfacy."
5+
policy:
6+
allow_implicit_invocation: true

0 commit comments

Comments
 (0)