Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0e2e07b
codegen
lchoquel Sep 6, 2026
0b0614f
Merge origin/dev into feature/Codegen
lchoquel Sep 6, 2026
54cf04d
Add pipelex-integrate and pipelex-scaffold, the campaign's two new sk…
lchoquel Sep 6, 2026
4572156
Reconcile three defects the integrate dogfood exposed
lchoquel Sep 6, 2026
40e7890
Record the api-dev ruling and park the Python target question upstream
lchoquel Sep 7, 2026
a96292b
Merge origin/dev into feature/Codegen
lchoquel Sep 12, 2026
245c978
Name all three reasons the validate verdict carries no main_pipe
lchoquel Sep 12, 2026
161c2a1
Refuse an occupied generated directory without a sidecar naming the m…
lchoquel Sep 12, 2026
907698e
Keep the scaffold skill from offering to clear a non-empty directory
lchoquel Sep 12, 2026
be82a3b
Let the scaffold skill reach a runtime a version manager already holds
lchoquel Sep 12, 2026
82c2c15
Name the emitter's extensionless import as a known defect
lchoquel Sep 12, 2026
917ee3b
Catch a project the workshop cannot reach before generating, not after
lchoquel Sep 12, 2026
3fe3327
Record what the dogfood changed, in the designs and the decisions
lchoquel Sep 12, 2026
8356f2c
Say how to test for the key without putting it in the transcript
lchoquel Sep 12, 2026
95828e2
Close Phase 3 in the tracker, with the two scenarios that stay open
lchoquel Sep 12, 2026
47fc92b
Merge origin/dev into feature/Codegen
lchoquel Sep 12, 2026
8cfd835
Compile and run the code these skills emit, and fix what that found
lchoquel Sep 12, 2026
6a8625f
Keep the dogfood's own guards from misfiring on the states they create
lchoquel Sep 12, 2026
a9c819d
Close the write half of the key rule, and the scaffold's destructive …
lchoquel Sep 12, 2026
41c0b7a
Run the scaffold's recipes into the integrate call site, and fix what…
lchoquel Sep 12, 2026
2b72eaf
Merge origin/dev into feature/Scaffold-skill
lchoquel Sep 13, 2026
d53f3cf
Read a directory holding nothing but .git as empty
lchoquel Sep 13, 2026
51395ef
Make the scaffold's recipes keep the guarantees its references state
lchoquel Sep 13, 2026
3a57f7d
Let branch A acquire into the directory the lone-.git rule admits
lchoquel Sep 13, 2026
96bb083
Serve the destination the acquisition was written for, and the rules …
lchoquel Sep 13, 2026
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
14 changes: 10 additions & 4 deletions CHANGELOG.md

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ templates/ # SOURCE OF TRUTH — all .j2 templates live here
│ ├── pipelex-inputs/SKILL.md.j2 # inputs.json preparation (MCP-backed)
│ ├── pipelex-synthetic-inputs/SKILL.md.j2 # File factory: render PDFs/PNGs/Office files from code, no AI (no MCP dependency)
│ ├── pipelex-integrate/SKILL.md.j2 # Wire a method into a TS/Python codebase: codegen write arm, exclusions, sidecar, gate, typed call site (MCP-backed)
│ ├── pipelex-scaffold/SKILL.md.j2 # Front door to a new project: a starter through its own bootstrap, or the ecosystem's initializer (no MCP dependency)
│ └── shared/
│ ├── frontmatter.md.j2 # Common YAML frontmatter (included by templates)
│ ├── mthds-reference.md.j2 # MTHDS language reference (rendered per target)
Expand All @@ -53,7 +54,8 @@ templates/ # SOURCE OF TRUTH — all .j2 templates live here
skills/ # SOURCE OF TRUTH for static (non-templated) skill assets, copied verbatim into every target
├── pipelex-design/references/writing-mthds.md # MTHDS authoring reference
├── pipelex-synthetic-inputs/references/ # pdf.md, png.md, office.md — runnable recipes, executed by tests/recipes
└── pipelex-integrate/references/ # typescript.md, python.md, codegen-check.mjs — detection tables, call-site templates, the offline gate copied into TS projects
├── pipelex-integrate/references/ # typescript.md, python.md, codegen-check.mjs — detection tables, call-site templates, the offline gate copied into TS projects
└── pipelex-scaffold/references/ # starters.md, initializers.md — the two starters side by side, the ecosystem initializers
pipelex/ # Claude prod plugin (generated, checked in)
pipelex-codex/ # Codex plugin (generated, checked in)
pipelex-vibe/ # Mistral Vibe target (generated, checked in; loaded via skill_paths; mcp/vibe-mcp.toml copied into ~/.vibe/config.toml)
Expand Down Expand Up @@ -146,4 +148,4 @@ So there is nothing to enable — the bundled hook loads on its own (hooks are S

The plugin imports nothing and requires no install. Validation rides on the vendored `check.mjs` bundle (wasm engine + `@pipelex/sdk` → hosted API) and, for the MCP-backed skills (`pipelex-design`, `pipelex-organize`, `pipelex-edit`, `pipelex-inputs`, `pipelex-integrate`), on the plugin-declared `pipelex-mcp` server (tools `mthds_validate` / `mthds_inputs_template`; `mthds_codegen`, whose write arm — `output_dir`, relative to the workshop's working directory — writes `pipelex-integrate`'s generated trees to disk so no artifact byte passes through the model; `mthds_prepare_inputs`, which uploads `pipelex-inputs`' file-bearing values to Pipelex storage and rewrites them to `pipelex-storage://` references so a run can reach them; plus the `mthds_run` family powering `pipelex-inputs`' closing offer to run; declared in the Claude and Codex manifests, and shipped on Vibe as the `mcp/vibe-mcp.toml` config fragment the user copies into `~/.vibe/config.toml`). The baked declaration is the **local workshop launcher** — `npx -y @pipelex/mcp@latest` over stdio, from the `[vars.mcp_server]` block in `targets/defaults.toml` — never a hosted URL: the hosted console is a connector users add in their host's own UI (see the README's "One install, one server" section and `docs/decisions.md`). Credential delivery: on Claude the manifest's `userConfig` prompts for the API key / base URL at enable time (keychain-stored) and the MCP entry spawns the `launch-pipelex-mcp.sh` wrapper, which receives them as `PIPELEX_PLUGIN_*` via `${user_config.*}` substitution and promotes each to `PIPELEX_API_KEY`/`PIPELEX_BASE_URL` **only when non-empty** — the canonical credential channel (required for Claude Desktop, which carries no shell env), with the non-empty guard keeping an unfilled option from shadowing a shell-exported key; injecting `PIPELEX_*` directly instead makes an empty option surface as a config-class `Unauthorized` that hard-stops every MCP-backed skill; on Codex the manifest forwards `PIPELEX_API_KEY`/`PIPELEX_BASE_URL` by name via `env_vars` because Codex whitelist-filters MCP spawn env; on Vibe the user writes the key into the fragment's `env` table, because Vibe also spawns stdio servers with a minimal environment and expands no variables in its config. Dev override: point `command`/`args` at a local checkout in `targets/defaults.toml` + `make build` on Claude; a same-named `[mcp_servers.pipelex]` entry in `~/.codex/config.toml` on Codex.

