BallonsTranslator Agent Skills & AI Rules

GitHub

深度学习辅助漫画翻译工具, 支持一键机翻和简单的图像/文本编辑 | Yet another computer-aided comic/manga translation tool powered by deeplearning

RAW Rules
1 Discovered Rules • ~1,833 Estimated Tokens
Quick:
Loading skill content...

AI Agent Protocol & Instructions

AGENTS.md root-instruction ~1,833 tokens
Raw
# AGENTS.md

## Project Shape

BallonsTranslator is a PyQt/qtpy desktop app for comic image translation.

- `ballontranslator/launch.py`: startup, dependencies, Qt setup, and headless mode.
- `ballontranslator/ui/`: canvas, panels, module manager, and workers.
- `ballontranslator/modules/`: registered detector/OCR/translator/inpainter implementations.
- `ballontranslator/utils/proj_imgtrans.py`: project persistence and image/textblock state.
- `ballontranslator/utils/textblock.py`: central TextBlock domain object.
- `ballontranslator/utils/config.py`: persistent config and module settings.
- Read [Text engine](doc/ui/text_engine.md) before changing text layout, effects, interaction, geometry, performance, or rendering; follow its topic links.
- Read [Draw panel](doc/ui/draw_panel.md) before changing drawing tools, canvas gestures, brush modifiers, drawing/inpaint state transitions, or drawing save/export behavior.

Use `rg` for repo search.

## Changes and Data Safety

- Preserve behavior unless explicitly asked to change it; prefer small, reviewable changes within the existing architecture.
- Treat pre-existing modified, untracked, and ignored files as user-owned. Never delete, overwrite, move, clean, or restore them without explicit authorization for the exact paths, especially config, backups, credentials, projects, and models. Follow existing save/backup behavior for source images, translations, masks, and project JSON.
- Passive config/project loading must warn about unknown, removed, renamed, malformed, or out-of-range optional data, discard only invalid portions, and continue. Never let it replace an existing file with empty/template state. Keep live runtime values and explicit write/export boundaries strict; give new saved fields defaults for older projects.
- Use the existing module registries and stable keys; renames require compatibility aliases. Preserve lazy/eager model-loading behavior. Config UI metadata must be lazy or `SafeEval`-compatible and pure, without executing initialization, `_setup_*`, updates, `flush`, model loading, downloads, or network calls.
- New dependencies require approval. Optional integrations must fail gracefully with a clear setup message.
- Make surprising behavior opt-in or clearly discoverable through existing config/UI/module parameters. Preserve Qt localization and ensure pipeline features work or safely no-op in headless mode.
- Keep long-running inference, IO, downloads, and model loading off the Qt main thread; trace signal and worker ordering, especially in `ui/module_manager.py`.

## Performance and Maintainability

- Trace production callers and data flow before changing code. Search for existing methods, helpers, and patterns; reuse or extend the owning implementation before adding another. Prefer standard-library and Qt facilities over custom equivalents.
- Use the simplest structure that meets current requirements. Add a helper or abstraction only when it removes demonstrated duplication or establishes a meaningful responsibility boundary. Avoid pass-through wrappers, speculative extension points, generic frameworks for one concrete operation, and layers that merely forward the same data.
- Put integration in the feature's owning module and shape APIs around production callers. Avoid test-only constructors, injection points, and shared hooks; tests can patch small instance attributes or narrower internals. Use names that make ownership clear.
- Check call frequency across the full operation and repeated lifecycle events. Reuse available results instead of repeating lookups, conversions, copies, validation, IO, or initialization. Fix duplicate calls and signal-driven work at their owner before adding caches or parallelism; justify performance complexity with tracing or measurement.
- Update only changed data and widgets. Keep setters and refreshers idempotent and coalesce equivalent work. Sanitize config at load/migration boundaries; reserve whole-panel rebuilds for reset/restore rather than ordinary row/card edits.
- Use indexed lookups for repeated access and derive values on demand, avoiding per-item full scans and eagerly materialized maps. Reuse existing caches; new caches need a demonstrated cost and explicit invalidation/lifetime. Keep render-only state out of shared config.
- Give state transitions one clear owner. Avoid redundant synchronization paths, equivalent signal emissions, and broad `blockSignals()` used to hide update loops.
- Simplification must remove the obsolete path too: unused helpers, shims, hooks, duplicate state, and architecture-preserving tests. Review the complete caller chain for leftover indirection and repeated work.
- Add useful type hints and return types to new or modified functions. Prefer domain/Qt types and precise callables; use `Any` only at dynamic boundaries and avoid unrelated annotation churn.

