Metadata-Version: 2.5
Name: pykaxe
Version: 0.1.1
Summary: A terminal UI for discovering and running small Python CLI tools.
Project-URL: Homepage, https://github.com/murshidm/pykaxe
Project-URL: Issues, https://github.com/murshidm/pykaxe/issues
Author-email: Murshid <murshidm@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: cli,terminal,textual,tools,tui
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Terminals
Requires-Python: >=3.10
Requires-Dist: rich>=13.0
Requires-Dist: textual>=0.60
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Description-Content-Type: text/markdown

# pykaxe

A terminal UI for discovering and running small Python CLI tools.

`pykaxe` scans a tools directory you choose for standalone Python scripts,
lets you fuzzy-search and launch them from a single prompt, and streams
their output live — with sandboxing (memory/CPU/runtime limits, output caps)
so a runaway tool can't take the terminal down with it.

## Install

```bash
pip install pykaxe
```

Or with [pipx](https://pipx.pypa.io/) (recommended for CLI tools):

```bash
pipx install pykaxe
```

## Usage

```bash
pykaxe
```

The first time you run it, pykaxe asks where to keep your tools:

```
Where should pykaxe store your tools? [~/.pykaxe/tools]:
```

Press Enter to accept the default or type a different path. It creates that
folder, seeds it with a few example tools, and remembers your choice in
`~/.pykaxe/config.json` — you won't be asked again. Override it for a single
run with the `PYKAXE_TOOLS_DIR` environment variable.

Type `/` to see available tools, fuzzy-filter by typing part of a name, and
press Enter to select. If a tool declares arguments, pykaxe prompts for each
one in turn — showing its choices/default/help when it declares them —
before running it.

| Key      | Action               |
| -------- | -------------------- |
| `/`      | List / filter tools   |
| `esc`    | Interrupt running tool |
| `ctrl+y` | Copy output to clipboard |
| `ctrl+s` | Re-scan tools directory |
| `ctrl+c` | Quit                  |

## Getting an AI to write a tool

```bash
pykaxe prompt --copy
```

copies a short prompt to your clipboard that explains the tool contract
below. Paste it into ChatGPT or Claude.ai once, then ask for tools in plain
language:

> Generate a pykaxe script to convert Celsius to Fahrenheit.

Save what it gives you as a `.py` file and run:

```bash
pykaxe add path/to/the-script.py
```

which checks it against the contract and copies it into your tools folder —
it shows up next time you type `/`.

If you're using a coding agent with filesystem access (e.g. [Claude
Code](https://claude.com/claude-code)), run `pykaxe skill` once to install a
skill that writes tools directly into your tools folder — no `pykaxe add`
step needed. Just ask it directly:

> Create a pykaxe tool that reverses a string.

## Writing a tool by hand

A tool is a Python script placed in your configured tools folder (see
`pykaxe tools-dir`) that exposes this contract:

```python
import argparse
import sys

TOOL_NAME = "my-tool"
TOOL_DESCRIPTION = "One-line description shown in the tool list."


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(prog=TOOL_NAME, description=TOOL_DESCRIPTION)
    parser.add_argument("--text", required=True, help="Text to process.")
    return parser


def main() -> int:
    args = build_parser().parse_args()
    print(f"you said: {args.text}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
```

Each tool runs as its own subprocess (`python <script> --arg value ...`), so
it must be runnable standalone and communicate purely through stdout/stderr
and its exit code. Drop it straight into your tools folder, or validate it
first with `pykaxe add path/to/script.py`.

## Contributing

1. Fork the repo and create a virtualenv.
2. Install in editable mode with dev dependencies:

   ```bash
   make dev
   ```

3. Add or edit a bundled example tool under `src/pykaxe/examples/`, or make
   changes to the app in `src/pykaxe/app.py`.
4. Run the tests and linter:

   ```bash
   make test
   make lint
   ```

5. Open a pull request.

## Building & releasing

This project uses [hatchling](https://hatch.pypa.io/) as its build backend.
The version lives in `src/pykaxe/__init__.py`.

```bash
make build      # bumps the patch version, then builds sdist + wheel into dist/
make publish    # builds, then uploads dist/* to PyPI via twine
```

To bump a minor or major version instead of a patch:

```bash
make bump-minor
make bump-major
```

## License

MIT — see [LICENSE](LICENSE).
