Simple English
moeru-ai/airi
Write or rewrite technical text with the rules of ASD-STE100 Simplified Technical English so it is clear, unambiguous, and free of AI slop.
End-of-task pipeline — simplify review, double review, tests, single analyze+test gate, changelog/docs.
$ npx skills add hacan359/tonkatsu_box --skill finish -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install hacan359/tonkatsu_box finish --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/hacan359/tonkatsu_box.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/finish .claude/skills/finish && 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 "finish" agent skill from https://github.com/hacan359/tonkatsu_box/tree/main/.claude/skills/finish into .claude/skills/finish/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "finish", 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/hacan359/tonkatsu_box/tree/main/.claude/skills/finishType 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 hacan359/tonkatsu_box --skill finish -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install hacan359/tonkatsu_box finish --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/hacan359/tonkatsu_box.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/finish .agents/skills/finish && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "finish" agent skill from https://github.com/hacan359/tonkatsu_box/tree/main/.claude/skills/finish into .agents/skills/finish/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "finish", 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 hacan359/tonkatsu_box --skill finish -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install hacan359/tonkatsu_box finish --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/hacan359/tonkatsu_box.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/finish .cursor/skills/finish && 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 "finish" agent skill from https://github.com/hacan359/tonkatsu_box/tree/main/.claude/skills/finish into .cursor/skills/finish/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "finish", 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/hacan359/tonkatsu_box.git --path .claude/skills/finish--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 hacan359/tonkatsu_box --skill finish -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install hacan359/tonkatsu_box finish --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/hacan359/tonkatsu_box.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/finish .gemini/skills/finish && 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 "finish" agent skill from https://github.com/hacan359/tonkatsu_box/tree/main/.claude/skills/finish into .gemini/skills/finish/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "finish", 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 hacan359/tonkatsu_box finishInstalls 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 hacan359/tonkatsu_box --skill finish -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/hacan359/tonkatsu_box.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/finish .github/skills/finish && 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 "finish" agent skill from https://github.com/hacan359/tonkatsu_box/tree/main/.claude/skills/finish into .github/skills/finish/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "finish", 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 hacan359/tonkatsu_box --skill finish -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install hacan359/tonkatsu_box finish --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/hacan359/tonkatsu_box.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/finish .opencode/skills/finish && 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 "finish" agent skill from https://github.com/hacan359/tonkatsu_box/tree/main/.claude/skills/finish into .opencode/skills/finish/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "finish", 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.
finishEnd-of-task pipeline — simplify review, double review, tests, single analyze+test gate, changelog/docs.
Finish is an agent skill from hacan359/tonkatsu_box. End-of-task pipeline — simplify review, double review, tests, single analyze+test gate, changelog/docs. Use when you've finished implementing a task and want to harden it before committing. Does NOT commit or push; the user must ask explicitly.
Its SKILL.md is about 7.4k 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 Development, covering Changelog and release notes. The repository describes itself as: Free open-source app to organize collections of retro games, movies, TV shows & anime. Track progress, rate favorites, create visual boards, share with friends. Flutter · Windows…. The licence is MIT.
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 00a4fac. 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:
flutterdartgitFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
gnu.orgFrom 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.
Finish loads about 7.4k tokens when it runs. Until then it costs about 63 tokens; SKILL.md has 3,813 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 hacan359/tonkatsu_box at commit 00a4fac, republished under its MIT licence (© hacan359). 3,813 words, ~7,422 tokens.
.claude/skills/finish/SKILL.md (or your agent's skills folder).Run this once at the end of a task. The pipeline merges the old simplify / double-review / full-coverage-tests / changelog-docs skills into a single flow with a single analyze+test gate at the end.
flutter analyze or flutter test between phases — only Phase 5 runs them..md files unless the user explicitly asks.///, //, or /* */ blocks. UI strings stay in .arb; this rule is about code comments.//, ///, or /* */) may exceed 2 consecutive lines — anywhere, including dartdoc on public API. If it doesn't fit in 2 lines, cut it until it does.// ===== Foo ===== and // --- bar --- are noise — drop them.// TODO: fix this rots; tie it to an issue or remove it.git status --short
git diff HEADEnumerate changed files once. If the diff is empty, stop with "nothing to finalise".
Review new/changed code from three independent angles. This phase is self-contained — do not delegate to a built-in /simplify skill, which may not exist in every Claude Code version. Run the review yourself using these three lenses:
Reuse
lib/shared/, sibling files of the changed file, existing DAOs.Quality
Efficiency
awaits in sequence → Future.wait.For large diffs (≥5 changed files or ≥300 lines), dispatch the three angles as parallel Agent sub-tasks (subagent_type: Explore) in a single message — each agent gets the full diff and reports its findings in ≤300 words. Then aggregate and fix. On small diffs, review all three angles yourself inline.
Fix actionable issues. Skip false positives — don't argue, just move on. Out-of-scope issues (pre-existing cruft in untouched files) get noted in the final report, not fixed here.
R1 — correctness
dynamic, no var in public API, final / const where possible, nullable handled via ?. / ?? / checks).'${profileId}' read via a getter (not cached in a field — profile can change). Global keys (API creds, theme, language) are the exception.package:path for joins, Platform.isX branches fall through for all supported OS (Windows + Linux + Android), Windows-only plugins (webview_windows) gated by kVgMapsEnabled.MediaType / CanvasItemType value): run flutter analyze to surface exhaustive-switch errors across canvas_view.dart, all_items_screen.dart, collection_screen.dart, export_service.dart, import_service.dart, plus filter chips, CollectionStats counts, collectedXxxIdsProvider, and all localisation keys (unknown*, allItems*, collectionFilter*, mediaType*, searchSource*).create*Table in schema.dart is shared between fresh installs (createAll) and the historical migration that first created the table — so any column or index baked into a create*Table is also re-applied when an old DB jumps many versions in one upgrade (the create runs with today's schema, then the historical ALTER / CREATE INDEX runs on top). A raw statement then throws duplicate column name / index already exists and the whole upgrade rolls back, leaving the app frozen on the splash. Rules:create*Table in schema.dart (fresh installs need it) and add a new migration that calls Migration.addColumnIfAbsent(db, table, column, columnDef) — never a bare ALTER TABLE ... ADD COLUMN.CREATE INDEX IF NOT EXISTS (and CREATE UNIQUE INDEX IF NOT EXISTS).create*Table into per-version copies. The idempotent ALTER / IF NOT EXISTS index is the sanctioned pattern — it's always valid to apply boldly because it's a no-op when the target already exists.version in _initDatabase() and register the migration in MigrationRegistry.all.R2 — quality and performance
const widgets, ListView.builder for long lists, no object creation in build()).R2b — enum single source of truth (mandatory)
No raw string / number literal in production code may duplicate a value, .name, .key, or display label that an enum already owns. If a concept is modelled by an enum (MediaType, ItemStatus, DataSource, CanvasItemType, CollectionSortMode, ExportFormat, AnimeMangaTitleLanguage, NavTab, DiscoverSectionId, …), every read / write / compare / label / default MUST go through it — EnumX.value, EnumX.name, EnumX.key, EnumX.label, localizedLabel(l), fromString / tryFromString — never a bare 'game', 'completed', 'mangabaka', 'IGDB', 'romaji', 'light'. This is doubly non-negotiable for values that already exist in an enum: the literal must live in exactly one place, the enum.
How to check: for each enum the diff touches (and its close neighbours), grep its literal values and labels across lib/. The only non-exception home should be the enum definition. Also grep the diff itself for quoted strings that echo an enum member — new hardcodes are the common regression.
Fix: replace the literal with the enum accessor (import the enum where needed). If it is a default parameter value (needs const), expose a static const on the enum and reference that (e.g. AnimeMangaTitleLanguage.defaultId). If several call sites hardcode a per-source string (groupId, apiName, sourceName), derive it once from the owning enum (DataSource.key / DataSource.label) and delete the overrides / parallel maps.
Allowed exceptions (do NOT flag these):
lib/core/database/migrations/) and create*Table DDL in schema.dart — historical / storage strings, immutable.movie/tv, AniList ANIME/MANGA, Kitsu / MAL / Trakt / Kinorium, search-filter API values, AniList JSON keys like romaji). These are not the enum's namespace.app_localizations*.dart) and .arb — localisation resources.label that legitimately differs from a full display name — e.g. DataSource.steamGridDb.label is 'SGDB' but the credits screen shows 'SteamGridDB'; these are different concepts, do not force one into the other. Same for a per-tab SearchSource.id ('movies', 'manga') which is a media/tab identifier, not the provider name.R2c — model purity (mandatory)
lib/shared/models/** stays pure Dart: no package:flutter, no dart:ui, no l10n imports — direct or transitive through other model files. Models hold data only (ARGB colors as int, hex colors as String, stored enum values); presentation (Color, IconData, localized labels) lives in extension <Model>Ui files under lib/shared/constants/*_ui.dart, hex⇄Color codecs in lib/shared/utils/color_hex.dart. Rationale: the model layer is slated for extraction into a pure-Dart core package shared with the selfhost server, and dart:ui does not exist in a plain Dart VM.
How to check (must return nothing):
grep -rln "package:flutter\|dart:ui\|l10n/" lib/shared/models/Fix: move the offending getter/method into the model's *_ui.dart extension (create it if missing), store the raw value in the model, and add the extension import at call sites. Never "fix" by re-adding a Flutter type to a model.
R2c-rpc — regenerate the RPC layer (mandatory when the diff touches a DAO or a model)
packages/core/tool/generate_rpc.dart emits the browser-side stubs, the
per-DAO dispatchers and the dispatch table from the DAO signatures and every
model those signatures reach. So a field added to Collection, Game,
CollectionItem — anything a DAO returns — changes the wire format while
changing no signature at all: nothing in the type system sees it, and the
stale stub silently drops the field.
If the diff touches packages/core/lib/database/dao/** or
packages/core/lib/models/**, regenerate and commit the result:
powershell.exe -Command "cd '$(wslpath -w "$PWD")/packages/core'; dart run tool/generate_rpc.dart"Do not hand-edit anything under packages/core/lib/rpc/generated/. The Phase 5
gate proves it: packages/core/test/rpc/generated_up_to_date_test.dart
regenerates in memory and diffs against the committed files, so a forgotten run
fails dart test.
New wire shape the generator refuses (No wire rule for X)? Teach it a rule in
_encode / _decode and cover it with a round-trip test in
packages/core/test/rpc/ — never work around it by degrading the DAO signature.
R2d — web readiness (mandatory)
The project is headed for a selfhost web build: same branch, web as one more build target, DAO calls become the client↔server RPC boundary, external APIs go through a server proxy. New code must not create rework for that plan. Check the diff for:
dart:io (Platform.is*, File, Directory, Process) in lib/features/ or lib/shared/. Platform branching goes through platform_features.dart flags; intrinsic file I/O (export/import, disk cache) stays behind existing service boundaries or a flag so web can stub it. dart:io inside lib/core/services/ that a web build will conditionally replace is acceptable; a Platform.isWindows inline in a widget is not.db.rawQuery outside lib/core/database/dao/ — every DAO method is a future RPC endpoint, so the UI/provider layer must call dao.method(...), never touch the Database handle. New DAO method signatures must be JSON-serialisable at the boundary: arguments and returns built from primitives, enums (sent as .name/.value), DateTime, models with toDb/fromDb, and collections thereof — no callbacks other than the established _getDatabase injection, no Database/Transaction parameters in public signatures, no returning raw Map rows where a typed record/model is feasible.lib/core/api/ clients (Dio) — never a one-off http/Dio call from a widget or provider; the proxy phase swaps base URLs in one place.dart:ui / package:flutter stay out of models and pure-logic layers (overlaps R2c) — the server imports these files in a plain Dart VM.webview_windows, window management, gamepad, Discord RPC, file pickers) — any new usage must sit behind a platform_features.dart flag, not a bare platform check.Fix: route the platform check through a flag, move raw SQL into a DAO method, move the HTTP call into the API client. Flag (don't silently accept) anything that would force the selfhost phases to redesign the new code.
R2e — theme awareness (mandatory)
The app has switchable themes (AppPalette.dark / AppPalette.sakura, selected in Settings → Appearance). Every color decision must survive both a near-black and a near-white background. Check the diff for:
Colors.* (except Colors.transparent) and no inline Color(0x...) in widgets — every color goes through an AppColors token, which reads the active palette. Semantic tokens for the common traps: over poster/image art use AppColors.scrim (+withAlpha at the call site) and AppColors.onOverlay; text/icons on brand-filled controls use AppColors.onBrand; drop shadows AppColors.shadow; modal barriers AppColors.barrier or scrim.withAlpha(...). Never assume "white text reads fine" — the background may be #FDF2F4.platform_ui.dart, service_badges.dart, RA/Discord brand constants, the settings capsule _k*Colors), color-picker swatch palettes (user content), luminance-based black/white contrast picks (luminance > 0.5 ? black : white), pure alpha masks ([white, transparent] shader gradients).AppColors.* / AppTypography.* / MediaTypeTheme.* in a static final, static const, top-level final, or a const constructor default — the value freezes on the palette active at first access and survives a theme switch. Use a getter (static Color get x => AppColors.y;) or compute inside build(). Grep the diff for static final/top-level final whose initializer mentions those classes.AppPalette as a field with a value for every palette (dark AND sakura — pick a sakura shade with real contrast on the light background, usually a darkened variant), plus a delegating AppColors getter. Never add a color that exists in only one theme.R3 — localisation
S.of(context).key or final S l = S.of(context);.lib/l10n/app_*.arb locale file (glob them — the set grows over time: en, ru, zh, …); placeholder names match across all of them; Russian plurals use ICU =0 / =1 / few / other. Languages without plural forms (e.g. Chinese) may render an ICU-plural key as a single flat string ({count} 项) as long as they keep the same placeholders.localizedLabel(S l) extensions, not raw .displayLabel.debugPrint, model field names, enum .name, test assertions.Goal: useful tests, not coverage theatre. 100% line/branch coverage is not the target. Aim for tests that break only when real behaviour breaks — and that would catch a future regression you'd actually care about.
Every test must pull its weight in one of three buckets:
1. UI doesn't silently break
expect(tester.takeException(), isNull)).find.byType(Container)). Design changes must not break tests. Localised string values — same rule: assert that some text appears, not that it equals a specific string.expect(find.text(collection.name), findsOneWidget) is OK; expect(find.text('Collections'), findsOneWidget) for a static title is not).2. Logic is verified reliably
fromJson/toJson, fromDb/toDb) when the change touches models.copyWith semantics when a new field is added.3. Method calls at the boundary are verified
verify(() => mock.method(args)).called(N) to pin down that the right method was called with the right args, the right number of times.verifyNever to assert negative-space guarantees (e.g. "no tag remap when sourceTagId is null").captureAny() to inspect complex payloads (e.g. "the cloned row has tag_id: null").Infrastructure rules (non-negotiable):
import '../../helpers/test_helpers.dart' — reuse mocks from test/helpers/mocks.dart, builders from builders.dart, fallbacks via registerAllFallbacks() in setUpAll.tester.pumpApp(), not a hand-rolled ProviderScope + MaterialApp.should [expected result] when [condition].Self-check before finishing a test: "If someone changed the design tomorrow (colours, labels, layout) — would this test fail?" If yes, and the change wasn't a logic change, the test is overfitted. Remove or relax it.
CHANGELOG.md — [Unreleased] section, Keep a Changelog version headers (## [Unreleased] / ## [X.Y.Z] - date) with Added / Changed / Fixed / Removed sub-sections; inside each sub-section, entries follow GNU Change Log style.
Entry structure — three parts separated by blank lines:
* path/to/file.dart (ClassName.methodName, OtherSymbol): what changed. Use full paths from the repo root and full symbol names (never abbreviate, never group with {foo,bar} syntax — every symbol must be greppable on its own). Several files with identical descriptions can be combined on one line separated by commas. A file with no specific symbol worth naming can be listed as * path/to/file.dart: what changed.Rules:
[Unreleased] that was never released, update the existing entry in place — don't add a separate Fixed / Changed bullet. Users should see the final state, not the development history. This applies to the topic line, body, and the file list alike.[Unreleased] cycle ("added music, then two tasks later fixed something in it") must never appear as its own entry — fold the final behaviour into the feature's entry, or drop it entirely if the feature text already covers it.Example:
- **Expand AniList search filters for anime and manga**
Anime tab grows from 2 filters to 4; manga from 2 to 4. Multi-select
genre uses OR match. Year filter uses `startDate` bounds so it works
for older and cancelled titles where `seasonYear` is null.
* lib/core/api/anilist_api.dart (AniListApi.browseAnime, AniListApi.browseManga):
Change `$genre: String` → `$genres: [String]`; add `$format`, `$status`,
`$startDateGreater`, `$startDateLesser` GraphQL vars.
* lib/features/search/filters/anilist_anime_format_filter.dart
(AniListAnimeFormatFilter), anilist_manga_status_filter.dart
(AniListMangaStatusFilter): New.
* lib/features/search/filters/manga_format_filter.dart (MangaFormatFilter.options):
Limit to MANGA, NOVEL, ONE_SHOT — MANHWA / MANHUA / LIGHT_NOVEL were
rejected by AniList's `MediaFormat` enum.docs/ — update only if the change actually affects them:
| File | When to touch |
|---|---|
ARCHITECTURE.md | New layer, major module, or shift in patterns. Keep it a high-level map — do NOT add per-file tables or SQL schema dumps |
CONTRIBUTING.md | Changes to development process |
CODESTYLE.md | New lint rules, typing conventions |
COMMITS.md | Changes to commit conventions |
RCOLL_FORMAT.md | Changes to .xcoll / .xcollx export format |
GAMEPAD.md | New focusable widgets, navigation rules |
SNACKBAR.md | Changes to context.showSnack() API or types |
Language per file: most are Russian. Keep each in its current language. Preserve formatting — make targeted edits, don't rewrite.
powershell.exe -Command "cd '$(wslpath -w "$PWD")'; flutter analyze --fatal-infos --fatal-warnings"
powershell.exe -Command "cd '$(wslpath -w "$PWD")'; flutter test"
powershell.exe -Command "cd '$(wslpath -w "$PWD")/packages/core'; dart test"
powershell.exe -Command "cd '$(wslpath -w "$PWD")/server'; dart test"packages/core and server resolve separately, so a change there is invisible
to flutter test — run all four.
Follow the failure-recovery rules below. When green, STOP — report what changed and wait for an explicit commit/push instruction.
| Failure | Response |
|---|---|
| Analyzer fails | Fix inline. Re-run analyzer only. Do not re-do earlier phases. |
| Test fails — a test I just wrote | Fix the test (wrong mock stub, missing fallback, wrong assertion). Re-run tests only. |
| Test fails — existing test | Default: the test is right, the production code is wrong. Do not edit the test yet. First, re-read the test and the code paths it covers. Ask: "Was this specific behaviour something I deliberately changed as part of the task?" Answer this honestly before touching anything. → If NO (surprise failure, behaviour change you didn't plan): back to Phase 1 — the code is wrong, fix the code, then Phase 3 for the affected area, then re-gate. → If YES (the old assertion contradicts the intended new behaviour, and the new behaviour is in the spec/user request): update the test, rerun tests. Document the behaviour change in the final report so the user sees what shifted. If unsure, default to NO. |
| Review (Phase 1-2) needs a code change | Fix inline. If the fix touches production code (not just comments/docstrings), add/update tests in Phase 3 before re-gating. |
| R3 reveals missing ARB keys | Add the key to every lib/l10n/app_*.arb locale file (glob them, don't assume a fixed set), run powershell.exe -Command "cd '$(wslpath -w "$PWD")'; flutter gen-l10n", re-run analyzer. |
generated_up_to_date_test fails | The RPC layer is stale — regenerate (dart run tool/generate_rpc.dart in packages/core) and commit the output. Never edit the generated files to make it pass. |
| Flaky test | Retry the affected test file once via flutter test path/to/test.dart. If it still fails, treat it as real. |
Anti-loop rule — if the same error has been attempted twice with different fixes and still fails, STOP and report to the user. Do not keep hacking.
Scope creep — unrelated issues discovered during review (pre-existing bugs, cruft in untouched files) are NOT fixed here. Note them in the final report; user decides.
One line per phase as it completes, e.g.:
Phase 1 simplify: 2 fixes (removed redundant setItemTag write, inlined unused helper).
Phase 2 R1 critical fix: SQLite LOWER() doesn't handle Cyrillic → switched to Dart toLowerCase. R2/R3 clean.
Phase 3 tests: 20 new tests across 3 files, all green.
Phase 4 changelog: 1 Changed entry; no docs/ touched.
Phase 5 gate: analyze clean, 4776 tests passed.
Risk: Low — re-downloadable cache only, no permanent data loss; affects the Settings cache button.
Status: ready for commit. Awaiting explicit /commit.A green gate proves the code compiles and the tests pass — it does not prove the change is safe to put in front of a real user. Close every run with a short, honest risk assessment so the user can decide whether to ship. Never rubber-stamp; if you can't find a risk, say why the change is inherently safe (pure addition, read-only, behind a flag), don't just assert "looks fine".
Cover four points, one or two lines each:
Blast radius — what it affects. The features, flows, screens, files, and stored data this change touches, and who is hit: all users, one platform (Windows / Android), or only users with a precondition (feature X enabled, a custom data folder, a specific profile, a populated cache/DB). Name the concrete surface, not "the app".
End-user safety. Can it lose or corrupt user data, delete files, break a DB migration, or wedge the app on the splash screen? Is the effect reversible (undo, re-download, re-sync from source) or permanent? Anything irreversible is called out explicitly. If the change deletes or overwrites anything on disk or in the DB, this point is mandatory, and you must distinguish destructive-but-recoverable (e.g. re-downloadable cache) from destructive-and-permanent (e.g. the only copy of a user upload).
Worst-case failure. If the change is subtly wrong despite the tests, what does the user actually experience — cosmetic glitch → broken flow → crash → silent data loss — and how likely is that given what the tests in Phase 3 actually pin down. Be specific about which failure modes the tests do not cover.
Bottom line. One rating — Low / Medium / High risk — with a one-sentence justification, plus any "watch this in the wild" notes: edge cases left untested, platform-specific behaviour, interactions with the data folder / profile / cache / migration chain.
Keep it factual and scoped to this diff. The bottom-line rating goes on the Risk: line of the report (see above); the four points expand it underneath when the change is anything more than trivial.
© hacan359, MIT. 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/finish of hacan359/tonkatsu_box.
Open the folder on GitHubat commit 00a4fac
Finish 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 |
|---|---|---|---|---|---|---|
| Finish this skillhacan359/tonkatsu_box | 581 | — | ~7.4k | Automated safety check: Pass | MIT | |
| Simple Englishmoeru-ai/airi | 50k | 2 repos | ~4.6k | Automated safety check: Pass | MIT | |
| StarRocks Release NotesStarRocks/starrocks | 12k | — | ~1.9k | Automated safety check: Notes | Apache-2.0 | |
| Cutting A ReleaseTriliumNext/Trilium | 38k | — | ~3.2k | Automated safety check: Pass | AGPL-3.0 | |
| Mole CLI Release Flowtw93/Mole | 70k | — | ~2.6k | Automated safety check: Pass | GPL-3.0 | |
| React Router Release Notes Prepremix-run/react-router | 57k | — | ~1.1k | Automated safety check: Pass | MIT |
moeru-ai/airi
Write or rewrite technical text with the rules of ASD-STE100 Simplified Technical English so it is clear, unambiguous, and free of AI slop.
StarRocks/starrocks
Drafts English release notes for a StarRocks patch release from the PRs merged into its release branch, then opens a documentation PR and hands translation to /translate.
TriliumNext/Trilium
A skill your agent uses when cutting, preparing, or debugging a Trilium release — bumping the monorepo version, tagging, or diagnosing a failed "Release" workflow run.
tw93/Mole
Runbook for assessing and executing a Mole CLI release: distribution channels, pre-flight checks, capital-V tags, build artifacts and the handoff to curated release notes.
remix-run/react-router
Polishes pending React Router change files before the versioning scripts run, and decides whether a long-form What's Changed section is warranted.
PrefectHQ/fastmcp
Cut a FastMCP release end to end. An agent skill from PrefectHQ/fastmcp.
Categories
End-of-task pipeline — simplify review, double review, tests, single analyze+test gate, changelog/docs. Finish is an agent skill from hacan359/tonkatsu_box. End-of-task pipeline — simplify review, double review, tests, single analyze+test gate, changelog/docs.
Finish fits situations like: youve finished implementing a task and want to harden it before committing; tasks that involve Changelog and release notes.
Run `npx skills add hacan359/tonkatsu_box --skill finish -a claude-code`. Or copy the skill folder (.claude/skills/finish in hacan359/tonkatsu_box) into .claude/skills/finish in your project. Claude Code loads it when a task matches its description.
Run `npx skills add hacan359/tonkatsu_box --skill finish -a codex`. Or copy the skill folder (.claude/skills/finish in hacan359/tonkatsu_box) into .agents/skills/finish 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 hacan359/tonkatsu_box --skill finish -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/finish, .gemini/skills/finish, .github/skills/finish and .opencode/skills/finish in your project.
Going by SKILL.md and its folder, Finish needs the command-line tools its instructions call (flutter, dart and git).
SKILL.md names 1 domain. As links in the text: gnu.org. 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.
Finish is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.4k tokens (SKILL.md is roughly 30k 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 Finish: Simple English (moeru-ai/airi, 50k stars), StarRocks Release Notes (StarRocks/starrocks, 12k stars), Cutting A Release (TriliumNext/Trilium, 38k stars) and Mole CLI Release Flow (tw93/Mole, 70k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
hacan359 (a GitHub user) maintains it in hacan359/tonkatsu_box, which has 581 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 8, 2026.
Source: hacan359/tonkatsu_box on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.