Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on:
push:
branches: [master, main]
pull_request:

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Sync workspace
run: uv sync --group dev

- name: Ruff
run: uv run ruff check .

- name: Typecheck
run: uv run ty check

- name: Pytest
run: uv run pytest
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Python
__pycache__/
*.py[cod]
*.egg-info/
.eggs/
dist/
build/
.venv/
venv/

# Tooling / coverage
.pytest_cache/
.ruff_cache/
.mypy_cache/
.ty_cache/
.coverage
htmlcov/
.cache/

# Editors / OS
.DS_Store
.idea/
.vscode/
*.swp

# Local agent scratch
.scratch/
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# pi-python

Python implementation aligned with [earendil-works/pi](https://github.com/earendil-works/pi) semantics: thin LLM adapter, agent runtime, Textual TUI, and interactive coding CLI (`piy`).

## Workspace

```text
packages/
pi_llm/ # Thin LiteLLM adapter
pi_agent/ # Agent loop + Agent SDK
pi_tui/ # Textual widgets/layouts
pi_coding_agent/ # Coding CLI (piy) wiring
```

## Develop

```bash
# Optional: faster installs in CN (do not commit as default — CI uses public PyPI)
export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple

uv sync --group dev
uv run pytest
uv run ruff check .
uv run ty check
```

## CLI

```bash
uv run piy
```
13 changes: 13 additions & 0 deletions packages/pi_agent/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[project]
name = "pi_agent"
version = "0.1.0"
description = "Agent loop and stateful Agent SDK for pi-python"
requires-python = ">=3.11"
dependencies = []

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/pi_agent"]
3 changes: 3 additions & 0 deletions packages/pi_agent/src/pi_agent/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Agent runtime: pure loop + stateful Agent SDK."""

__all__: list[str] = []
25 changes: 25 additions & 0 deletions packages/pi_coding_agent/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[project]
name = "pi_coding_agent"
version = "0.1.0"
description = "Interactive coding CLI (piy) for pi-python"
requires-python = ">=3.11"
dependencies = [
"pi_llm",
"pi_agent",
"pi_tui",
]

[project.scripts]
piy = "pi_coding_agent.cli:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/pi_coding_agent"]

[tool.uv.sources]
pi_llm = { workspace = true }
pi_agent = { workspace = true }
pi_tui = { workspace = true }
3 changes: 3 additions & 0 deletions packages/pi_coding_agent/src/pi_coding_agent/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Interactive coding CLI package (piy)."""

__all__: list[str] = []
8 changes: 8 additions & 0 deletions packages/pi_coding_agent/src/pi_coding_agent/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Console entrypoint for `piy`."""

from __future__ import annotations


def main() -> None:
"""Stub entrypoint; interactive wiring lands in a later ticket."""
raise SystemExit("piy: not implemented yet (scaffold stub)")
13 changes: 13 additions & 0 deletions packages/pi_llm/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[project]
name = "pi_llm"
version = "0.1.0"
description = "Thin LiteLLM adapter for the pi-python agent runtime"
requires-python = ">=3.11"
dependencies = []

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/pi_llm"]
3 changes: 3 additions & 0 deletions packages/pi_llm/src/pi_llm/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Thin LLM adapter (LiteLLM-backed)."""

__all__: list[str] = []
13 changes: 13 additions & 0 deletions packages/pi_tui/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[project]
name = "pi_tui"
version = "0.1.0"
description = "Textual widgets and layouts for the pi-python coding CLI"
requires-python = ">=3.11"
dependencies = []

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/pi_tui"]
3 changes: 3 additions & 0 deletions packages/pi_tui/src/pi_tui/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Textual UI widgets and layouts."""

__all__: list[str] = []
48 changes: 48 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[project]
name = "pi-python"
version = "0.1.0"
description = "Python implementation aligned with earendil-works/pi semantics"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"pi_llm",
"pi_agent",
"pi_tui",
"pi_coding_agent",
]

[tool.uv.workspace]
members = [
"packages/pi_llm",
"packages/pi_agent",
"packages/pi_tui",
"packages/pi_coding_agent",
]

[tool.uv.sources]
pi_llm = { workspace = true }
pi_agent = { workspace = true }
pi_tui = { workspace = true }
pi_coding_agent = { workspace = true }

[dependency-groups]
dev = [
"pytest>=8.0",
"ruff>=0.9",
"ty>=0.0.1a16",
]

[tool.pytest.ini_options]
testpaths = ["tests", "packages"]
pythonpath = ["."]

[tool.ruff]
target-version = "py311"
line-length = 100
src = ["packages", "tests"]

[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B"]

[tool.ty.environment]
python-version = "3.11"
25 changes: 25 additions & 0 deletions tests/test_workspace_smoke.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""Smoke tests for the uv workspace scaffold (#19)."""

from __future__ import annotations

import importlib
import shutil
from importlib import metadata


def test_four_packages_are_importable() -> None:
for name in ("pi_llm", "pi_agent", "pi_tui", "pi_coding_agent"):
module = importlib.import_module(name)
assert module.__name__ == name


def test_piy_console_entrypoint_is_declared() -> None:
# Console script name must be `piy` (stub body is fine for scaffold).
eps = metadata.entry_points()
scripts = eps.select(group="console_scripts")
names = {ep.name for ep in scripts}
assert "piy" in names


def test_piy_executable_resolves_on_path() -> None:
assert shutil.which("piy") is not None
Loading
Loading