Skip to content

Feature: Custom Python Commands/Plugins System #8

@genro

Description

@genro

Problem

Currently, when you need to execute custom logic in gtext templates, you have to:

  1. Write inline shell commands with Python (python -c "...")
  2. Deal with multi-line quoting issues
  3. Configure security rules for each command pattern
  4. No easy way to reuse logic across projects

Example that's hard to write:

```include
cli: python -c "
import tomli
from pathlib import Path
# ... complex logic with escaping issues
"

## Proposed Solution

Add a **plugin/custom commands system** that allows registering Python scripts or functions as named commands.

### Option 1: Script-based Commands

Configure custom commands in `.gtext/config.yml` or `pyproject.toml`:

```toml
[tool.gtext.commands]
scandir = "scripts/scandir.py"
listprojects = "scripts/list_projects.py"

Usage in templates:

```include
scandir: .

### Option 2: Plugin Class-based

More powerful approach with proper API:

```python
# .gtext/plugins/scandir.py
from gtext.plugins import Plugin

class ScandirPlugin(Plugin):
    name = "scandir"
    description = "Scan directory for Python projects"
    
    def execute(self, path=".", **kwargs):
        # Implementation
        return markdown_output

Usage:

```include
scandir: .
```include
listprojects: --format table

## Benefits

- ✅ **Cleaner templates** - No complex shell escaping
- ✅ **Reusable** - Share plugins across projects
- ✅ **Type-safe** - Python functions instead of shell strings
- ✅ **Testable** - Easy to unit test plugins
- ✅ **Security** - Plugin allowlist instead of shell command patterns
- ✅ **Documentation** - Plugins can self-document
- ✅ **IDE support** - Autocomplete for plugin names

## Real-World Use Case

**We-Birds README.md.gtext** needs to dynamically list all tools by scanning subdirectories and reading their `pyproject.toml` files. Currently impossible to do cleanly with inline commands.

With plugins:
```markdown
## Tools in the Flock 🪶

```include
scandir: . --type python-projects --format markdown

## Implementation Ideas

1. **Discovery**: Load plugins from `.gtext/plugins/` or configured paths
2. **Registration**: Register as new protocol handlers (like `cli:`, `glob:`)
3. **Security**: Plugins are local files, safer than arbitrary shell
4. **Standard library**: Ship common plugins (file operations, git info, etc.)

## Related

Related to #6 (command system refactoring) - could be part of that work.

## Priority

Medium - Would significantly improve DX for complex use cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions