From 72661ae9beb69d66ab3e4d1b8554bce6d02d1d5c Mon Sep 17 00:00:00 2001 From: Lawrence Date: Sun, 15 Mar 2026 22:20:21 +0000 Subject: [PATCH 1/8] Create antislop.yml --- .github/workflows/antislop.yml | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/antislop.yml diff --git a/.github/workflows/antislop.yml b/.github/workflows/antislop.yml new file mode 100644 index 00000000..7d39469c --- /dev/null +++ b/.github/workflows/antislop.yml @@ -0,0 +1,57 @@ +name: PR Quality + +on: + pull_request_target: + types: [opened, reopened, edited, synchronize] + +permissions: + contents: read + issues: read + pull-requests: write + +jobs: + anti-slop: + runs-on: ubuntu-latest + + steps: + - uses: peakoss/anti-slop@v0.2.1 + with: + # sensitivity + max-failures: 4 + + # PR quality + require-description: true + max-description-length: 2000 + max-emoji-count: 2 + max-code-references: 5 + + # commits + max-commit-message-length: 300 + require-commit-author-match: true + + # contributor signals + min-account-age: 30 + min-profile-completeness: 4 + min-global-merge-ratio: 30 + + # spam behaviour + max-daily-forks: 7 + detect-spam-usernames: true + + # repo protection + blocked-source-branches: | + main + master + + # label results + success-add-pr-labels: checked + failure-add-pr-labels: slop + + # message when PR is closed + failure-pr-message: | + ⚠️ This pull request was automatically closed by **Anti-Slop**. + + Our automated checks detected patterns commonly associated with + low-quality or automated PR submissions. + + If this was a mistake, a maintainer can reopen the PR. From a309d1abca15126d0edd924496507166150fcdbc Mon Sep 17 00:00:00 2001 From: Lawrence Date: Sun, 15 Mar 2026 22:20:31 +0000 Subject: [PATCH 2/8] Delete .github/workflows/antislop.yml --- .github/workflows/antislop.yml | 57 ---------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 .github/workflows/antislop.yml diff --git a/.github/workflows/antislop.yml b/.github/workflows/antislop.yml deleted file mode 100644 index 7d39469c..00000000 --- a/.github/workflows/antislop.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: PR Quality - -on: - pull_request_target: - types: [opened, reopened, edited, synchronize] - -permissions: - contents: read - issues: read - pull-requests: write - -jobs: - anti-slop: - runs-on: ubuntu-latest - - steps: - - uses: peakoss/anti-slop@v0.2.1 - with: - # sensitivity - max-failures: 4 - - # PR quality - require-description: true - max-description-length: 2000 - max-emoji-count: 2 - max-code-references: 5 - - # commits - max-commit-message-length: 300 - require-commit-author-match: true - - # contributor signals - min-account-age: 30 - min-profile-completeness: 4 - min-global-merge-ratio: 30 - - # spam behaviour - max-daily-forks: 7 - detect-spam-usernames: true - - # repo protection - blocked-source-branches: | - main - master - - # label results - success-add-pr-labels: checked - failure-add-pr-labels: slop - - # message when PR is closed - failure-pr-message: | - ⚠️ This pull request was automatically closed by **Anti-Slop**. - - Our automated checks detected patterns commonly associated with - low-quality or automated PR submissions. - - If this was a mistake, a maintainer can reopen the PR. From 361f4dbdf6b847430f74bc7af650e52c75dfb363 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Sun, 15 Mar 2026 22:20:46 +0000 Subject: [PATCH 3/8] Add Anti-Slop workflow for PR quality checks This workflow checks pull request quality using Anti-Slop, enforcing various criteria such as description length, commit message requirements, and contributor signals. --- .github/workflows/antislop.yml | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/antislop.yml diff --git a/.github/workflows/antislop.yml b/.github/workflows/antislop.yml new file mode 100644 index 00000000..7d39469c --- /dev/null +++ b/.github/workflows/antislop.yml @@ -0,0 +1,57 @@ +name: PR Quality + +on: + pull_request_target: + types: [opened, reopened, edited, synchronize] + +permissions: + contents: read + issues: read + pull-requests: write + +jobs: + anti-slop: + runs-on: ubuntu-latest + + steps: + - uses: peakoss/anti-slop@v0.2.1 + with: + # sensitivity + max-failures: 4 + + # PR quality + require-description: true + max-description-length: 2000 + max-emoji-count: 2 + max-code-references: 5 + + # commits + max-commit-message-length: 300 + require-commit-author-match: true + + # contributor signals + min-account-age: 30 + min-profile-completeness: 4 + min-global-merge-ratio: 30 + + # spam behaviour + max-daily-forks: 7 + detect-spam-usernames: true + + # repo protection + blocked-source-branches: | + main + master + + # label results + success-add-pr-labels: checked + failure-add-pr-labels: slop + + # message when PR is closed + failure-pr-message: | + ⚠️ This pull request was automatically closed by **Anti-Slop**. + + Our automated checks detected patterns commonly associated with + low-quality or automated PR submissions. + + If this was a mistake, a maintainer can reopen the PR. From 60d7fcd7c605133e73b6847d97c5bf956f4a1eae Mon Sep 17 00:00:00 2001 From: Lawrence Date: Mon, 16 Mar 2026 21:38:06 +0000 Subject: [PATCH 4/8] Update antislop.yml --- .github/workflows/antislop.yml | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/.github/workflows/antislop.yml b/.github/workflows/antislop.yml index 7d39469c..1fea1f6c 100644 --- a/.github/workflows/antislop.yml +++ b/.github/workflows/antislop.yml @@ -12,46 +12,50 @@ permissions: jobs: anti-slop: runs-on: ubuntu-latest - steps: - - uses: peakoss/anti-slop@v0.2.1 + - uses: peakoss/anti-slop@85daca1880e9e1af197fc06ea03349daf08f4202 with: - # sensitivity max-failures: 4 - # PR quality require-description: true max-description-length: 2000 max-emoji-count: 2 max-code-references: 5 - # commits max-commit-message-length: 300 require-commit-author-match: true - # contributor signals min-account-age: 30 min-profile-completeness: 4 min-global-merge-ratio: 30 - # spam behaviour max-daily-forks: 7 detect-spam-usernames: true - # repo protection blocked-source-branches: | main master - # label results + blocked-terms: | + ignore previous instructions + you are a helpful AI + as an AI language model + + exempt-draft-prs: true + exempt-bots: | + dependabot[bot] + renovate[bot] + github-actions[bot] + exempt-author-association: OWNER,MEMBER,COLLABORATOR + success-add-pr-labels: checked failure-add-pr-labels: slop - # message when PR is closed failure-pr-message: | - ⚠️ This pull request was automatically closed by **Anti-Slop**. - + ⚠️ This pull request has been flagged by **Anti-Slop**. Our automated checks detected patterns commonly associated with - low-quality or automated PR submissions. + low-quality or automated/AI submissions (failure count reached). + No automatic closure — a maintainer will review it. + If this is legitimate work, please add more context, link issues, or ping us. - If this was a mistake, a maintainer can reopen the PR. + close-pr: false From a678bd2e960a0aa5de6e28f41720e79ed5f024a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Mar 2026 21:53:09 +0000 Subject: [PATCH 5/8] Initial plan From d908448a3e4e5fc17febe765163c93779dc393bc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Mar 2026 22:00:52 +0000 Subject: [PATCH 6/8] feat: add None option to remove premade backgrounds Co-authored-by: lawrence-mil <221152068+lawrence-mil@users.noreply.github.com> --- src/components/video-editor/SettingsPanel.tsx | 36 ++++++++++++++----- src/components/video-editor/VideoPlayback.tsx | 16 ++++++--- src/i18n/locales/en/settings.json | 1 + src/i18n/locales/es/settings.json | 1 + src/i18n/locales/zh-CN/settings.json | 1 + src/lib/exporter/frameRenderer.ts | 8 ++++- src/lib/wallpapers.ts | 3 ++ 7 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 1cbf39b7..2c983e26 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -1,7 +1,7 @@ import { cn } from "@/lib/utils"; import { useEffect, useRef } from "react"; import { getAssetPath, getRenderableAssetUrl } from "@/lib/assetPath"; -import { BUILT_IN_WALLPAPERS, WALLPAPER_PATHS, WALLPAPER_RELATIVE_PATHS } from "@/lib/wallpapers"; +import { BUILT_IN_WALLPAPERS, NO_BACKGROUND, WALLPAPER_PATHS, WALLPAPER_RELATIVE_PATHS } from "@/lib/wallpapers"; import { SliderControl } from "./SliderControl"; import { Switch } from "@/components/ui/switch"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; @@ -631,14 +631,32 @@ export function SettingsPanel({ accept=".jpg,.jpeg,image/jpeg" className="hidden" /> - +
+
onWallpaperChange(NO_BACKGROUND)} + role="button" + /> + +
{customImages.map((imageUrl, idx) => { diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index 6c5b7f0d..36313d84 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -1,7 +1,7 @@ import type React from "react"; import { useEffect, useRef, useImperativeHandle, forwardRef, useState, useMemo, useCallback } from "react"; import { getAssetPath, getRenderableAssetUrl } from "@/lib/assetPath"; -import { DEFAULT_WALLPAPER_PATH, DEFAULT_WALLPAPER_RELATIVE_PATH } from "@/lib/wallpapers"; +import { DEFAULT_WALLPAPER_PATH, DEFAULT_WALLPAPER_RELATIVE_PATH, NO_BACKGROUND } from "@/lib/wallpapers"; import { Application, Container, Sprite, Graphics, BlurFilter, Texture, VideoSource } from 'pixi.js'; import { MotionBlurFilter } from 'pixi-filters/motion-blur'; import { ZOOM_DEPTH_SCALES, type ZoomRegion, type ZoomFocus, type ZoomDepth, type TrimRegion, type SpeedRegion, type AnnotationRegion, type CursorTelemetryPoint } from "./types"; @@ -1024,10 +1024,13 @@ const VideoPlayback = forwardRef(({ }; }, []) + const isNoBackground = wallpaper === NO_BACKGROUND; const isImageUrl = Boolean(resolvedWallpaper && (resolvedWallpaper.startsWith('file://') || resolvedWallpaper.startsWith('http') || resolvedWallpaper.startsWith('/') || resolvedWallpaper.startsWith('data:'))) - const backgroundStyle = isImageUrl - ? { backgroundImage: `url(${resolvedWallpaper || ''})` } - : { background: resolvedWallpaper || '' }; + const backgroundStyle = isNoBackground + ? {} + : isImageUrl + ? { backgroundImage: `url(${resolvedWallpaper || ''})` } + : { background: resolvedWallpaper || '' }; const nativeAspectRatio = (() => { const locked = lockedVideoDimensionsRef.current; @@ -1046,7 +1049,10 @@ const VideoPlayback = forwardRef(({ {/* Background layer */}
0 ? `blur(${backgroundBlur}px)` : 'none', }} diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json index 2405ce5f..46a76248 100644 --- a/src/i18n/locales/en/settings.json +++ b/src/i18n/locales/en/settings.json @@ -34,6 +34,7 @@ }, "background": { "title": "Background", + "none": "None", "image": "Image", "color": "Color", "gradient": "Gradient", diff --git a/src/i18n/locales/es/settings.json b/src/i18n/locales/es/settings.json index 7b3a1379..1eb012fd 100644 --- a/src/i18n/locales/es/settings.json +++ b/src/i18n/locales/es/settings.json @@ -34,6 +34,7 @@ }, "background": { "title": "Fondo", + "none": "Ninguno", "image": "Imagen", "color": "Color", "gradient": "Degradado", diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index 46106e60..310a8cc3 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -34,6 +34,7 @@ }, "background": { "title": "背景", + "none": "无", "image": "图片", "color": "颜色", "gradient": "渐变", diff --git a/src/lib/exporter/frameRenderer.ts b/src/lib/exporter/frameRenderer.ts index 65dc925d..8805ef1a 100644 --- a/src/lib/exporter/frameRenderer.ts +++ b/src/lib/exporter/frameRenderer.ts @@ -8,6 +8,7 @@ import { applyZoomTransform, computeFocusFromTransform, computeZoomTransform, cr import { DEFAULT_FOCUS, ZOOM_SCALE_DEADZONE, ZOOM_TRANSLATION_DEADZONE_PX } from '@/components/video-editor/videoPlayback/constants'; import { renderAnnotations } from './annotationRenderer'; import { PixiCursorOverlay, DEFAULT_CURSOR_CONFIG, preloadCursorAssets } from '@/components/video-editor/videoPlayback/cursorRenderer'; +import { NO_BACKGROUND } from '@/lib/wallpapers'; interface FrameRenderConfig { width: number; @@ -187,6 +188,11 @@ export class FrameRenderer { private async setupBackground(): Promise { const wallpaper = await this.resolveWallpaperForExport(this.config.wallpaper); + // No background requested — leave the composite canvas transparent + if (this.config.wallpaper === NO_BACKGROUND) { + return; + } + // Create background canvas for separate rendering (not affected by zoom) const bgCanvas = document.createElement('canvas'); bgCanvas.width = this.config.width; @@ -615,7 +621,7 @@ export class FrameRenderer { } else { ctx.drawImage(bgCanvas, 0, 0, w, h); } - } else { + } else if (this.config.wallpaper !== NO_BACKGROUND) { console.warn('[FrameRenderer] No background sprite found during compositing!'); } diff --git a/src/lib/wallpapers.ts b/src/lib/wallpapers.ts index 4540fe6c..7b6be16f 100644 --- a/src/lib/wallpapers.ts +++ b/src/lib/wallpapers.ts @@ -35,3 +35,6 @@ export const WALLPAPER_PATHS = BUILT_IN_WALLPAPERS.map((wallpaper) => wallpaper. export const WALLPAPER_RELATIVE_PATHS = BUILT_IN_WALLPAPERS.map((wallpaper) => wallpaper.relativePath); export const DEFAULT_WALLPAPER_PATH = WALLPAPER_PATHS[0]; export const DEFAULT_WALLPAPER_RELATIVE_PATH = WALLPAPER_RELATIVE_PATHS[0]; + +/** Sentinel value indicating no background should be rendered. */ +export const NO_BACKGROUND = 'none'; From 139c072ac86817a8857f4f008bb3d220b6f6f358 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Mon, 16 Mar 2026 22:19:58 +0000 Subject: [PATCH 7/8] refactor: remove NO_BACKGROUND references and related code for cleaner background handling --- src/components/video-editor/SettingsPanel.tsx | 36 +++++-------------- src/components/video-editor/VideoPlayback.tsx | 16 +++------ src/i18n/locales/en/settings.json | 1 - src/i18n/locales/es/settings.json | 1 - src/i18n/locales/zh-CN/settings.json | 1 - src/lib/exporter/frameRenderer.ts | 8 +---- src/lib/wallpapers.ts | 3 -- 7 files changed, 15 insertions(+), 51 deletions(-) diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index f8b9b216..f5f15cf6 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -1,7 +1,7 @@ import { cn } from "@/lib/utils"; import { useEffect, useRef } from "react"; import { getAssetPath, getRenderableAssetUrl } from "@/lib/assetPath"; -import { BUILT_IN_WALLPAPERS, NO_BACKGROUND, WALLPAPER_PATHS, WALLPAPER_RELATIVE_PATHS } from "@/lib/wallpapers"; +import { BUILT_IN_WALLPAPERS, WALLPAPER_PATHS, WALLPAPER_RELATIVE_PATHS } from "@/lib/wallpapers"; import { SliderControl } from "./SliderControl"; import { Switch } from "@/components/ui/switch"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; @@ -631,32 +631,14 @@ export function SettingsPanel({ accept=".jpg,.jpeg,image/jpeg" className="hidden" /> -
-
onWallpaperChange(NO_BACKGROUND)} - role="button" - /> - -
+
{customImages.map((imageUrl, idx) => { diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index 36313d84..6c5b7f0d 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -1,7 +1,7 @@ import type React from "react"; import { useEffect, useRef, useImperativeHandle, forwardRef, useState, useMemo, useCallback } from "react"; import { getAssetPath, getRenderableAssetUrl } from "@/lib/assetPath"; -import { DEFAULT_WALLPAPER_PATH, DEFAULT_WALLPAPER_RELATIVE_PATH, NO_BACKGROUND } from "@/lib/wallpapers"; +import { DEFAULT_WALLPAPER_PATH, DEFAULT_WALLPAPER_RELATIVE_PATH } from "@/lib/wallpapers"; import { Application, Container, Sprite, Graphics, BlurFilter, Texture, VideoSource } from 'pixi.js'; import { MotionBlurFilter } from 'pixi-filters/motion-blur'; import { ZOOM_DEPTH_SCALES, type ZoomRegion, type ZoomFocus, type ZoomDepth, type TrimRegion, type SpeedRegion, type AnnotationRegion, type CursorTelemetryPoint } from "./types"; @@ -1024,13 +1024,10 @@ const VideoPlayback = forwardRef(({ }; }, []) - const isNoBackground = wallpaper === NO_BACKGROUND; const isImageUrl = Boolean(resolvedWallpaper && (resolvedWallpaper.startsWith('file://') || resolvedWallpaper.startsWith('http') || resolvedWallpaper.startsWith('/') || resolvedWallpaper.startsWith('data:'))) - const backgroundStyle = isNoBackground - ? {} - : isImageUrl - ? { backgroundImage: `url(${resolvedWallpaper || ''})` } - : { background: resolvedWallpaper || '' }; + const backgroundStyle = isImageUrl + ? { backgroundImage: `url(${resolvedWallpaper || ''})` } + : { background: resolvedWallpaper || '' }; const nativeAspectRatio = (() => { const locked = lockedVideoDimensionsRef.current; @@ -1049,10 +1046,7 @@ const VideoPlayback = forwardRef(({ {/* Background layer */}
0 ? `blur(${backgroundBlur}px)` : 'none', }} diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json index b0d7121d..2ffb67f0 100644 --- a/src/i18n/locales/en/settings.json +++ b/src/i18n/locales/en/settings.json @@ -34,7 +34,6 @@ }, "background": { "title": "Background", - "none": "None", "image": "Image", "color": "Color", "gradient": "Gradient", diff --git a/src/i18n/locales/es/settings.json b/src/i18n/locales/es/settings.json index 9f35964d..335bb00d 100644 --- a/src/i18n/locales/es/settings.json +++ b/src/i18n/locales/es/settings.json @@ -34,7 +34,6 @@ }, "background": { "title": "Fondo", - "none": "Ninguno", "image": "Imagen", "color": "Color", "gradient": "Degradado", diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index f3854608..5e2ef5bb 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -34,7 +34,6 @@ }, "background": { "title": "背景", - "none": "无", "image": "图片", "color": "颜色", "gradient": "渐变", diff --git a/src/lib/exporter/frameRenderer.ts b/src/lib/exporter/frameRenderer.ts index 8805ef1a..65dc925d 100644 --- a/src/lib/exporter/frameRenderer.ts +++ b/src/lib/exporter/frameRenderer.ts @@ -8,7 +8,6 @@ import { applyZoomTransform, computeFocusFromTransform, computeZoomTransform, cr import { DEFAULT_FOCUS, ZOOM_SCALE_DEADZONE, ZOOM_TRANSLATION_DEADZONE_PX } from '@/components/video-editor/videoPlayback/constants'; import { renderAnnotations } from './annotationRenderer'; import { PixiCursorOverlay, DEFAULT_CURSOR_CONFIG, preloadCursorAssets } from '@/components/video-editor/videoPlayback/cursorRenderer'; -import { NO_BACKGROUND } from '@/lib/wallpapers'; interface FrameRenderConfig { width: number; @@ -188,11 +187,6 @@ export class FrameRenderer { private async setupBackground(): Promise { const wallpaper = await this.resolveWallpaperForExport(this.config.wallpaper); - // No background requested — leave the composite canvas transparent - if (this.config.wallpaper === NO_BACKGROUND) { - return; - } - // Create background canvas for separate rendering (not affected by zoom) const bgCanvas = document.createElement('canvas'); bgCanvas.width = this.config.width; @@ -621,7 +615,7 @@ export class FrameRenderer { } else { ctx.drawImage(bgCanvas, 0, 0, w, h); } - } else if (this.config.wallpaper !== NO_BACKGROUND) { + } else { console.warn('[FrameRenderer] No background sprite found during compositing!'); } diff --git a/src/lib/wallpapers.ts b/src/lib/wallpapers.ts index 7b6be16f..4540fe6c 100644 --- a/src/lib/wallpapers.ts +++ b/src/lib/wallpapers.ts @@ -35,6 +35,3 @@ export const WALLPAPER_PATHS = BUILT_IN_WALLPAPERS.map((wallpaper) => wallpaper. export const WALLPAPER_RELATIVE_PATHS = BUILT_IN_WALLPAPERS.map((wallpaper) => wallpaper.relativePath); export const DEFAULT_WALLPAPER_PATH = WALLPAPER_PATHS[0]; export const DEFAULT_WALLPAPER_RELATIVE_PATH = WALLPAPER_RELATIVE_PATHS[0]; - -/** Sentinel value indicating no background should be rendered. */ -export const NO_BACKGROUND = 'none'; From d8d601ff5d838bd1be481e81a8aa2c66084cc8e6 Mon Sep 17 00:00:00 2001 From: Lawrence Date: Mon, 16 Mar 2026 22:24:27 +0000 Subject: [PATCH 8/8] Add auto-translate workflow for zh-CN This workflow automatically translates markdown files from English to Chinese (zh-CN) on pushes to the main branch. --- .github/workflows/auto-translate-zh.yml | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/auto-translate-zh.yml diff --git a/.github/workflows/auto-translate-zh.yml b/.github/workflows/auto-translate-zh.yml new file mode 100644 index 00000000..62846e9d --- /dev/null +++ b/.github/workflows/auto-translate-zh.yml @@ -0,0 +1,38 @@ +name: Auto Translate to zh-CN + +on: + push: + branches: [main] + paths: + - "*.md" + +permissions: + contents: write + models: read + +jobs: + translate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/cache@v4 + with: + path: .genaiscript/cache/** + key: translation-cache-${{ github.run_id }} + restore-keys: translation-cache- + + - uses: pelikhan/action-continuous-translation@v0.2.11 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + source: en + lang: zh + files: "*.md;README.md;CONTRIBUTING.md;TRANSLATION_GUIDE.md;CLAUDE.md" + filename_template: "{{ base }}.zh-CN{{ ext }}" + + - uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "docs(zh-CN): auto-translate updates" + file_pattern: "*.zh-CN.md"