Cherry Studio Regression Tests
CherryHQ/cherry-studio
Runs Cherry Studio's critical-path regression suite as deterministic Playwright E2E tests through a GitHub workflow on macOS and Windows runners.
Post a Korean release risk digest to a Microsoft Teams thread, grouped by risk category.
$ npx skills add lablup/backend.ai-webui --skill release-train-prep -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install lablup/backend.ai-webui release-train-prep --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/lablup/backend.ai-webui.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/release-train-prep .claude/skills/release-train-prep && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "release-train-prep" agent skill from https://github.com/lablup/backend.ai-webui/tree/main/.claude/skills/release-train-prep into .claude/skills/release-train-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release-train-prep", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/lablup/backend.ai-webui/tree/main/.claude/skills/release-train-prepType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add lablup/backend.ai-webui --skill release-train-prep -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install lablup/backend.ai-webui release-train-prep --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/lablup/backend.ai-webui.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/release-train-prep .agents/skills/release-train-prep && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "release-train-prep" agent skill from https://github.com/lablup/backend.ai-webui/tree/main/.claude/skills/release-train-prep into .agents/skills/release-train-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release-train-prep", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add lablup/backend.ai-webui --skill release-train-prep -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install lablup/backend.ai-webui release-train-prep --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/lablup/backend.ai-webui.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/release-train-prep .cursor/skills/release-train-prep && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "release-train-prep" agent skill from https://github.com/lablup/backend.ai-webui/tree/main/.claude/skills/release-train-prep into .cursor/skills/release-train-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release-train-prep", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/lablup/backend.ai-webui.git --path .claude/skills/release-train-prep--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add lablup/backend.ai-webui --skill release-train-prep -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install lablup/backend.ai-webui release-train-prep --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/lablup/backend.ai-webui.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/release-train-prep .gemini/skills/release-train-prep && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "release-train-prep" agent skill from https://github.com/lablup/backend.ai-webui/tree/main/.claude/skills/release-train-prep into .gemini/skills/release-train-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release-train-prep", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install lablup/backend.ai-webui release-train-prepInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add lablup/backend.ai-webui --skill release-train-prep -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/lablup/backend.ai-webui.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/release-train-prep .github/skills/release-train-prep && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "release-train-prep" agent skill from https://github.com/lablup/backend.ai-webui/tree/main/.claude/skills/release-train-prep into .github/skills/release-train-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release-train-prep", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add lablup/backend.ai-webui --skill release-train-prep -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install lablup/backend.ai-webui release-train-prep --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/lablup/backend.ai-webui.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/release-train-prep .opencode/skills/release-train-prep && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "release-train-prep" agent skill from https://github.com/lablup/backend.ai-webui/tree/main/.claude/skills/release-train-prep into .opencode/skills/release-train-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release-train-prep", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
release-train-prepPost a Korean release risk digest to a Microsoft Teams thread, grouped by risk category.
Release Train Prep is an agent skill from lablup/backend.ai-webui. Post a Korean release risk digest to a Microsoft Teams thread, grouped by risk category. Runs scripts/release-risk-report.mjs over a ref range and renders the result as a short HTML message: new features and change hotspots first, then version-gating gaps (@since), untranslated keys, UI without e2e cover, and manual gaps. Use when someone gives a Teams thread URL and asks to summarize a release, an rc, or a branch there — "이번 릴리즈 리스크 팀즈에 올려줘", "이 스레드에 정리해서 알려줘", "post the release risk report to Teams"…
Its SKILL.md is about 5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Testing & QA, covering End-to-end testing. It works with GitHub and Microsoft Teams. The repository describes itself as: Backend.AI Web UI for web / desktop app (Windows/Linux/macOS). Backend.AI Web UI provides a convenient environment for users, while allowing various commands to be executed… The licence is LGPL-3.0.
5 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 10554dc. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitghnodeFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git and gh, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Release Train Prep loads about 5k tokens when it runs. Until then it costs about 255 tokens; SKILL.md has 2,215 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from lablup/backend.ai-webui at commit 10554dc, republished under its LGPL-3.0 licence (© lablup). 2,215 words, ~4,957 tokens.
.claude/skills/release-train-prep/SKILL.md (or your agent's skills folder).Prepare a release train: turn a ref range into a QA checklist, post it to the
train's Teams thread grouped by risk category, and (with --train) open the
Final Train GitHub issue. The analysis is done entirely by
scripts/release-risk-report.mjs; this skill runs it once, renders Korean
HTML, and posts.
Prep, not release. This skill touches the train issue and Teams only — it never creates a release branch, pushes a tag, or publishes a GitHub release. Cutting an rc or a stable is
create-release; the post-release version bump isbump-alpha-version. If the ask is "릴리즈 찍어줘" rather than "릴리즈 준비해줘", stop and use those.
Skill reference: Invoke the
teams-workflowskill for Teams CLI usage.
gh pr view over the findings — everything needed is already there.git log, or grep
the tree to "understand" a finding. The digest reports what the tool found; the
reader opens the PR if they want detail.$ARGUMENTS may contain these in any order:
--from <ref> — the base of the comparison. When absent, offer the choices
below rather than erroring or guessing (see Resolving --from).--to <ref> — defaults to HEAD.--dry-run — preview only, no side effects anywhere: write the HTML to
/tmp/release-train-prep-preview.html, skip the Teams post, and with
--train also skip every tracker action (no issue, no project item) — describe what
would be created instead. A dry run must never mutate anything.--auto — skip the confirm-before-post prompt (for cron / unattended runs).--train [version] — also open the release train: create the
Final Train to v<version> GitHub issue and post the kickoff into the thread.
The version may be omitted — it is read from the thread's own title.
See Train kickoff below.teams.microsoft.com/l/message/...) — required unless --dry-run.
There is deliberately no default: posting a release summary to the wrong thread
is not something to get wrong by omission. If the user did not give one, ask.
The Teams CLI can only reply to an existing thread — it cannot open a new
channel message — so the thread itself is created by a human first, which
matches how the team actually runs a train.--fromNothing is inferred silently: no release tag is an ancestor of main in this
repository (they live on the release branches, so git describe fails on main),
and defaulting to the newest tag would report a whole release to someone who ran
this on a feature branch. But an error is a dead end — offer the choices.
Refresh first. A stale origin/main moves the merge base and quietly changes
every file-based finding, so fetch before offering it:
git fetch origin main --quiet
LATEST_TAG=$(git tag --sort=-creatordate | head -1)
# Previous tag of the SAME release line (v26.9.0-rc.3 -> the v26.9.0 line):
# an interleaved hotfix tag from another line must not become the "직전 rc".
RELEASE_LINE=${LATEST_TAG%%-*}
PREV_RC=$(git tag --sort=-creatordate | grep -F "$RELEASE_LINE" | sed -n 2p)
# Previous *stable* release, excluding LATEST_TAG itself — when the newest tag
# is already stable, this must yield the one before it, not an empty range.
PREV_STABLE=$(git tag --sort=-creatordate | grep -Ev '\-(rc|alpha|beta)\.|\+' | grep -vxF "$LATEST_TAG" | head -1)
BRANCH=$(git branch --show-current)Then ask with AskUserQuestion, putting the option that matches the current HEAD
first and marking it (Recommended). On a feature branch that is the branch diff;
on a release branch or a detached tag it is the release comparison.
| Option | --from / --to | Answers |
|---|---|---|
| 현재 브랜치가 추가한 것 | origin/main (just fetched) | what this PR puts into a release |
| 다음 릴리즈에 쌓인 것 | $LATEST_TAG → HEAD | what is queued but not yet cut |
| 이번 릴리즈 전체 | $PREV_STABLE → $LATEST_TAG | what the release as a whole contains |
| 직전 rc 이후 | $PREV_RC → $LATEST_TAG | what changed in the last rc turn |
Offer the last row only when $LATEST_TAG is a prerelease. The two release rows
are far apart in size and answer different questions — at the time of writing,
$PREV_STABLE..$LATEST_TAG was 175 commits and $PREV_RC..$LATEST_TAG was 18 —
so do not collapse them into one "previous tag" option.
AskUserQuestion always offers Other, which is how the user supplies a ref
this list does not cover (an older tag, another branch, a SHA) — take that string
verbatim as --from. Do not pre-validate it; the script fails loudly on a bad ref.
Say which ref you resolved to in the reply, so a wrong pick is visible before the message reaches Teams.
Must run from a backend.ai-webui checkout; the script shells out to git in the
current directory. By this point $FROM is whatever Resolving --from settled on —
the script itself takes no default and exits 2 without one.
TO="${TO:-HEAD}" # --to is optional; an empty string would override the script's default
node scripts/release-risk-report.mjs --from "$FROM" --to "$TO" --json > /tmp/release-risk.jsonIf the script exits non-zero, report the message and stop. Do not fall back to reading git history by hand.
Top-level fields:
| Field | Meaning |
|---|---|
from, to, base | the range, and the merge base file comparisons ran from |
divergedFrom | true when to forked before from moved on — mention the base when true |
commits[] | {sha, subject, pr, fr, type, scope} |
featureMatrix[] | {flag, version, used} — gates added inside the range |
gating.gaps[] | {key, version, kind, ungated[]} — new schema fields used without @since or a supports() guard |
hotspots[] | {area, commits, prs[]} — existing-feature churn, most-changed first (feat excluded) |
undeclared[] | flags used but never declared, i.e. permanently false |
risks.noE2E[] | {pr, fr, subject, ui[]} — UI changed, no e2e changed |
risks.destructive[] | {pr, fr, subject, destructive[]} — irreversible-flow files |
risks.noDocs[] | {pr, fr, subject} — feat: that changed a page or component (`react/src/pages |
risks.noDocsSkipped[] | {pr, fr, subject, reason} — feat: with UI files the script set aside (dev-tooling, library-only, no-page-surface). Debugging only — answers "why was #N not flagged?"; the digest never counts or lists them, they already appear under 새 기능 |
i18n[] | {file, addedCount, missing[], placeholder[]} per locale file |
The digest answers one question for the reader: 릴리즈 준비 때 어떤 기능을 집중적으로 만져봐야 하는가. Sections in order:
R4 (destructive-flow touches) stays in the full --out report for reviewers,
but the digest does not carry it — the team asked for feature-level focus, not
file-level caution.
Keep it short. A Teams message is read on a phone. Per section list at most
5 items and append 외 N건 when there are more. For R3, do not list 40 locale
files — collapse to the shape (대부분의 언어에서 placeholder N개 / 누락 M개) and
name only the outliers.
외 N건 is a size fold, nothing else. It means "N more of the same kind that
did not fit", so the reader can ask for them and get a list of equals. An item
you drop for a reason — not manual material, not user-facing, a false positive
— is never folded into it: either leave it out entirely (the script already
does this for R5) or name it with its reason. The rc.4 thread had to ask what
"외 4건" were because a triage was hiding inside a fold.
HTML safety: escape &, <, >, ", ' in every string taken from the JSON
(PR subjects, file paths, flag names) before inserting it. Emit only <b>, <i>,
<br/>, <ul>, <li>, <a href="...">, <code>, <hr/>. Escape & in URLs too.
PR links are https://github.com/lablup/backend.ai-webui/pull/{pr}.
Template:
Name releases, not refs. The header speaks in release versions: for an
upcoming stable cut from main, 26.8.1 → 26.9.0(예정, 현재 main 기준) — never a
bare v26.8.1 → origin/main, which readers cannot place on the release line.
Template:
<b>🚀 릴리즈 준비 — {이전 정식} → {다음 버전}(예정, 현재 {to} 기준)</b><br/>
커밋 {commits.length}건{, 비교 기준 merge-base <code>{base[0:8]}</code> when divergedFrom}<br/><br/>
<b>✨ 새 기능</b> — {feat 커밋 수}건<br/>
<ul>
<li><a href="{prUrl}">#{pr}</a> {사용자 관점 한 줄 설명}</li>
</ul>
{외 N건}<br/>
<b>🔧 많이 바뀐 기존 기능</b><br/>
<ul>
<li><b>{영역 한글명}</b> — 변경 {commits}건 (<a>#{pr}</a>, <a>#{pr}</a>, …)</li>
</ul>
<i>릴리즈 테스트에서 이 기능들을 우선적으로 확인해 주세요.</i><br/><br/>
<b>⚙️ 버전 게이팅 누락</b> — {gating.gaps.length}건<br/>
<ul>
<li><code>{key}</code> ({version} 추가) — <code>{ungated file}</code>에서 @since 없이 사용</li>
</ul>
<i>낮은 버전 매니저에서 이 쿼리는 실패합니다. @since(version:) 주석 또는 supports() 게이트가 필요합니다.</i><br/><br/>
<b>🌐 미번역</b> — 신규 영어 키 {addedCount}개<br/>
{shape line, then outliers}<br/><br/>
<b>🧪 e2e 미커버 UI 변경</b> — {n}건<br/>
<ul><li><a href="{prUrl}">#{pr}</a> {subject}</li></ul>
{외 N건}<br/><br/>
<b>📖 매뉴얼 미반영</b> — {n}건<br/>
<ul><li><a href="{prUrl}">#{pr}</a> {subject}</li></ul>
{외 N건}
<hr/>
<i>🤖 scripts/release-risk-report.mjs · 결함 목록이 아니라 QA 확인 항목입니다</i>How each special section is written:
feat commit, but the line is YOURS to write — a Korean
sentence describing what the user can now do, synthesized from the subject
("pick the model mount subpath with a directory picker" → "모델 마운트 경로를
디렉터리 탐색기로 선택"). Never paste raw commit subjects here. Cap at ~6
lines + 외 N건.hotspots[] top ~5. Translate the area token into
the UI's own term (VFolder → 폴더, Deployment → 배포/디플로이먼트 — the i18n
label wins, per the terminology precedence), show the change count and 2–3 PR
links. This is the "여기를 우선 테스트" list.gating.gaps is empty,
keep the section as the single line ⚙️ 버전 게이팅 누락 — 없음 ✅: for a
go/no-go reader, "checked and clean" and "not checked" must not look the same.risks.noDocs[] is the list and the heading count is
its length. Feats the script set aside (risks.noDocsSkipped[]: dev tooling,
library-only, no page surface) are not counted and not mentioned — they are
already in 새 기능 and the commit list. If one of them does deserve a manual
entry, fix isManualFacing in the script rather than editing the digest.Drop any other section whose count is 0 rather than printing an empty heading. If every section is empty, post a single line saying the range has no risk signals.
The closing italic line matters: these are actions to check, not confirmed defects. Do not phrase a finding as a bug.
Unless --auto, show the rendered HTML and ask for approval before posting.
Posting to Teams is outward-facing and cannot be unsent cleanly.
TEAMS_READER=$(find ~/.claude/plugins -name teams_reader.py 2>/dev/null | head -1)
[ -z "$TEAMS_READER" ] && { echo "FAIL: teams_reader.py not found. Install the fw plugin."; exit 1; }
TEAMS_PYTHON="${TEAMS_PYTHON:-python3}"
export TEAMS_TENANT_ID="${TEAMS_TENANT_ID:-13c6a44d-9b52-4b9e-aa34-0513ee7131f2}"
export TEAMS_CLIENT_ID="${TEAMS_CLIENT_ID:-7a2e1945-3a1c-407f-9780-c573119d1c1b}"
BODY=$(mktemp); LOG=$(mktemp)
cat > "$BODY" <<'HTMLEOF'
<HTML HERE>
HTMLEOF
if "$TEAMS_PYTHON" "$TEAMS_READER" --no-ai-label --reply "$(cat "$BODY")" "$TEAMS_URL" >"$LOG" 2>&1; then
rm -f "$BODY" "$LOG"; echo "OK"
else
cat "$LOG"; rm -f "$BODY" "$LOG"; exit 1
fiPass --no-ai-label: the template already carries its own footer.
For --dry-run, write the same HTML to /tmp/release-train-prep-preview.html
and print the path instead.
--train [version])The team's release ritual: a human opens a 🚂 Final train to vX.Y.Z thread,
someone creates the Final Train to vX.Y.Z issue, and every bug found during
release testing is linked onto it — as a blocked by dependency for
blockers, a #N mention for the rest. The stable tag is cut when no blocker
is left open. This mode automates the middle step and seeds the thread with
the digest.
The whole flow works from just the thread URL. The human's only manual step is opening the thread; version and range are inferred from there:
--train carries no version (or the ask is just "이
스레드로 트레인 준비해줘"), read the thread's ROOT message first
(teams_reader.py --no-thread <url> — its Subject: line) and parse the
version from the title: /final train to v?(?:WebUI\s*)?(\d+\.\d+\.\d+)/i
matches the team's 🚂 Final train to vWebUI 26.9.0 shape. If the title
yields no version, ask — never guess one from tags.--from $PREV_STABLE --to HEAD (the
"이전 정식 → 다음 정식(예정)" comparison the digest header speaks in),
skipping the usual AskUserQuestion. An explicit --from still overrides.Both inferred values are shown in the issue-creation confirm (step 2), which is where a wrong parse gets caught — one confirm, not two.
Runs in addition to the normal digest flow, sharing its confirm gate. The
thread URL is required here even though --dry-run normally waives it —
the issue embeds it, and version inference reads it — and under --dry-run
every step below is described, not executed. Steps, in order:
Duplicate scan first. An existing train for the same version is reused, never doubled:
gh search issues --repo lablup/backend.ai-webui --match title "Final Train" \
--sort created --order desc --limit 10 --json number,title,state,url \
--jq '.[] | "\(.number)\t\(.state)\t\(.title)"' \
| grep -iF "$VERSION"List the recent trains and match the version string yourself. Do NOT put
the version into the search query: search tokenizes 26.9.0, and a
tokenized text search for the version once returned nothing for an
existing "Final Train to v26.9.0" (FR-3663, 2026-09-09) — a --train run
that trusted it would have created a second train. The grep also catches
the vWebUI 26.9.0 and bare 26.9.0 spellings alike. Trains from before
the move to GitHub are their Jira clones and match the same way.
On a hit, skip creation, use the existing issue, and say so in the reply.
Create the issue — after explicit user confirmation. Creating an issue
is outward-facing: show the exact title, type, and body you are about to
submit and ask (AskUserQuestion) before every creation — no batch
pre-approval, one confirm per issue. Type Task, exact title format
Final Train to v$VERSION — the team greps for this shape (FR-3663,
FR-3392, FR-3238 all follow it). The body lists the PRs in the range — one
line per distinct commits[].pr from the report JSON, - #N subject —
so the train is readable without the digest:
ISSUE_URL=$(gh api -X POST repos/lablup/backend.ai-webui/issues \
-f title="Final Train to v$VERSION" -f type=Task \
-f body="Release train for v$VERSION. Bugs found during release testing are
linked here: **blocked by** (issue dependency) for release blockers, a \`#N\`
mention for non-blocking findings. The stable tag is cut when no blocking
issue is open.
Kickoff thread: $TEAMS_URL
Risk digest at kickoff: see the thread reply posted alongside this issue.
## PRs in this train ($FROM → $TO)
$PR_LINES" --jq .html_url)Put it in the current iteration of Project 41 so it shows on the
board: gh project item-add 41 --owner lablup --url "$ISSUE_URL", then set
its Iteration field to the current iteration (gh project field-list 41 --owner lablup for the field and iteration ids, gh project item-edit to
set it). The Teams thread is already in the body — there is no separate
link step.
Post the kickoff reply into the thread: the digest as usual, prefixed with the train header:
<b>🚂 Final Train to v{VERSION}</b> — <a href="{ISSUE_URL}">#{NUMBER}</a><br/>
릴리즈 테스트에서 발견되는 버그는 이 이슈에 연결해주세요 —
블로커는 <b>blocked by</b>, 그 외는 <b>#{NUMBER}</b> 언급으로.<br/><br/>
{the normal digest body}What this mode deliberately does not do:
astryx-bug-report /
fw:github-issue-workflow flow already covers the mechanics).gh pr list --search "#$NUMBER" for
the PRs that mention it); it needs no digest.create-release's job, triggered by a human.# Open the train: version and range inferred from the thread's own title
/release-train-prep --train <teams-url>
# Same, everything explicit
/release-train-prep --train 26.10.0 --from v26.9.0 <teams-url>
# An rc, posted to the release thread
/release-train-prep --from v26.8.1 --to v26.9.0-rc.3 <teams-url>
# What is queued for the next release
/release-train-prep --from v26.8.1 <teams-url>
# One PR's checklist, previewed locally first
/release-train-prep --from origin/main --to FR-3820 --dry-runscripts/release-risk-report.mjs — the analysis; --help for its own flagsteams-workflow (fw) — the Teams CLI, mentions, and imagesfw:github-issue-workflow — creating GitHub issues, Project 41 fields, and the Resolves #N conventionsmerged-pr-digest (fw) — the same post-to-Teams shape for merged PRscreate-release — cutting the tag itself; out of this skill's scope.claude/rules/destructive-confirmation.md — what R4 asks the reader to re-verify© lablup, LGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/release-train-prep of lablup/backend.ai-webui.
Open the folder on GitHubat commit 10554dc
Release Train Prep next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Release Train Prep this skilllablup/backend.ai-webui | 133 | — | ~5k | Automated safety check: Pass | LGPL-3.0 | |
| Cherry Studio Regression TestsCherryHQ/cherry-studio | 52k | — | ~1.2k | Automated safety check: Pass | AGPL-3.0 | |
| Nemoclaw Maintainer Fix E2E FailuresNVIDIA/NemoClaw | 23k | — | ~2.6k | Automated safety check: Pass | Apache-2.0 | |
| Explore Feature E2E Testcomet-ml/opik | 22k | — | ~3.4k | Automated safety check: Pass | Apache-2.0 | |
| Kane CLI Browser TestingLambdaTest/kane-cli | 247 | — | ~8.4k | Automated safety check: Pass | Apache-2.0 | |
| Detect Flaky Testsagent-substrate/substrate | 4.5k | — | ~3k | Automated safety check: Pass | Apache-2.0 |
CherryHQ/cherry-studio
Runs Cherry Studio's critical-path regression suite as deterministic Playwright E2E tests through a GitHub workflow on macOS and Windows runners.
NVIDIA/NemoClaw
Continuously maintain automatic NemoClaw main E2E results through coordinated repairs.
comet-ml/opik
Turns a code change into one committed, passing Playwright end-to-end spec by resolving the change scope and handing authoring to a companion skill.
LambdaTest/kane-cli
Drives a real browser through the kane-cli tool and designs requirement-linked test suites from a PRD or a plain description, with mobile and cloud-grid runs.
agent-substrate/substrate
Detects flaky Go tests by analyzing GitHub Actions workflow runs across the last 7 days and all PRs — covering both the run-tests job (unit/integration) and the e2e-test job (gVisor and microVM…
hardisgroupcom/sfdx-hardis
Runs a full end-to-end test of sfdx-hardis promotion branches and backpromote against real Salesforce orgs and a throwaway repository, then writes a report.
lablup/backend.ai-webui
Mint a walkthrough for the PR this session just implemented: a set of numbered stops a reviewer opens in the live dev server, each one marking an element on screen with what changed and what to check.
lablup/backend.ai-webui
A skill your agent uses whenever the user mentions docs, the manual, documentation, terminology, translations, or screenshots — including indirect mentions like "이 PR 문서 영향 봐줘", "문서 점검", "용어 통일"…
lablup/backend.ai-webui
Expert guide for Backend.AI distributed computing platform. An agent skill from lablup/backend.ai-webui.
lablup/backend.ai-webui
Start the project's development server (pnpm dev for backend.ai-webui; discovered from README/package.json elsewhere), deriving the header color, app name, default backend endpoint and login…
lablup/backend.ai-webui
Record Playwright e2e tests as one GIF per test case (video → ffmpeg palette GIF) and return a markdown table for a PR description.
lablup/backend.ai-webui
A skill your agent uses when writing if (success) updateFetchKey(), an onRequestClose handler, or any refetch after a mutation; when a setting modal handles both create and update behind one…
Works with
Categories
Post a Korean release risk digest to a Microsoft Teams thread, grouped by risk category. ai-webui. Post a Korean release risk digest to a Microsoft Teams thread, grouped by risk category.
Release Train Prep fits situations like: someone gives a Teams thread URL and asks to summarize a release; A branch there — 이번 릴리즈 리스크 팀즈에 올려줘; 이 스레드에 정리해서 알려줘; post the release risk report to Teams.
Run `npx skills add lablup/backend.ai-webui --skill release-train-prep -a claude-code`. Or copy the skill folder (.claude/skills/release-train-prep in lablup/backend.ai-webui) into .claude/skills/release-train-prep in your project. Claude Code loads it when a task matches its description.
Run `npx skills add lablup/backend.ai-webui --skill release-train-prep -a codex`. Or copy the skill folder (.claude/skills/release-train-prep in lablup/backend.ai-webui) into .agents/skills/release-train-prep in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add lablup/backend.ai-webui --skill release-train-prep -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/release-train-prep, .gemini/skills/release-train-prep, .github/skills/release-train-prep and .opencode/skills/release-train-prep in your project.
Going by SKILL.md and its folder, Release Train Prep needs the command-line tools its instructions call (git, gh and node).
SKILL.md contains no URLs. Its commands use git and gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Release Train Prep is published under the LGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Release Train Prep: Cherry Studio Regression Tests (CherryHQ/cherry-studio, 52k stars), Nemoclaw Maintainer Fix E2E Failures (NVIDIA/NemoClaw, 23k stars), Explore Feature E2E Test (comet-ml/opik, 22k stars) and Kane CLI Browser Testing (LambdaTest/kane-cli, 247 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
lablup (a GitHub organization) maintains it in lablup/backend.ai-webui, which has 133 GitHub stars. The repository holds 13 skills in this directory. The repository was last updated on October 7, 2026.
Source: lablup/backend.ai-webui on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.