Skip to content

Optimize P0-P2 stability, performance, and packaging#58

Merged
ShellMonster merged 48 commits intomainfrom
feature/p0-p2-optimizations
Apr 28, 2026
Merged

Optimize P0-P2 stability, performance, and packaging#58
ShellMonster merged 48 commits intomainfrom
feature/p0-p2-optimizations

Conversation

@ShellMonster
Copy link
Copy Markdown
Owner

@ShellMonster ShellMonster commented Apr 28, 2026

User description

Summary

  • Complete P0-P2 hardening across CI, backend limits/timeouts, provider logging, worker behavior, Docker health checks, and Tauri asset/CSP boundaries.
  • Improve desktop performance and maintainability with template grid virtualization, unified template scrolling, narrower Zustand subscriptions, slimmer history cache, lazy locale loading, and component/API splits.
  • Bump app metadata to v2.8.4 and add a local Tauri packaging script that builds the Go sidecar while skipping updater signing on developer machines.

Verification

  • cd backend && go test ./... && go vet ./...
  • cd desktop && npm run type-check && npm run build
  • cd frontend && npm run type-check && npm run build
  • docker compose config
  • cd desktop && PATH="$HOME/.cargo/bin:$PATH" npm run tauri:build:local

Notes

  • Tag v2.8.4 has been pushed.
  • Local macOS DMG generated at desktop/src-tauri/target/release/bundle/dmg/大香蕉 AI_2.8.4_aarch64.dmg.

CodeAnt-AI Description

Tighten app stability, speed up template browsing, and make image handling safer

What Changed

  • The app now uses a lighter template browser that only renders visible cards, keeping search and filters responsive even with 900+ templates
  • Reference images are limited to 10 files, 20MB each, and 80MB total, with clearer errors when uploads or local image picks go over the limit
  • Provider errors and logs now show safe, shortened previews instead of full response bodies or secret data
  • Desktop startup and language switching avoid loading every language file up front, and the app now switches languages after the needed file is loaded
  • The backend and Docker setup now use clearer health checks and connection settings so long-running generation streams stay connected and deployment checks catch frontend or Nginx failures

Impact

✅ Faster template browsing
✅ Fewer upload failures from oversized reference images
✅ Clearer provider error messages

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

ShellMonster and others added 29 commits April 28, 2026 01:37
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Also adds a local Tauri packaging script that builds the sidecar and skips updater signing for developer machines without release secrets.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 28, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Apr 28, 2026
@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented Apr 28, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 688 complexity · 83 duplication

Metric Results
Complexity 688
Duplication 83

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the application's stability, performance, and maintainability by addressing critical areas from backend infrastructure to frontend user experience. It introduces robust error handling, optimizes resource usage, and streamlines the development and deployment workflows, ensuring a more reliable and efficient application for both desktop and web environments.

Highlights

  • P0-P2 Stability and Hardening: Implemented comprehensive hardening across CI, backend limits/timeouts, provider logging, worker behavior, Docker health checks, and Tauri asset/CSP boundaries to improve overall system stability.
  • Desktop Performance and Maintainability: Enhanced desktop application performance and maintainability through template grid virtualization, unified template scrolling, narrower Zustand subscriptions, a slimmer history cache, lazy locale loading, and component/API splits.
  • Packaging and Build Process: Updated app metadata to v2.8.4 and introduced a local Tauri packaging script that builds the Go sidecar while bypassing updater signing for developer machines.
  • Reference Image Limits: Added strict validation for reference images, limiting them to a maximum of 10 images, 20MB per image, and a total of 80MB per request, for both multipart uploads and local file paths.
  • Enhanced Provider Logging and Error Handling: Improved diagnostic logging for providers (OpenAI, Gemini) to redact sensitive information and bound response body previews, ensuring better troubleshooting without exposing secrets or excessive log data.
  • Optimized Worker Pool Behavior: Refactored the worker pool to directly execute provider generation within the worker goroutine, handling panics gracefully and ensuring context cancellation properly terminates long-running operations like multipart writes.
Ignored Files
  • Ignored by pattern: **/*.json (4)
    • desktop/package-lock.json
    • desktop/package.json
    • desktop/src-tauri/tauri.conf.json
    • frontend/package.json
  • Ignored by pattern: **/*.lock (1)
    • desktop/src-tauri/Cargo.lock
  • Ignored by pattern: **/*.md (2)
    • docs/superpowers/plans/2026-04-28-p0-p2-optimization-plan.md
    • docs/superpowers/specs/2026-04-28-p0-p2-optimization-design.md
  • Ignored by pattern: **/*.toml (1)
    • desktop/src-tauri/Cargo.toml
  • Ignored by pattern: **/*.yml (2)
    • .github/workflows/pr-check.yml
    • .github/workflows/release.yml
  • Ignored by pattern: **/package-lock.json (1)
    • frontend/package-lock.json
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant enhancements to backend security and frontend performance. Key changes include the implementation of strict reference image validation (size, count, and file type), refactored worker pool logic with panic recovery, and optimized HTTP server timeouts to support SSE long-connections. On the frontend, performance was improved through virtualized rendering in the template market, lazy-loaded i18n bundles, and a bounded localStorage cache for history records. Additionally, Zustand subscriptions were optimized using useShallow to minimize unnecessary re-renders. Review feedback focuses on reducing code duplication in validation handlers, externalizing hardcoded magic numbers in the grid layout logic, and moving helper functions outside of hooks to improve code organization.