## UI Styling

- Lightweight settings/tools should reuse a frameless `Qt.Dialog`, transparent outer widget, rounded theme-token `QFrame`, and scoped stylesheet. Keep native dialogs for platform workflows; confirmations, progress, and costly-to-dismiss flows must not close on outside clicks.
- Keep selectors and lists in the application font; use a dedicated preview for content fonts. Match widget structure before adjusting alignment, such as bare checkboxes plus `ParamNameLabel`.
- Scope config styles by object/section names, never broad widget selectors. Use `resources/themes.json` and `resources/stylesheet.css` tokens, except established accents such as `rgb(30, 147, 229)`. Custom config rows needing a painted background require an object name and `WA_StyledBackground`.
- Scope ordinary checkbox indicators without affecting icon-based controls. `QListWidget` indicators are item-view subcontrols; style their selected, hover, and disabled states separately and check readability in both themes.
- Render manually painted SVG pixmaps through `ui/icon_rendering.py`.
- Never change style machinery inside `Polish`, `StyleChange`, or `Paint`: no `setStyle`, `setStyleSheet`, explicit polish/unpolish, `ensurePolished`, or delegate replacement. Re-entering native style code can crash Qt. Prefer scoped subcontrols, construction-time setup, or idempotent setup in safe show/input events.

## Qt Event Filters

- Reuse `OutsideClickFramelessMixin` from `ui/framelesswindow.py` before the Qt base for lightweight centered, draggable windows with Escape/outside-click dismissal, `title_bar`, and `close_button`. Keep `hide()` for cached panels; override `_dismiss_transient_window()` with `reject()` for staged dialogs and `_preserve_on_outside_click()` for owned popups/dialogs.
- Application event filters are global hooks: install only while active where possible, and remove on hide, collapse, close, or destruction.
- Check relevance before event details. Global filters first check visibility, receiver, and widget/event types; local filters first guard the watched object. Only then access `event.type()`, global positions, or widget-specific methods.
- Outside-click handling should use widget-target mouse presses and explicit popup/dialog whitelists, not broad geometry or `QWindow` interpretation.

## Qt Signals and QObject Lifetimes

- Never connect child/transient signals to lambdas, nested functions, or partials capturing parents or other QObjects. Bindings can retain callbacks and invalid wrappers after native deletion. Prefer bound QObject slots, action data/properties read through `sender()`, or typed row signals.
- Pure-Python or fixed-lifetime callbacks without a demonstrated lifetime problem need no blanket rewrite.
- `close()`/`hide()` do not delete objects. For one-shot modal dialogs, read state after `exec_()` and call `deleteLater()` in `finally`; preserve intentionally cached panels.

## Comments and Documentation

- Comment non-obvious intent, invariants, compatibility, and ordering/failure constraints, especially around Qt, model loading, persistence, and IO. Explain subtle preserved behavior during refactors; omit boilerplate and narration. Include a standard Python `>>>` doctest example for core classes and complex functions.
- Keep maintainer guides focused on ownership, stable contracts, failure modes, extension points, and verification. Update only missing or changed guidance; a bug fix alone does not justify an addition. Keep implementation details in code/tests and investigation history in PRs. Revise existing explanations, document each fact once, and check the whole document for redundancy.

## Verification

- Test observable behavior and failure modes through real construction paths, not obsolete APIs, incidental widget hierarchy, object names, sizes, margins, spacing, or stretch factors.
- Run targeted import checks and relevant tests for Python changes. UI-heavy changes require `python -m py_compile` on touched files, `git diff --check`, and an offscreen Qt smoke check when practical. Use a themed-app pass for styling and state any unverified UI/threading behavior.
- Risky global-filter changes need a regression proving irrelevant receivers/non-mouse events are ignored before `event.type()` is requested.
- QObject lifecycle fixes need deferred-delete processing and assertions for behavior plus wrapper/registry release. Run both PyQt5 and PyQt6 when binding behavior matters.
- Completion requires existing workflows and older projects to work, new behavior to be configurable or discoverable, and verification results or limitations to be stated.