Metadata-Version: 2.4
Name: promptex-py
Version: 1.1.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: License :: OSI Approved :: Apache Software License
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: Programming Language :: Rust
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Code Generators
Classifier: Typing :: Typed
License-File: LICENSE-APACHE
License-File: LICENSE-MIT
Summary: Python SDK、核心的預編譯二進位綁定與命令列工具，三者為同一次發布產出
Keywords: prompt,prompt-engineering,ai,llm,agent,claude,codex,mcp,skills,codegen
Author: promptex-ai
License: MIT OR Apache-2.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Changelog, https://github.com/promptex-ai/promptex/blob/main/CHANGELOG.md
Project-URL: Homepage, https://github.com/promptex-ai/promptex
Project-URL: Issues, https://github.com/promptex-ai/promptex/issues
Project-URL: Repository, https://github.com/promptex-ai/promptex

# promptex-py

Declare prompt resources in Python, compile them into whatever your AI coding tool
expects on disk.

Skills, rules, agents, hooks, MCP servers and permissions are ordinary files in a
directory tree, and every tool wants that tree laid out its own way. This package
lets you declare each resource once and project the result onto a target platform.
It ships the Python SDK, a precompiled native extension bound to the shared core,
and the `promptex` command line tool.

## Install

```console
pip install promptex-py
```

Requires Python 3.10 or newer. Wheels carry the native extension, so there is no
Rust toolchain to install.

To start a new project, or to add promptex to an existing one, use
[`create-promptex-py`](../create-promptex-py/README.md). It writes the config file
and an example, and leaves your existing files alone:

```console
uvx create-promptex-py .
uv add promptex-py
uv run promptex build --install
```

## Minimal example

Declarations live in a `prompts/` directory. Anything you `define_*` at module
scope is registered when the file is evaluated.

```python
# my_project/prompts/review.py
from promptex import define_skill

define_skill(
    id="code-review",
    name="Code Review",
    description="Reviews a pull request for correctness and readability",
    config={"whenToUse": "Reviewing a pull request"},
    content="Check correctness first, then readability.",
)
```

Point the command line tool at the directory that *contains* `prompts/`:

```console
$ promptex build --install my_project --out my_project --platform claude
✓ Metadata written (graph + content)
  wrote .claude/skills/code-review/SKILL.md
Install report (claude)
  Projected artifacts, 1: .claude/skills/code-review/SKILL.md
```

Which writes:

```text
my_project/.claude/skills/code-review/SKILL.md
```

```markdown
---
name: code-review
description: Reviews a pull request for correctness and readability
when_to_use: Reviewing a pull request
---

Check correctness first, then readability.
```

Switch `--platform codex` and the same declaration lands in Codex's layout instead.

## Commands

| Command | What it does |
| :--- | :--- |
| `promptex build <dir>` | Compile and refresh the framework metadata under `.promptex/`. No platform artifacts, no ownership registry, no pruning. |
| `promptex build --install <dir>` | Compile, write the platform artifacts, record ownership, and prune what you deleted. This is the one to use for real installs. |
| `promptex build --install --dry-run <dir>` | Show what `--install` would change, without writing anything. Add `--content --json` to get the bytes it would write. |
| `promptex build --export <export-dir> <dir>` | Write the exact tree `--install` would write under `<export-dir>/<unit>/`, with no registry. The unit subtree is cleared first. |
| `promptex build --watch <dir>` | Rerun the same flags (`build` alone, `--install` or `--export`) as sources change. |
| `promptex manifest <dir>` | Answer registry queries from the current projection. |
| `promptex init <dir>` | Deprecated, removed in 2.0. Use `uvx create-promptex-py <dir>` instead. |
| `promptex version` | Report the package version, the language and the flags each command supports (`--json` for the machine-readable form). |

Common flags: `--out <install root>` (single-directory mode), `--platform <name>` (`manifest` only), `--unit <unit name>`, `--json`, `--locale <tag>`.

## Machine-readable output

`--json` makes a command print one JSON document on stdout. Every document, and every
file the tool writes under `.promptex/`, carries `formatVersion` (currently `"1.1"`).
Within 1.x the version only gains keys, so read the keys you know and ignore the rest.

`promptex version --json` reports the package, the language and what this CLI
supports, so a caller can check a feature before using it:

```json
{"formatVersion":"1.1","package":{"name":"promptex-js","version":"1.0.1"},"language":"ts",
 "capabilities":{"verbs":{"build":{"flags":["--install","--dry-run","…"]},"version":{"flags":[]}},
                 "globalFlags":["--json","--locale"]}}
```

A failing command with `--json` prints an error document on stdout and the same
message on one line of stderr:

```json
{"formatVersion":"1.1","error":{"code":"USAGE_UNKNOWN_FLAG","message":"Unknown flag: --foo","details":{"flag":"--foo","usage":"…"}}}
```

- `code` is stable. A `USAGE_` code means the call was wrong. A `RUN_` code means the
  call was fine and the work failed. Branch on `code`, never on `message`, which is
  localized and may change.
- `details` is always an object. Its keys are fixed per code and identical in all three
  languages. Its values (paths, usage text) may differ.
- Exit code is `1` for every failure of the existing commands, usage errors included,
  as before. A usage error of `version` exits with `2`.
- `config` always prints a JSON document, with or without `--json`. When it fails, that
  document is the error document. A `config write` that is refused is a result, not an
  error: the result document is printed and the exit code is `1`.
- `build --watch` prints each failed round for a person to read and emits no error
  document, because watching is a long-running loop.

## What you can declare

`define_skill`, `define_rule`, `define_agent`, `define_instruction`,
`define_resource`, `define_hook`, `define_mcp`, `define_permission`,
`define_asset`, `define_dir`.

Each `define_*` takes either keyword arguments or one spec object from the
`promptex.kinds` module (`SkillDef`, `RuleDef`, `AgentDef`, `InstructionDef`,
`ResourceDef`, `HookDef`, `McpDef`, `PermissionDef`, `AssetDef`, `DirDef`). The
two forms produce byte-identical intermediate representations. Spec objects are
for shared packages: a pure function returns the spec, and each unit calls
`define_rule(rule_def(...))` in its own source file, so the node's recorded
source location is the caller's line, not the package's.

```python
from promptex import RuleDef, define_rule

def lint_rule_def(spec) -> RuleDef:
    return RuleDef(id=spec.id, name=spec.name, content=spec.statement)

define_rule(lint_rule_def(spec))
```

Per-platform native settings are not declared in your sources: they belong to the
target, so you write them as `claude(settings={…})` in `promptex.config.py`. Keys
pass through verbatim into that platform's own settings file and the framework
keeps no allowlist.

Larger projects add a `promptex.config.py` with `define_config` to split the tree
into units, and register third-party platforms with `define_target`.

## Notes

The SDK's evaluation path depends on nothing outside the standard library: writing
and evaluating declarations never touches the native extension. The extension is
loaded only once work moves past evaluation, which is also why the test suite runs
with no build step.

Everything past evaluation — projection, install, registry, graph, diagnostics —
happens in a shared Rust core called in-process, not as a subprocess. The
TypeScript and Rust packages call the same core, so identical declarations produce
byte-identical output across all three.

## Links

- Source and issues: <https://github.com/promptex-ai/promptex>
- Architecture notes: <https://github.com/promptex-ai/promptex/blob/main/docs/architecture.md>

## License

Dual-licensed under either of MIT or Apache-2.0, at your option. See `LICENSE-MIT`
and `LICENSE-APACHE`.