Comment thread backend/internal/api/handlers.go Outdated
Comment on lines 566 to 580
if err := validateReferenceImageCount(len(refImageBytes) + 1); err != nil {
Error(c, http.StatusBadRequest, 400, err.Error())
return
}
if err := validateReferenceImageSize(file.Name, int64(len(file.Content))); err != nil {
Error(c, http.StatusBadRequest, 400, err.Error())
return
}
if err := validateReferenceImagesTotalBytes(totalReferenceImageBytes(refImageBytes) + int64(len(file.Content))); err != nil {
Error(c, http.StatusBadRequest, 400, err.Error())
return
}
refImageBytes = append(refImageBytes, file.Content)
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The logic for validating reference images is duplicated across multiple places in this handler. Consider extracting this into a helper function to improve maintainability and ensure consistent validation rules.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 47d6182. The repeated reference image byte validation path now goes through appendReferenceImageBytes/validateReferenceImageBytesAppend, so count, per-file size, and total-size checks stay centralized before adding content.

typeof window !== 'undefined'
? window.innerWidth || document.documentElement.clientWidth
: width;
const columnCount = width > 0 ? getTemplateColumnCount(width, viewportWidth) : 2;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The getTemplateColumnCount function uses hardcoded magic numbers for breakpoints and column counts. These should be defined as constants at the top of the file or in a configuration file to improve maintainability.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 617f729. Template grid columns and breakpoints are now named constants (TEMPLATE_GRID_COLUMNS / TEMPLATE_GRID_BREAKPOINTS) instead of inline magic numbers.

Comment on lines +19 to +27
const isTextInputTarget = (target: EventTarget | null) => {
const element = target as HTMLElement | null;
return Boolean(
element &&
((element as any).isContentEditable ||
element.tagName === 'INPUT' ||
element.tagName === 'TEXTAREA')
);
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The isTextInputTarget function is defined inside the hook but is only used as a helper. It should be moved outside the hook or to a utility file to avoid re-creation on every render.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Already fixed in fbaab63. isTextInputTarget remains module-scoped outside the hook and now uses instanceof HTMLElement instead of unsafe casts.

Comment thread desktop/src/App.tsx
const nextLanguage = language === 'system' ? languageResolved : language;
if (!nextLanguage) return;
if (i18n.language !== nextLanguage) {
void changeAppLanguage(nextLanguage);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: This fire-and-forget language switch introduces a race condition: if language changes happen quickly, an older async call can finish last and overwrite the newer selection, leaving UI language out of sync with store state. Serialize or cancel in-flight language changes (or await the latest request) so only the newest selection is applied. [race condition]

Severity Level: Major ⚠️
- ⚠️ Desktop UI language may not match selected language.
- ⚠️ i18n instance can diverge from config store state.
- ⚠️ Users quickly toggling language see inconsistent translations.
Steps of Reproduction ✅
1. Start the desktop app so that `App` from `desktop/src/App.tsx` mounts and subscribes to
the config store's `language` and `languageResolved` at lines 12–13, and note that the
language change effect at lines 18–25 calls `void changeAppLanguage(nextLanguage);` when
`i18n.language !== nextLanguage` (line 23).

2. Open the Settings UI that renders `SettingsModal` from
`desktop/src/components/Settings/SettingsModal.tsx` (file referenced by Grep) and rapidly
change the language selection in the `<select>` control twice (e.g., from `zh-CN` to
`system` and then quickly to another concrete language), causing `handleLanguageChange` at
lines ~663–678 (see Grep output) to be invoked multiple times in quick succession.

3. Each `handleLanguageChange` invocation updates the Zustand config store via
`setLanguage(...)` / `setLanguageResolved(...)` and then performs a fire‑and‑forget
language switch by calling `void changeAppLanguage(...)` at `SettingsModal.tsx:666` and
`:676`, and `App.tsx:23` also issues its own `void changeAppLanguage(nextLanguage);` based
on the updated store state, resulting in multiple concurrent `changeAppLanguage` calls for
different target languages.

4. In `desktop/src/i18n/index.ts:26–30`, each `changeAppLanguage` call asynchronously
loads translations (`await localeLoaders[lang]()` at lines 21–22 via
`ensureLanguageResource`) and then calls `await i18n.changeLanguage(normalized);`; because
these asynchronous operations can complete in any order, an earlier call (for the first
language the user briefly selected) can finish last and set `i18n.language` back to the
outdated value while the config store still holds the latest language, leaving the UI text
(which reads from `i18n`) out of sync with the stored `language`/`languageResolved` until
some later action happens to trigger another correction.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** desktop/src/App.tsx
**Line:** 23:23
**Comment:**
	*Race Condition: This fire-and-forget language switch introduces a race condition: if language changes happen quickly, an older async call can finish last and overwrite the newer selection, leaving UI language out of sync with store state. Serialize or cancel in-flight language changes (or await the latest request) so only the newest selection is applied.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 28, 2026

CodeAnt AI finished reviewing your PR.

ShellMonster and others added 19 commits April 28, 2026 16:37
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@ShellMonster ShellMonster merged commit e594c22 into main Apr 28, 2026
5 checks passed
@ShellMonster ShellMonster deleted the feature/p0-p2-optimizations branch April 28, 2026 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant