diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md index 37252e4..a2ea6d2 100644 --- a/.claude/skills/release/SKILL.md +++ b/.claude/skills/release/SKILL.md @@ -31,11 +31,14 @@ The landing verifies the publish from the run, the tag and the Release: ```bash gh run list --workflow=github-release.yml --branch main --limit 3 --json conclusion,headSha,url # the run whose headSha is the merge SHA: success, or a later one if it was cancelled -git -C
fetch --tags --prune origin && git -C
rev-list -n 1 vX.Y.Z # the tag, on the merge SHA +git -C
fetch --tags --prune origin && git -C
tag --list vX.Y.Z # the tag +git -C
rev-list -n 1 vX.Y.Z # on the merge SHA gh release view vX.Y.Z # the Release and its notes ``` -Once the tag exists, the landing proves what the release is for: every package runs by its address at the tag. From `
`, with `PIPELEX_API_KEY` set, run `.claude/skills/release/scripts/check-addresses.sh vX.Y.Z`. It lists the packages the tag itself carries, asks the hosted API's `POST /v1/validate` to fetch and validate each one at `
/@vX.Y.Z`, and spends no inference. Every line must read `✓`. A `✗` is a release that did not do its job, since the hosted fetch refuses that package at its own tag: report it with the line the script printed, and file the fix against `methods` as a bug discovered from the release item. +The `git tag --list` line is the tag's declaration: `ledger land` holds the release to it, and `ledger new --after-release methods@X.Y.Z` reads this repo's releases in that spelling. + +Once the tag exists, the landing proves what the release is for: every package runs by its address at the tag. From `
`, with `PIPELEX_API_KEY` set, run `.claude/skills/release/scripts/check-addresses.sh vX.Y.Z`. It lists the packages the tag itself carries, asks the hosted API's `POST /v1/validate` to fetch and validate each one at `
/@vX.Y.Z`, and spends no inference. Every line must read `✓`. A `✗` is a release that did not do its job, since the hosted fetch refuses that package at its own tag: report it with the line the script printed, and file the fix against `methods` as a `bug` that quotes that line. If the run failed, read its log before anything else. Its deliberate refusals, manifests that disagree and a missing changelog entry, are also what the pull request's checks assert, so either one reaching `main` means a check was bypassed. A failure from outside the repository is re-run with `gh run rerun --failed`, or, once `main` has moved on, with `gh workflow run github-release.yml --ref main`. The guards make either safe, since the tag lands on the merge commit whichever run creates it. @@ -75,4 +78,4 @@ Both act only on a head matching `^release/v([0-9]+\.[0-9]+\.[0-9]+)$` and pass - **The pull request body names the manifests.** The repo has no single version file, so the play's "Bumps version" line reads "Bumps every package manifest from `A.B.C` to `X.Y.Z`." - **Consumers pin library tags, and a release moves none of them.** The cookbook, both starters, the method-app template, the plugins and the MCP name addresses at tags of this library in their docs, samples and tests. When a release fixes something one of them pins, as `v0.1.2` did for `table_extraction`'s sample, file the move against that repo; whether and when it moves is that repo's call. - **The skill, the docs page and the workflows move together.** This skill, `docs/releasing.md` and the workflows in `.github/workflows/` state the same rules; a change to one of them changes the others in the same commit. -- **No release follow-ups are armed.** `ledger.toml` declares no `release_followups` for `methods`, so filing the release item materializes no blocked tasks; anything a release owes another repo is filed by hand beside it. +- **A release files nothing in the ledger.** Work another repo must do once this version ships, such as moving a pinned tag as the bullet above describes, is filed against that repo with `ledger new --after-release methods@X.Y.Z`, or linked onto an item already open with `ledger link --after-release methods@X.Y.Z`, and becomes ready by itself once the `vX.Y.Z` tag is in this repo's checkout. diff --git a/CHANGELOG.md b/CHANGELOG.md index 3060d8c..8fc9c2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [v0.1.6] - 2026-10-03 + +### Added + +- **`image_card`**: generates an image from a text description with the deck's small image generation model, `@default-small`, and presents the image and its description side by side in an HTML page. Its entry pipe, `generate_image_card`, takes a `description` text, like `image_generation_fast`'s `generate_image`, and returns an `Html` page. The page links the image by its storage URL, so where signed URLs are configured the image stops showing once the link expires. + ## [v0.1.5] - 2026-10-03 ### Added diff --git a/README.md b/README.md index 55f1f7e..07e3744 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ This repository is the public library of packaged [MTHDS](https://mthds.ai) meth | [`slide_designer`](methods/slide_designer/) | Turn a rough slide-deck brief into design proposals: multiple visual themes, a rendered mockup image for each, and an HTML report presenting them all | `generate_design_proposals_from_rough_brief` | | [`image_generation`](methods/image_generation/) | Generate images from text: render a description directly, or refine it into an optimized image prompt first | `illustrate` | | [`image_generation_fast`](methods/image_generation_fast/) | Generate an image quickly: render a description directly with a small, fast image generation model | `generate_image` | +| [`image_card`](methods/image_card/) | Generate an image from a description with a small, fast image generation model, and present the image and its description side by side in an HTML page | `generate_image_card` | | [`tweet_optimizer`](methods/tweet_optimizer/) | Score a draft tech tweet for fluffiness, cringiness, humblebragging and vagueness, then rewrite it in your own writing style | `optimize_tweet_sequence` | | [`text_stats`](methods/text_stats/) | Deterministic text statistics computed by a sandboxed Python function (PipeFunc, no LLM): counts, vocabulary richness, most frequent words, and estimated reading and speaking times, as a Markdown report | `analyze_text` | diff --git a/methods/cv_analyzer/METHODS.toml b/methods/cv_analyzer/METHODS.toml index f620c19..4b3a2ab 100644 --- a/methods/cv_analyzer/METHODS.toml +++ b/methods/cv_analyzer/METHODS.toml @@ -2,7 +2,7 @@ name = "cv_analyzer" display_name = "CV Analyzer" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "End-to-end candidate screening: extract a CV and a job offer, analyze the match, then either generate tailored interview questions or draft a courteous refusal email." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/doc_summarizer/METHODS.toml b/methods/doc_summarizer/METHODS.toml index 3d2cb2b..caa1ebd 100644 --- a/methods/doc_summarizer/METHODS.toml +++ b/methods/doc_summarizer/METHODS.toml @@ -2,7 +2,7 @@ name = "doc_summarizer" display_name = "Document Summarizer" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Deep document summarization: profile the document and extract importance-ranked key points in parallel, then synthesize a structured summary with themes and open questions." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/documents/METHODS.toml b/methods/documents/METHODS.toml index fed77b6..76a7b51 100644 --- a/methods/documents/METHODS.toml +++ b/methods/documents/METHODS.toml @@ -2,7 +2,7 @@ name = "documents" display_name = "Documents" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Document extraction methods for text, images, and page views." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/image_card/METHODS.toml b/methods/image_card/METHODS.toml new file mode 100644 index 0000000..69f511f --- /dev/null +++ b/methods/image_card/METHODS.toml @@ -0,0 +1,13 @@ +[package] +name = "image_card" +display_name = "Image Card" +address = "github.com/Pipelex/methods" +version = "0.1.6" +description = "Generate an image from a text description with a small, fast image model, and present the image and its description side by side in an HTML page." +authors = ["Evotis S.A.S"] +license = "MIT" +mthds_version = ">=1.0.0" +main_pipe = "generate_image_card" + +[exports.image_card] +pipes = ["generate_image_card"] diff --git a/methods/image_card/image_card.mthds b/methods/image_card/image_card.mthds new file mode 100644 index 0000000..672d7b7 --- /dev/null +++ b/methods/image_card/image_card.mthds @@ -0,0 +1,58 @@ +domain = "image_card" +description = "Generating an image from a text description and presenting the two side by side in an HTML page" +main_pipe = "generate_image_card" + +[pipe.generate_image_card] +type = "PipeSequence" +description = """ +Generate an image from a text description with a small and fast image generation model, then present the image and its description side by side in an HTML page. +""" +inputs = { description = "Text" } +output = "Html" +steps = [ + { pipe = "generate_image", result = "image" }, + { pipe = "compose_image_card", result = "image_card" }, +] + +# The same pipe as image_generation_fast's generate_image, inlined because a package must not reference another package's pipes. +[pipe.generate_image] +type = "PipeImgGen" +description = "Generate an image directly from a text description, with a small and fast image generation model" +inputs = { description = "Text" } +output = "Image" +prompt = "$description" +model = "@default-small" + +[pipe.compose_image_card] +type = "PipeCompose" +description = "Present an image and its description side by side in an HTML page" +inputs = { description = "Text", image = "Image" } +output = "Html" + +[pipe.compose_image_card.template] +category = "html" +template = """ + + + + + + Image card + + + +
+
+ {{ description }} +
+

{{ description }}

+
+ + +""" diff --git a/methods/image_card/inputs.json b/methods/image_card/inputs.json new file mode 100644 index 0000000..e86b5f7 --- /dev/null +++ b/methods/image_card/inputs.json @@ -0,0 +1,3 @@ +{ + "description": "A lighthouse keeper's desk at dusk, cluttered with brass instruments, an open logbook, and a mug of tea, warm lamplight against a stormy sea outside the window" +} diff --git a/methods/image_generation/METHODS.toml b/methods/image_generation/METHODS.toml index 340e024..604bf97 100644 --- a/methods/image_generation/METHODS.toml +++ b/methods/image_generation/METHODS.toml @@ -2,7 +2,7 @@ name = "image_generation" display_name = "Image Generation" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Image generation methods: render a description directly, or refine it into an optimized image prompt first." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/image_generation_fast/METHODS.toml b/methods/image_generation_fast/METHODS.toml index fcfdf46..6d5cc9d 100644 --- a/methods/image_generation_fast/METHODS.toml +++ b/methods/image_generation_fast/METHODS.toml @@ -2,7 +2,7 @@ name = "image_generation_fast" display_name = "Image Generation Fast" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Fast image generation: render a text description directly with a small image generation model." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/invoice_extraction/METHODS.toml b/methods/invoice_extraction/METHODS.toml index 848feee..e11e835 100644 --- a/methods/invoice_extraction/METHODS.toml +++ b/methods/invoice_extraction/METHODS.toml @@ -2,7 +2,7 @@ name = "invoice_extraction" display_name = "Invoice Extraction" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Extract structured invoice data from a document: classify each page as bill or receipt, then extract amounts, VAT, vendor and buyer details using both the OCR text and the page view." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/slide_designer/METHODS.toml b/methods/slide_designer/METHODS.toml index 41ba197..16bfff8 100644 --- a/methods/slide_designer/METHODS.toml +++ b/methods/slide_designer/METHODS.toml @@ -2,7 +2,7 @@ name = "slide_designer" display_name = "Slide Designer" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Turn a rough slide-deck brief into design proposals: polish the brief, generate multiple visual themes, render a mockup image for each, and compose an HTML report presenting them all." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/table_extraction/METHODS.toml b/methods/table_extraction/METHODS.toml index 357b3b3..354b6a2 100644 --- a/methods/table_extraction/METHODS.toml +++ b/methods/table_extraction/METHODS.toml @@ -2,7 +2,7 @@ name = "table_extraction" display_name = "Table Extraction" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Extract a data table from a screenshot into faithful HTML, then review the result against the image to correct text and formatting." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/text_stats/METHODS.toml b/methods/text_stats/METHODS.toml index ab20dc8..d71addb 100644 --- a/methods/text_stats/METHODS.toml +++ b/methods/text_stats/METHODS.toml @@ -2,7 +2,7 @@ name = "text_stats" display_name = "Text Stats" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Deterministic text statistics computed in pure Python: character, word, sentence and paragraph counts, vocabulary richness, most frequent words, and estimated reading and speaking times, reported as Markdown." authors = ["Evotis S.A.S"] license = "MIT" diff --git a/methods/tweet_optimizer/METHODS.toml b/methods/tweet_optimizer/METHODS.toml index 833f79d..dc4b964 100644 --- a/methods/tweet_optimizer/METHODS.toml +++ b/methods/tweet_optimizer/METHODS.toml @@ -2,7 +2,7 @@ name = "tweet_optimizer" display_name = "Tweet Optimizer" address = "github.com/Pipelex/methods" -version = "0.1.5" +version = "0.1.6" description = "Optimize a tech tweet: score the draft for fluffiness, cringiness, humblebragging and vagueness, then rewrite it in your own writing style following Twitter/X best practices." authors = ["Evotis S.A.S"] license = "MIT"