**`pipelex-synthetic-inputs` depends on none of that.** It is the second MCP-free skill after `pipelex-explain` — no tool, no key, no Pipelex service — and its only dependency is a Python it can reach: `uv` with ephemeral `--with` packages on the normal rung, and a venv it creates itself under `${XDG_CACHE_HOME:-$HOME/.cache}/pipelex-plugins/synth-venv` when `uv` is absent. Swapping the runner line is the *only* difference between the two rungs, and `tests/recipes` proves it by running real recipes through both. When neither rung is reachable the skill stops with the exact missing piece and, called from `pipelex-inputs`, returns no path so that one input is left unfilled rather than aborting the flow. Keep it out of the `MCP_SKILLS` tuple in `tests/unit/test_gen_skill_docs.py`.
**`pipelex-synthetic-inputs` depends on none of that.** It is the second MCP-free skill after `pipelex-explain` — no tool, no key, no Pipelex service — (`pipelex-scaffold` is the third: git, the starters' own bootstrap scripts and the ecosystem's initializers are all it uses, and it hands every project it creates to `pipelex-integrate`) and its only dependency is a Python it can reach: `uv` with ephemeral `--with` packages on the normal rung, and a venv it creates itself under `${XDG_CACHE_HOME:-$HOME/.cache}/pipelex-plugins/synth-venv` when `uv` is absent. Swapping the runner line is the *only* difference between the two rungs, and `tests/recipes` proves it by running real recipes through both. When neither rung is reachable the skill stops with the exact missing piece and, called from `pipelex-inputs`, returns no path so that one input is left unfilled rather than aborting the flow. Keep it and `pipelex-scaffold` out of the `MCP_SKILLS` tuple in `tests/unit/test_gen_skill_docs.py`.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ This is the plugin generation that pairs with the hosted Pipelex API and the (cl

## What's inside

- **Skills** — Pipelex skills for working with MTHDS bundles: `pipelex-explain` (read and explain a bundle), `pipelex-design` (design a method contract-first with a complexity-adaptive workflow: build a fully understood shallow graph directly as a coherent runnable bundle, or use validated signature-driven refinement for deep, uncertain, staged, or resumable work), `pipelex-organize` (regroup a construction-shaped or otherwise awkward layout into coherent module files — or a single file when the method is simple — proven equivalent through the MCP validation verdict; automatically follows `pipelex-design` only when the converged layout needs it), `pipelex-edit` (contract-preserving edits to an existing bundle — prompts, model references, mechanical renames — proven with a before/after MCP validation verdict; structural or contract changes route to `/pipelex-design`, which re-enters the affected region directly or through signatures according to its complexity), `pipelex-inputs` (prepare an `inputs.json` for a method — placeholder template, synthetic data, user files, or a mix — from the input template the MCP server projects; targets a local bundle or a registered catalog method by its `mt_…` id, uploads any local files to Pipelex storage so the run can reach them, and closes by offering to start the run through the MCP run tools), `pipelex-synthetic-inputs` (render the files a method needs when the user has none — PDFs through reportlab, PNGs through Pillow and matplotlib as charts, diagrams, scanned-looking pages or app screenshots, plus Word and Excel; `pipelex-inputs` delegates to it for every file-typed input), `pipelex-integrate` (wire a method into an existing TypeScript or Python codebase: the workshop's `mthds_codegen` writes drift-proof generated types into one directory per method, the skill excludes that tree from formatters, records a `sources.json` sidecar, wires the offline drift check into the project's gate on TypeScript, and writes one typed call site that runs the method through `@pipelex/sdk` or `pipelex-sdk`; a project made from a Pipelex starter keeps its own codegen harness).
`pipelex-synthetic-inputs` is the plugin's second MCP-free skill after `pipelex-explain`: it needs no API key and no Pipelex service. It renders files from code — no image-generation model, no hosted method — using only packages whose licences are compatible with MIT, and it installs them itself, through `uv`'s ephemeral environments or an isolated venv under your cache directory when `uv` is absent. Nothing is installed into your project, and installing a *tool* always asks first. Photographs and handwriting are deliberately out of scope: code cannot render either convincingly, and the skill asks for your own file rather than handing a method an imitation.
- **Skills** — Pipelex skills for working with MTHDS bundles: `pipelex-explain` (read and explain a bundle), `pipelex-design` (design a method contract-first with a complexity-adaptive workflow: build a fully understood shallow graph directly as a coherent runnable bundle, or use validated signature-driven refinement for deep, uncertain, staged, or resumable work), `pipelex-organize` (regroup a construction-shaped or otherwise awkward layout into coherent module files — or a single file when the method is simple — proven equivalent through the MCP validation verdict; automatically follows `pipelex-design` only when the converged layout needs it), `pipelex-edit` (contract-preserving edits to an existing bundle — prompts, model references, mechanical renames — proven with a before/after MCP validation verdict; structural or contract changes route to `/pipelex-design`, which re-enters the affected region directly or through signatures according to its complexity), `pipelex-inputs` (prepare an `inputs.json` for a method — placeholder template, synthetic data, user files, or a mix — from the input template the MCP server projects; targets a local bundle or a registered catalog method by its `mt_…` id, uploads any local files to Pipelex storage so the run can reach them, and closes by offering to start the run through the MCP run tools), `pipelex-synthetic-inputs` (render the files a method needs when the user has none — PDFs through reportlab, PNGs through Pillow and matplotlib as charts, diagrams, scanned-looking pages or app screenshots, plus Word and Excel; `pipelex-inputs` delegates to it for every file-typed input), `pipelex-integrate` (wire a method into an existing TypeScript or Python codebase: the workshop's `mthds_codegen` writes drift-proof generated types into one directory per method, the skill excludes that tree from formatters, records a `sources.json` sidecar, wires the offline drift check into the project's gate on TypeScript, and writes one typed call site that runs the method through `@pipelex/sdk` or `pipelex-sdk`; a project made from a Pipelex starter keeps its own codegen harness), and `pipelex-scaffold` (start a project where none exists — one of the Pipelex starter templates run through its own `bootstrap` skill, or the ecosystem's initializer — and hand it to `pipelex-integrate`).
`pipelex-synthetic-inputs` is the plugin's second MCP-free skill after `pipelex-explain` (`pipelex-scaffold` is the third — it needs only git, the starters' own scripts and the ecosystem's initializers): it needs no API key and no Pipelex service. It renders files from code — no image-generation model, no hosted method — using only packages whose licences are compatible with MIT, and it installs them itself, through `uv`'s ephemeral environments or an isolated venv under your cache directory when `uv` is absent. Nothing is installed into your project, and installing a *tool* always asks first. Photographs and handwriting are deliberately out of scope: code cannot render either convincingly, and the skill asks for your own file rather than handing a method an imitation.

- **Hooks** — a CLI-free validation hook that checks `.mthds` files on edit (Claude/Codex `PostToolUse`, Mistral Vibe `post_tool`). On every target, lint and format run locally through a bundled WASM engine (offline, no credentials — the file is also auto-formatted in place), and full semantic validation calls the hosted Pipelex API when `PIPELEX_API_KEY` is set. Everything fails open: no Node → the hook no-ops; no key / API unreachable → only the validate stage is skipped. See [docs/hooks.md](docs/hooks.md).
- **MCP server declaration** — on Claude Code and Codex the plugin declares the `pipelex-mcp` server as the **local workshop launcher** (`npx -y @pipelex/mcp@latest`, stdio; tools `mthds_validate` for bundle validation (its verdict carries the main pipe's signature, which `pipelex-integrate` types call sites from), `mthds_inputs_template` for input templates, `mthds_codegen` to project a method's concepts into typed code (`ts-zod`, `python-pydantic`, `python-structures`) and, with `output_dir`, write the tree to disk, `mthds_prepare_inputs` to upload a filled template's file values to Pipelex storage so a run can reach them, and the `mthds_run` family for durable runs — each takes submitted file contents or a registered method's catalog id (`mt_…`) as `method_id`, operating on the method's current stored content; by-id calls require an API key since the catalog is org-scoped), which the MCP-backed skills require. The harness spawns it automatically at session start, and it authenticates to the Pipelex API with the key from the plugin configuration (prompted at enable time on Claude Code) or, as a fallback, `PIPELEX_API_KEY` from your session environment — the same credential the hook uses. On Mistral Vibe, which has no plugin manifest, the target ships the same launcher as a config fragment instead: nothing is spawned until you add it to `~/.vibe/config.toml`, and the server takes its key only from that entry's `env` table, never from your shell (see [Mistral Vibe](#mistral-vibe)). Unlike the fail-open hook, the MCP-backed skills stop with a setup instruction when the tools are absent. The hosted console is never baked into the plugin — see [One install, one server](#one-install-one-server--workshop-vs-console) and [docs/decisions.md](docs/decisions.md).
Expand Down
2 changes: 1 addition & 1 deletion docs/build-targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ scripts/gen_skill_docs.py renders .j2 templates with merged variables

**`templates/`** holds all `.j2` source files. Never edit files in `pipelex/`, `pipelex-codex/`, or `pipelex-vibe/` directly — they are generated output.

**`skills/`** at the repo root (if present) holds only static per-skill assets (`references/` subdirectories) that are copied into every target. Several skills use it — `pipelex-design`, `pipelex-synthetic-inputs`, `pipelex-integrate` — and a reference need not be Markdown: `pipelex-integrate` ships `codegen-check.mjs`, a script the skill copies verbatim into TypeScript projects, so a reference edit is followed by `make build` and, for a script, by running it (`node --check` at the least). **`pipelex/`**, **`pipelex-codex/`**, and **`pipelex-vibe/`** are generated output directories (build artifacts checked into git).
**`skills/`** at the repo root (if present) holds only static per-skill assets (`references/` subdirectories) that are copied into every target. Several skills use it — `pipelex-design`, `pipelex-synthetic-inputs`, `pipelex-integrate`, `pipelex-scaffold` — and a reference need not be Markdown: `pipelex-integrate` ships `codegen-check.mjs`, a script the skill copies verbatim into TypeScript projects, so a reference edit is followed by `make build` and, for a script, by running it (`node --check` at the least). **`pipelex/`**, **`pipelex-codex/`**, and **`pipelex-vibe/`** are generated output directories (build artifacts checked into git).

## Target configuration

Expand Down
Loading
Loading