Skip to content

ci: post story screenshots at ai-loop handoff (#284) - #352

Merged
allxsmith merged 5 commits into
mainfrom
feat/story-screenshots-handoff
Jul 26, 2026
Merged

allxsmith merged 5 commits into
mainfrom
feat/story-screenshots-handoff

Conversation

@allxsmith

@allxsmith allxsmith commented Jul 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

Gives the human reviewer eyes at handoff (#284): when an ai-loop PR flips to needs-human-review, a new story-screenshots.yml workflow captures the Storybook stories affected by the PR's changed files with Playwright — once light, once dark — and posts them to the PR as an upserted <!-- story-screenshots --> comment with inline images, plus a 30-day workflow artifact. The loop's reviewers are text-only; CSS bugs invisible to jsdom survived four review rounds on #257.

How it works

  • bulma-ui/scripts/capture-stories.mjs maps changed files → story IDs via storybook-static/index.json: importPath for a changed *.stories.tsx, componentPath (index v5) for a changed component, basename heuristic for scss (_carousel.scss → Carousel.stories.tsx). Caps at 6 stories/file, 24 total (skipped IDs listed in the comment). Each story is screenshotted on a fresh page load per theme — an in-place toggle leaves mid-transition colors from the other theme in the picture.
  • Dark mode needs emulated prefers-color-scheme, not just data-theme: the preview loads bulma.min.css then bulma-prefixed.min.css, and the prefixed file's media-scoped light :root block outranks the unprefixed [data-theme=dark] block in the cascade (equal specificity, later wins). The attribute alone changes nothing — verified empirically. ⚠ This means the existing smoke test's STORYBOOK_THEME=dark pass isn't actually rendering dark either; that's a separate fix outside this PR's scope.
  • story-screenshots.yml splits privileges like visual-regression.yml: the capture job runs PR code with a read-only token (reuses the CI run's storybook artifact for the pinned head SHA when present — at loop handoff CI is green by definition — and builds as fallback); the publish job holds contents: write + pull-requests: write, runs no PR code, and treats everything from capture as untrusted (filename charset whitelist, HTML-escaped titles, env-var injection only).
  • Images are committed via the git data API (verified commits) to the disposable orphan branch story-screenshots under pr-<n>/<run-id>/ — run-id-unique paths so GitHub's Camo proxy never serves a stale cache. Deleting the branch only breaks images in old handoff comments; the next run re-bootstraps it.
  • Trigger: the loop dispatches the workflow at both handoff sites — label edits via GITHUB_TOKEN fire no labeled runs (GitHub's recursion guard), but workflow_dispatch via API does. The pull_request: [labeled] trigger covers a human applying the label by hand (same-repo guard; pull_request_target deliberately avoided since this builds PR code).
  • Changed-files-but-no-matching-stories posts an explicit "nothing to screenshot" comment rather than silence, and re-handoffs upsert (latest-wins) instead of stacking comments.

Verified locally

  • Fake diff (Block.tsx + _carousel.scss) → 28 stories matched (componentPath + scss paths), capped to 12, all captured; light/dark PNGs eyeballed correct (including the extras' Carousel SCSS going dark).
  • Edge probes: empty list → clean exit + empty manifest; --max 2 → skipped list populated.
  • Both workflows YAML-parse; the embedded publish script was dry-run end-to-end against the real manifest with a stubbed GitHub API (bootstrap-on-404, 24 blobs, append commit, comment body renders correctly).
  • eslint + prettier clean.

Post-merge verification plan

  1. Apply needs-human-review to a trivial test PR (labeled path, artifact reuse) → comment renders images.
  2. gh workflow run story-screenshots.yml -f pr=<n> on the same PR → comment is edited in place, new run-id dir on the branch.
  3. Delete story-screenshots branch, re-dispatch → bootstrap works.
  4. Next organic handoff → dispatch fires from the loop (handoff job log).

Note: the docs paragraph in ai-development.md also rides on #347 (it was swept into that branch's commit) — the text is identical, so the two merge cleanly in either order.

Closes #284

Summary by CodeRabbit

  • New Features
    • Automatically captures and posts updated Storybook screenshots (light + dark) as a single upserted pull request comment when a pull request reaches human review.
    • Uses handoff/escalation to trigger screenshot rendering, with manual workflow triggering available when needed.
    • Retains screenshots for 30 days and publishes images to a dedicated screenshots branch, updating on subsequent runs; reports “nothing to screenshot” and links screenshot failures with a rerun command.
  • Documentation
    • Added a “Screenshots at handoff” guide, including what happens during the flow and how to trigger capture manually.

Give the human reviewer eyes at handoff: when an ai-loop PR flips to
needs-human-review, a new story-screenshots.yml workflow captures the
Storybook stories affected by the PR's changed files with Playwright —
once light, once dark — and posts them to the PR as an upserted marker
comment (inline images) plus a 30-day artifact. The loop's reviewers are
text-only; CSS bugs invisible to jsdom survived four review rounds on
PR #257, and a picture at handoff is the cheapest catch.

- bulma-ui/scripts/capture-stories.mjs maps changed files to story IDs
  via storybook-static/index.json (importPath for changed stories files,
  componentPath for changed components, basename heuristic for scss),
  serves the built storybook, and screenshots each story per theme on a
  fresh load. Dark needs emulated prefers-color-scheme, not just the
  data-theme attribute: bulma-prefixed.min.css loads after bulma.min.css
  and its media-scoped light :root block outranks the unprefixed
  [data-theme=dark] block in the cascade.
- story-screenshots.yml splits privileges: `capture` runs PR code with a
  read-only token (reusing the CI run's storybook artifact when present,
  building as fallback); `publish` holds the write scopes, runs no PR
  code, treats capture output as untrusted (filename whitelist, escaped
  titles), commits images to the disposable orphan branch
  story-screenshots for raw.githubusercontent embedding, and upserts the
  <!-- story-screenshots --> comment.
- claude-pr-loop.yml dispatches the workflow at both handoff sites —
  label edits via GITHUB_TOKEN fire no `labeled` runs (recursion guard),
  workflow_dispatch does. The labeled trigger covers humans applying the
  label by hand.

Closes #284
@coderabbitai

coderabbitai Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 70051207-d6bc-4225-ae33-31f84b73d845

📥 Commits

Reviewing files that changed from the base of the PR and between 55d4850 and a48bc14.

📒 Files selected for processing (4)
  • .github/workflows/claude-pr-loop.yml
  • .github/workflows/story-screenshots.yml
  • bulma-ui/scripts/capture-stories.mjs
  • docs/docs/guides/getting-started/ai-development.md

Walkthrough

Adds automated Storybook screenshot capture for affected stories during AI-loop handoff, including light and dark themes, artifact publication, pull request comments, failure reporting, and documentation for manual runs.

Changes

Story screenshot handoff

Layer / File(s) Summary
Handoff dispatch wiring
.github/workflows/claude-pr-loop.yml
The AI loop dispatches story-screenshots.yml during handoff and contested-thread escalation, with actions: write permission.
Screenshot workflow capture
.github/workflows/story-screenshots.yml
The workflow validates the pull request, prepares or reuses Storybook, runs the capture CLI, and uploads results.
Story selection and themed capture
bulma-ui/scripts/capture-stories.mjs
Changed source files are mapped to safe Storybook stories, which are captured in light and dark themes with manifest status tracking.
Publication and handoff documentation
.github/workflows/story-screenshots.yml, docs/docs/guides/getting-started/ai-development.md
Screenshots are stored on the story-screenshots branch and published through upserted pull request comments; publication, failure, and manual-run behavior is documented.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AI Loop
  participant Story Screenshots
  participant Storybook
  participant Playwright
  participant GitHub PR
  AI Loop->>Story Screenshots: dispatch with PR number
  Story Screenshots->>Storybook: build or reuse static output
  Story Screenshots->>Playwright: capture affected stories in light and dark themes
  Playwright-->>Story Screenshots: PNGs and manifest
  Story Screenshots->>GitHub PR: publish artifact and upsert screenshot comment
Loading

Possibly related PRs

  • allxsmith/bestax#216: Updates the AI-loop handoff workflow that now dispatches screenshot capture.
  • allxsmith/bestax#246: Modifies terminal-state routing in the same workflow area used by screenshot dispatch.

Suggested labels: released, deep-review

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: posting story screenshots at ai-loop handoff.
Description check ✅ Passed The description is detailed, but it doesn't fully mirror the template sections for package/type/checklist; the core summary, issue link, and verification are present.
Linked Issues check ✅ Passed The PR implements handoff-triggered Playwright screenshots of changed stories in light and dark themes, with comments and artifacts, matching #284.
Out of Scope Changes check ✅ Passed The added docs, workflow, and capture script all support the screenshot-at-handoff feature, with no clear unrelated changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/story-screenshots-handoff

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://07acc85f.bestax.pages.dev

@allxsmith

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@allxsmith

Copy link
Copy Markdown
Owner Author

@claude deep review

@claude

claude Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

Claude finished @allxsmith's task in 6m 26s —— View job


Deep review

  • Gather context (read the commit diff directly — shallow clone has no merge-base with main)
  • Review .github/workflows/story-screenshots.yml
  • Review .github/workflows/claude-pr-loop.yml changes
  • Review bulma-ui/scripts/capture-stories.mjs
  • Review docs change
  • Post findings

This is an unusually well-documented PR — the security split (read-only capture / write-only publish, matching visual-regression.yml's pattern), the SAFE_ID/SAFE_PNG charset whitelisting before any filename/URL use, the HTML-escaping of untrusted story titles, and the path.normalize-on-an-absolute-pathname static-file-server (traversal-safe because URL.pathname is always root-anchored) all check out. I traced the dark-mode cascade fix, the per-PR/per-run-id orphan-branch paths (Camo-cache-safe), and the upsert/marker-comment logic — no correctness bugs found there.

One real gap:

No signal if the capture job itself fails or times out. publish (.github/workflows/story-screenshots.yml:174-176) only runs via needs: capture with no if: override, so GitHub Actions auto-skips it when capture doesn't succeed — meaning a genuine failure looks identical to "nothing to screenshot" from the reviewer's side (no comment, no artifact, no error). Concretely: the capture job has a 20-minute timeout (story-screenshots.yml:47), and shoot()'s per-theme budget is up to 30s goto + 15s waitForSelector (capture-stories.mjs:206-219) — at the 24-story cap that's a plausible way to blow the timeout on a slow runner, or Playwright/Chromium install can hit a transient network failure. Either way the job is killed/fails, publish is skipped, and the human at handoff sees silence where the PR's own design goal was "changed-files-but-no-matching-stories posts an explicit comment rather than silence." A publish-adjacent job/step gated on if: always() && needs.capture.result == 'failure' that posts a short "screenshot pass failed — see run" comment would close that gap.

Fix this →

Everything else — claude-pr-loop.yml's two dispatch sites (fix job's terminal-state escalation and the handoff job), the new actions: write grant on handoff, and the docs update in ai-development.md — matches the implementation and is internally consistent.
· branch

allxsmith and others added 2 commits July 25, 2026 17:57
The deep review on #352 caught a silent-failure gap: `publish` hangs off a
plain `needs: capture`, so Actions auto-skips it whenever capture fails or
hits its 20-minute timeout. A skipped publish is silence — which is exactly
what a healthy "nothing to screenshot" run looks like from the PR. A
Playwright install that 500s would read to the reviewer as "no CSS to look
at here", defeating the point of putting eyes on the handoff.

Add a report-failure job, gated on `needs.capture.result == 'failure'`, that
upserts the same marker comment with the failure and a link to the run.
Reusing the comment means the notice also supersedes images from an earlier
run, rather than leaving stale ones to pass as current. `failure` only:
`cancelled` is the concurrency group retiring a superseded run and `skipped`
is the label guard, neither of which is news. When capture dies before
resolving a PR number — the deliberate refusals, closed or cross-repo — the
job stays silent, since declining to run is not breakage.

The marker moves to a workflow-level env var so the two jobs that upsert
that comment cannot drift apart and start stacking two of them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014se1ctqQjBCBaqjQRfHdzi
@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://5c5f97e4.bestax.pages.dev

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
.github/workflows/story-screenshots.yml (3)

47-51: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Reject protected-configuration PRs before capture.

The eligibility check only looks for bulma-ui/src/; an AI-loop PR that also changes .github/**, Jest, commitlint, release, or pnpm-workspace configuration is still checked out, built, captured, and published. Add a read-only preflight that marks such PRs ineligible and gate all downstream jobs on it.

As per coding guidelines, “Do not allow the AI development loop to process pull requests that modify .github/** or jest, commitlint, release, or pnpm-workspace configuration.”

Also applies to: 96-113

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/story-screenshots.yml around lines 47 - 51, Add a
read-only preflight job that detects pull requests modifying .github/** or Jest,
commitlint, release, or pnpm-workspace configuration, marks those PRs
ineligible, and expose its result as an output. Update the
workflow_dispatch/pull-request eligibility condition and all downstream jobs to
require the preflight approval, while preserving manual dispatch behavior.

Source: Coding guidelines


248-283: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle already-exists bootstrap races for story-screenshots.

Concurrency is per PR, so two first-time PR runs can both observe a missing story-screenshots ref. Both may run the bootstrap path and both then await createRef; the first can succeed while the later one fails before it reaches the append retry loop, so the PR gets no handoff comment. Catch the ref-already-exists response, fetch heads/${BRANCH}, and fall through to the existing append retry path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/story-screenshots.yml around lines 248 - 283, Update the
bootstrap logic around createRef in the story-screenshots workflow to handle an
already-existing ref caused by concurrent runs. Catch the specific
ref-already-exists response from github.rest.git.createRef, fetch the current
heads/${BRANCH} ref to refresh tip, and continue into the existing append retry
path; rethrow unrelated errors and preserve the current bootstrap behavior when
creation succeeds.

64-82: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Pin the changed-file list to the resolved base/head SHAs.

gh pr diff "$PR" reads the PR’s current diff at runtime, while head_sha is pinned from the resolved PR metadata. If push/the PR branch advances after Resolve PR, the checkout can use the old head while changed-file detection uses the new one. Fetch baseRefOid and run a pinned compare like gh pr diff "$PR" ... --base "$BASE_SHA" --head "$HEAD_SHA" or use the compare API against the stored bases/heads.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/story-screenshots.yml around lines 64 - 82, Update the
Resolve PR step to also retrieve and expose the resolved base SHA, alongside
head_sha. In the changed-file detection flow, replace the unpinned gh pr diff
invocation with a comparison explicitly using the stored base and head SHAs,
ensuring file detection matches the checkout selected by Resolve PR.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/docs/guides/getting-started/ai-development.md`:
- Line 97: Update the manual story-screenshots workflow command in the
getting-started documentation to use a shell-safe concrete pull request value
such as 123, and note that readers should replace it with the relevant pull
request number. Keep the existing command and surrounding instructions
unchanged.

---

Outside diff comments:
In @.github/workflows/story-screenshots.yml:
- Around line 47-51: Add a read-only preflight job that detects pull requests
modifying .github/** or Jest, commitlint, release, or pnpm-workspace
configuration, marks those PRs ineligible, and expose its result as an output.
Update the workflow_dispatch/pull-request eligibility condition and all
downstream jobs to require the preflight approval, while preserving manual
dispatch behavior.
- Around line 248-283: Update the bootstrap logic around createRef in the
story-screenshots workflow to handle an already-existing ref caused by
concurrent runs. Catch the specific ref-already-exists response from
github.rest.git.createRef, fetch the current heads/${BRANCH} ref to refresh tip,
and continue into the existing append retry path; rethrow unrelated errors and
preserve the current bootstrap behavior when creation succeeds.
- Around line 64-82: Update the Resolve PR step to also retrieve and expose the
resolved base SHA, alongside head_sha. In the changed-file detection flow,
replace the unpinned gh pr diff invocation with a comparison explicitly using
the stored base and head SHAs, ensuring file detection matches the checkout
selected by Resolve PR.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 799fe662-c448-4c2a-8fdd-ed2314e01fb5

📥 Commits

Reviewing files that changed from the base of the PR and between 05efb18 and c7a5b1d.

📒 Files selected for processing (2)
  • .github/workflows/story-screenshots.yml
  • docs/docs/guides/getting-started/ai-development.md

Comment thread docs/docs/guides/getting-started/ai-development.md Outdated
`-f pr=<number>` looks like a placeholder but a shell reads `<number>` as
input redirection, so copying the line verbatim fails on a missing file
rather than running the workflow. Use a concrete number and say to swap it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014se1ctqQjBCBaqjQRfHdzi
@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://3aa57f20.bestax.pages.dev

Three findings from the CodeRabbit review, posted outside the diff range.

Pin the changed-file list to the resolved SHAs. "Resolve PR" pins head_sha
and the checkout uses it, but the file list came from `gh pr diff <n>`, which
re-reads the PR's current diff — so a push landing in between paired the new
head's file list with the old head's checkout. The step comment already
claimed the diff was pinned; now it is, via a three-dot compare of the
recorded base and head.

Survive losing the orphan-branch bootstrap race. Concurrency is per-PR, so
two first-ever runs can both see the 404 and both bootstrap; the loser's
createRef threw 422 and killed the job before the append retry loop, costing
that PR its handoff comment. Adopt the winner's branch and fall through.
Verified against a stubbed API: pre-fix the race throws and posts nothing,
post-fix it commits and comments.

Extend the failure notice to `publish`. It was watching `capture` only, but
publish is the job that dies on a blob upload or a lost branch race, and its
silence reads to the reviewer exactly the same.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014se1ctqQjBCBaqjQRfHdzi

Copy link
Copy Markdown
Owner Author

Addressing the three outside-diff-range findings from the last CodeRabbit review. Two fixed in a48bc14, one refuted.

✅ 64-82 — Pin the changed-file list to the resolved SHAs. Valid, and the file was already contradicting itself: the comment above Resolve PR claims "diff, artifact lookup and checkout all use it so a push racing this run can't mix two heads," but the diff came from gh pr diff <n>, which re-reads the PR's current state. A push landing between the two steps paired the new head's file list with the old head's checkout. Now records baseRefOid alongside headRefOid and uses a pinned three-dot compare. (Note gh pr diff has no --base/--head flags, so this went through gh api .../compare/$BASE...$HEAD.)

✅ 248-283 — Handle the already-exists bootstrap race. Valid. Confirmed rather than assumed: replaying the publish script against a stubbed API with createRef returning 422, the pre-fix code throws and posts nothing, so the losing PR silently gets no handoff comment. It now adopts the winner's branch and falls through to the append retry loop. Post-fix the same scenario commits and comments.

While here I also widened the failure notice to watch publish, not just capture — publish is exactly the job that would die on this race or a blob upload, and its silence reads identically to the reviewer.

❌ 47-51 — Reject protected-configuration PRs before capture. Not applying this one; I think the guideline is being read past its scope.

The rule protects the code-writing loop from editing its own gates — claude-pr-loop.yml:162 states it directly: "Protected paths: the loop may never modify its own gates," and it halts so Claude never authors changes to CI, release, or lint config. story-screenshots.yml authors nothing; it reads a PR and posts pictures.

There's also no privilege here to escalate into. capture is the only job that runs PR code and it holds contents: read + pull-requests: read + actions: read on pull_request (deliberately not pull_request_target); publish holds the write scopes and executes zero PR code, treating capture's output as untrusted. Untrusted authors can't reach either path: the labeled trigger requires head.repo.full_name == github.repository and Resolve PR refuses isCrossRepository, so only same-repo PRs run — authors who already have push access and don't need this workflow to get it. The dispatch path is narrower still, since the loop dispatches --ref main and workflow_dispatch resolves the workflow from that ref rather than the PR head.

Adding the guard would also break the case it's meant to serve: a PR touching both .github/** and bulma-ui/src/ is precisely one where the screenshots are worth having — this PR is that shape.

Happy to add the preflight if you'd rather have belt-and-braces here, but I don't think it's buying safety at the moment.


Generated by Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://0f4d7ae6.bestax.pages.dev

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

Re-requesting because a48bc14 doesn't appear to have been picked up — the last review covered 298954b. That commit is the one that acted on the previous round's outside-diff findings (pinned base/head compare, createRef 422 handling, failure notice widened to publish), so it's the part most worth a fresh pass.


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

@allxsmith: Understood — I’ll run a fresh full review of #352, with particular attention to the a48bc14 follow-up changes and their workflow/security behavior.

✅ Action performed

Full review finished.

@allxsmith
allxsmith merged commit fb8861a into main Jul 26, 2026
12 checks passed
@allxsmith
allxsmith deleted the feat/story-screenshots-handoff branch July 26, 2026 01:08
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.7.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.8.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Post Playwright screenshots of changed stories to ai-loop PRs

1 participant