Skip to content

feat(social): 实现社交解锁状态管理与多语言支持 - #2672

Merged
wehos merged 16 commits into
Project-N-E-K-O:mainfrom
breakkh811-star:New
Aug 5, 2026
Merged

feat(social): 实现社交解锁状态管理与多语言支持#2672
wehos merged 16 commits into
Project-N-E-K-O:mainfrom
breakkh811-star:New

Conversation

@breakkh811-star

@breakkh811-star breakkh811-star commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

变更内容

  • 实现社交解锁状态管理,更新相关按钮样式和标题。
  • 补齐全部 locale 文本。
  • 集成透明卡片制作嵌入模式,优化资源加载和缓存控制。
  • 添加对应的前端与单元测试。

验证

  • 分支中已包含相关回归测试。
  • 创建 PR 前未重新运行完整测试套件。

回归报告 / Regression Report

  • 改动内容:新增透明卡片制作嵌入模式,并补充社交解锁状态、按钮样式和多语言文案。
  • 修改必要性:嵌入模式需要按模型类型加载轻量运行时;社交入口需要在首次使用后的前三个自然日保持锁定。
  • 改动前后:改动前卡片制作页只能走完整编辑器运行时,社交按钮在解锁日可能仍显示锁定状态;改动后嵌入页按需加载运行时,社交按钮会在午夜或语言切换时刷新解锁状态。
  • 潜在回归点:模型运行时资源版本缓存、嵌入页初始化以及社交按钮点击拦截和 UI 状态同步。已通过 Python 定向测试 5/5、Node 定向测试 5/5 和 diff 检查。

Summary by CodeRabbit

  • 新功能
    • 新增透明卡片制作器嵌入模式,支持 Live2D、VRM、MMD 和 PNGTuber。
    • 社交入口新增三天锁定与自动解锁提示,锁定期间按钮不可用并显示剩余天数。
  • 改进
    • 嵌入模式采用更轻量的渲染配置,提升加载速度与稳定性。
    • 优化静态资源缓存,仅对有效版本资源启用长期不可变缓存。
    • 自动纳入模板中的版本化资源,减少缓存失效和重复加载。
    • 更新多语言界面的社交入口名称与状态提示。
    • 优化 VRM 鼠标跟踪的启用与禁用行为。

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ef9a3e2e-7a9b-4ec8-b4dd-56b0e548a068

📥 Commits

Reviewing files that changed from the base of the PR and between 7600458 and daeb590.

📒 Files selected for processing (1)
  • tests/unit/test_vrm_interaction_static_contracts.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/test_vrm_interaction_static_contracts.py

Walkthrough

本 PR 新增卡片制作器嵌入模式、轻量模型运行时、社交按钮三天解锁状态、版本化静态资源缓存校验,以及项目根目录导入规范化喵。

Changes

卡片制作器与嵌入运行时

Layer / File(s) Summary
嵌入页面入口与启动流程
templates/card_maker.html, static/js/card_maker_embed_bootstrap.js, static/js/card_maker.js, tests/unit/test_card_maker_embed_static.py
模板按 mode=embed 选择资源。启动脚本加载页面配置和模型运行时。card_maker.js 复用配置 Promise 喵。
模型提供商与轻量运行时
static/live2d/live2d-model.js, static/mmd/mmd-init.js, static/vrm/vrm-init.js, static/vrm/vrm-manager.js, static/js/card_maker.js, tests/unit/test_card_maker_embed_static.py, tests/unit/test_vrm_interaction_static_contracts.py
Live2D、VRM、MMD 和 PNGTuber 支持嵌入加载。嵌入模式关闭交互模块,并减少 Live2D 初始化等待。VRM 禁用鼠标跟踪时清理回退视线目标喵。

社交入口解锁

Layer / File(s) Summary
社交入口解锁状态
static/avatar/avatar-ui-buttons/methods-buttons.js, static/app/app-ui/surface-floating-controls.js, static/social-embed.js, static/locales/*.json, static/i18n-i18next.js, tests/frontend/social_unlock_state.test.cjs, tests/frontend/avatar_ui_buttons_split.test.cjs, tests/frontend/yui-guide-day1-systray-intro.test.cjs
新增 window.nekoSocialUnlock。模块记录首次日期并计算三天锁定期。锁定时拦截社交入口点击,并更新按钮样式、ARIA 属性、标题和本地化文本喵。

静态资源与导入路径

Layer / File(s) Summary
静态资源版本与缓存校验
app/main_server/web_app.py, main_routers/pages_router.py, tests/unit/test_static_cache_policy.py, tests/unit/test_card_maker_embed_static.py, tests/unit/test_avatar_return_button_cat1_static.py
模板静态资源支持自动发现。仅符合生成版本格式的查询参数启用长期 immutable 缓存。新增运行时和聊天资源的版本跟踪喵。
项目根目录导入规范化
launcher_core/runtime.py, tests/unit/test_plugin_sdk_packaging.py
运行时和 PyInstaller SDK 收集测试将项目根目录置于 sys.path 首位,并移除重复路径喵。

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: enhancement

Poem

嵌入脚本开始加载喵
四种模型按需登场喵
三日状态守住入口喵
版本缓存保持长效喵
项目路径排好队喵

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确概括了社交解锁状态管理和多语言支持这一主要变更,内容清晰且与改动相关喵。
Description check ✅ Passed 描述包含变更概述、回归报告和测试信息,已说明未运行完整测试套件;其余大部分模板要求均已覆盖喵。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added enhancement New feature or request Needs Check! need doctor to check labels Aug 4, 2026
@breakkh811-star
breakkh811-star marked this pull request as ready for review August 4, 2026 02:45
@breakkh811-star
breakkh811-star requested a review from wehos as a code owner August 4, 2026 02:45

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@static/avatar/avatar-ui-buttons/methods-buttons.js`:
- Around line 108-113: Update refreshButtons() in
static/avatar/avatar-ui-buttons/methods-buttons.js:108-113 to query the
data-social-button marker written by applyButtonState(), or consistently change
registration to use data-neko-social-button. In
tests/frontend/social_unlock_state.test.cjs:77-105, make the mocked
document.querySelectorAll() return registered buttons and verify
refreshButtons() clears locked styling and updates the title on the unlock date.

In `@static/js/card_maker_embed_bootstrap.js`:
- Around line 44-53: Update _YUI_GUIDE_ASSET_VERSION_PATHS in
main_routers/pages_router.py to include all seven Live2D runtime assets loaded
by loadLive2DRuntime in static/js/card_maker_embed_bootstrap.js: the four
static/libs files plus live2d-core.js, live2d-emotion.js, and live2d-model.js.
Add regression assertions in tests/unit/test_card_maker_embed_static.py covering
lines 94-100 to verify each runtime asset changes static_asset_version produced
by _static_assets_ctx().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: de0dfe45-d807-4701-8be1-f1e265aca1e1

📥 Commits

Reviewing files that changed from the base of the PR and between e8a97d0 and 2cc2cd7.

📒 Files selected for processing (22)
  • app/main_server/web_app.py
  • main_routers/pages_router.py
  • static/app/app-ui/surface-floating-controls.js
  • static/avatar/avatar-ui-buttons/methods-buttons.js
  • static/js/card_maker.js
  • static/js/card_maker_embed_bootstrap.js
  • static/live2d/live2d-model.js
  • static/locales/en.json
  • static/locales/es.json
  • static/locales/ja.json
  • static/locales/ko.json
  • static/locales/pt.json
  • static/locales/ru.json
  • static/locales/zh-CN.json
  • static/locales/zh-TW.json
  • static/mmd/mmd-init.js
  • static/social-embed.js
  • static/vrm/vrm-init.js
  • templates/card_maker.html
  • tests/frontend/avatar_ui_buttons_split.test.cjs
  • tests/frontend/social_unlock_state.test.cjs
  • tests/unit/test_card_maker_embed_static.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)

Comment thread static/avatar/avatar-ui-buttons/methods-buttons.js
Comment thread static/js/card_maker_embed_bootstrap.js

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2cc2cd7ec4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


function refreshButtons() {
const status = getStatus();
document.querySelectorAll('[data-neko-social-button="true"]').forEach((btn) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use the same social-button marker when refreshing

When the midnight timer or localechange calls refreshButtons(), this selector never matches because applyButtonState() marks the button via btn.dataset.socialButton = 'true' (data-social-button), and there is no writer for data-neko-social-button. Users who leave the app open until the 3-day lock expires, or whose button initializes before i18n finishes, keep the grey disabled styling and stale title even though clicks are now allowed; query the same attribute that is actually set.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

该问题已在前一修复提交 fb0f3f2 中处理:refreshButtons() 已改为查询 data-social-button 标记,并补充了解锁日刷新测试。

Comment thread app/main_server/web_app.py Outdated
Comment on lines +42 to +43
if b"v=" in scope.get("query_string", b""):
response.headers["Cache-Control"] = "public, max-age=31536000, immutable"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Don’t make fixed-version submodules immutable

Applying a one-year immutable policy to every static URL containing v= also covers dynamically loaded modules whose cache buster is not tied to the file contents; for example, I checked static/mmd/mmd-init.js, which still loads all MMD submodules with the fixed ?v=1.0.0. After a user opens an MMD avatar once, a later release that changes one of those submodules can keep serving the old cached file for up to a year, so this should either be limited to URLs using the computed static_asset_version or those loaders need to propagate a changing version.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已处理,提交 5a27377:immutable 缓存现在只对内容派生的时间戳版本启用,固定版本如 MMD 的 ?v=1.0.0 不再被缓存一年;新增了覆盖动态/固定版本的缓存策略测试。

Comment thread static/locales/en.json
"screenShare": "Screen Share",
"social": "Neko Community",
"social": "nekoverse",
"socialCharging": "nekoverse charging — come back in {{days}} days.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Bump the locale cache version with new keys

Adding buttons.socialCharging requires bumping the locale cache buster in static/i18n-i18next.js; it still requests locale files with LOCALE_VERSION = '2026-07-27-merged-main-i18n', and the new immutable static caching means returning users can keep an older /static/locales/*.json?v=2026-07-27-merged-main-i18n that lacks this key for up to a year. In that case the locked social button renders the raw buttons.socialCharging key instead of the countdown text.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已处理,提交 5a27377:将 LOCALE_VERSION 更新为 2026-08-04-social-unlock,确保新增的 buttons.socialCharging 文案不会继续命中旧语言包缓存;相关 Node/Python 定向测试已通过。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/unit/test_static_cache_policy.py (1)

6-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

补充 CustomStaticFiles 的响应头回归测试喵。

当前参数化用例只覆盖 _has_generated_asset_version 喵。它没有调用 CustomStaticFiles.get_response,因此 app/main_server/web_app.py Line 59-60 的响应头行为即使回归,测试仍会通过喵。请添加有效 v、无效 v 和缺失 v 的响应级测试,并在合并前运行完整测试套件喵。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_static_cache_policy.py` around lines 6 - 19, Extend
test_only_generated_asset_versions_enable_immutable_cache with response-level
tests for CustomStaticFiles.get_response, covering a valid v value, an invalid v
value, and a missing v value. Assert the resulting response headers match the
intended immutable-cache behavior, so regressions in CustomStaticFiles rather
than only _has_generated_asset_version are detected; run the full test suite
afterward.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/main_server/web_app.py`:
- Around line 45-50: 在处理版本尾部的逻辑中更新条件,使 version_tail 同时满足 isascii() 和
isdigit(),确保仅接受 ASCII 数字;保留现有长度与版本参数筛选行为,并为 Unicode 数字尾部补充否定测试。

In `@static/i18n-i18next.js`:
- Around line 32-34: 将 static/i18next.js 中 LOCALE_VERSION 的日期格式值改为
_has_generated_asset_version 接受的生成资源版本格式,以启用 immutable 缓存策略;同时同步更新
static/yui-guide-day1-systray-intro.test.cjs 中对应的版本断言,确保测试与新版本值一致。

---

Nitpick comments:
In `@tests/unit/test_static_cache_policy.py`:
- Around line 6-19: Extend
test_only_generated_asset_versions_enable_immutable_cache with response-level
tests for CustomStaticFiles.get_response, covering a valid v value, an invalid v
value, and a missing v value. Assert the resulting response headers match the
intended immutable-cache behavior, so regressions in CustomStaticFiles rather
than only _has_generated_asset_version are detected; run the full test suite
afterward.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3db8c2a2-4f5e-4033-a3f3-c68a1c9d8ae5

📥 Commits

Reviewing files that changed from the base of the PR and between fb0f3f2 and 5a27377.

📒 Files selected for processing (5)
  • app/main_server/web_app.py
  • static/i18n-i18next.js
  • static/yui-guide-day1-systray-intro.test.cjs
  • tests/unit/test_card_maker_embed_static.py
  • tests/unit/test_static_cache_policy.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/test_card_maker_embed_static.py

Comment thread app/main_server/web_app.py
Comment thread static/i18n-i18next.js
@breakkh811-star

Copy link
Copy Markdown
Contributor Author

关于本轮缓存策略测试的 nitpick:已处理,提交 939aecd 新增了真实调用 CustomStaticFiles.get_response() 的响应级测试,覆盖内容派生版本、固定版本和缺失版本三种情况,并断言最终 Cache-Control 响应头。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 939aecda52

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if path.endswith(".js"):
response.headers["Content-Type"] = "application/javascript"
if _has_generated_asset_version(scope.get("query_string", b"")):
response.headers["Cache-Control"] = "public, max-age=31536000, immutable"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Limit immutable caching to complete asset versions

Because this header is now applied solely from the shape of the v query, every ?v={{ static_asset_version }} URL must be covered by the timestamp that generated it. I checked templates/index.html and /static/social-embed.js?v={{ static_asset_version }} is emitted there, but social-embed.js is not part of _YUI_GUIDE_ASSET_VERSION_PATHS; after a patch that only changes that script while APP_VERSION and the tracked paths stay unchanged, clients that already cached it under the unchanged generated v can keep the old embed for up to a year. Either make the version depend on all versioned assets or only mark known tracked paths immutable.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已处理,提交 56cbafc:将 static/social-embed.js 加入 _YUI_GUIDE_ASSET_VERSION_PATHS。现在该文件内容变化会更新 static_asset_version,避免继续复用旧的 immutable 缓存。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/test_plugin_sdk_packaging.py`:
- Line 46: 在测试函数 test_current_sdk_modules_are_importable 开始时调用
_ensure_project_root_first,确保导入所有 plugin.sdk 模块前项目根目录优先。保留现有调用,并让该 helper
在相关两个测试开始前都执行,避免测试顺序影响模块解析。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f3df3f29-7e82-4a26-b7a6-589f6e63c8d1

📥 Commits

Reviewing files that changed from the base of the PR and between 939aecd and 2228de5.

📒 Files selected for processing (2)
  • launcher_core/runtime.py
  • tests/unit/test_plugin_sdk_packaging.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)

Comment thread tests/unit/test_plugin_sdk_packaging.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2228de5855

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread static/mmd/mmd-init.js
window._mmdModulesLoading = true;
window._mmdModulesFailed = null;
console.log('[MMD] 开始加载依赖模块');
const lightweightEmbed = window.__NEKO_CARD_MAKER_EMBED__ === true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add mmd-init to static version inputs

When only the MMD loader changes after this release, clients that opened the main page can keep /static/mmd/mmd-init.js?v={{ static_asset_version }} cached under the new immutable policy, but main_routers/pages_router.py still tracks only static/mmd/mmd-ui-buttons.js for MMD, not this loader. That means changes like this lightweight-embed branch may not reach existing users until some unrelated tracked asset changes or the one-year cache expires; include mmd-init.js (or the MMD loader set) in the static asset version inputs before serving it immutably.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已处理,提交 56cbafc:将 static/mmd/mmd-init.js 加入 _YUI_GUIDE_ASSET_VERSION_PATHS,MMD loader 的变更现在会触发新的静态资源版本。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56cbafc4a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +59 to +60
if _has_generated_asset_version(scope.get("query_string", b"")):
response.headers["Cache-Control"] = "public, max-age=31536000, immutable"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Track every asset before serving it immutable

Fresh evidence after the current fixes: templates/index.html still serves assets such as /static/app/app-chat.js?v={{ static_asset_version }} (lines 411-412), but _YUI_GUIDE_ASSET_VERSION_PATHS only includes selected static/app files and the app-ui/app-interpage globs, not static/app/app-chat.js (main_routers/pages_router.py lines 97-103). With this new header, a release that changes only one of those untracked versioned files keeps the same generated v, so returning clients can reuse the old script for up to a year; either make the version input cover every static_asset_version URL or restrict immutable to known tracked assets.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已处理,感谢指出。之前版本仅维护了部分静态资源清单,导致模板中的 app-chat.js 等资源单独变更时版本号不会更新。现在 pages_router 会自动扫描 templates 中所有带 static_asset_version 的静态资源引用,并将实际存在的文件加入版本计算,同时保留运行时/非模板资源的手工清单。新增回归测试覆盖全部模板引用;修复已在提交 90cd5e0 中推送。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/test_card_maker_embed_static.py`:
- Around line 142-153: Update test_template_versioned_static_assets_are_tracked
to assert referenced_paths is non-empty and explicitly contains ROOT /
"static/js/card_maker_embed_bootstrap.js" before the existing subset and
tracked-path assertions, ensuring the template scan actually discovers a known
versioned asset.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c00d129-de46-48c2-9954-c47a7787a954

📥 Commits

Reviewing files that changed from the base of the PR and between 56cbafc and 90cd5e0.

📒 Files selected for processing (2)
  • main_routers/pages_router.py
  • tests/unit/test_card_maker_embed_static.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)

Comment thread tests/unit/test_card_maker_embed_static.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3c1cca1f9f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if path.endswith(".js"):
response.headers["Content-Type"] = "application/javascript"
if _has_generated_asset_version(scope.get("query_string", b"")):
response.headers["Cache-Control"] = "public, max-age=31536000, immutable"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Limit immutable caching to version-owned assets

Fresh evidence after the template-scan fix: static/app/app-react-chat-window/cat-local-chat.js builds /static/assets/neko-idle/thought-items/cat1-chat-angry.gif?v=<react_chat_asset_version> from its own script URL, but _REACT_CHAT_ASSET_VERSION_PATHS in main_routers/pages_router.py does not include that GIF. With this broad Cache-Control, a release that changes only that image keeps the same numeric React-chat version, so clients that have already loaded the cat-local-chat sticker can reuse the old image for up to a year; include that asset in the React-chat version inputs or only mark paths owned by the version immutable.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已处理,提交 7600458cat1-chat-angry.gif 现在加入 _REACT_CHAT_ASSET_VERSION_PATHS,因此由 cat-local-chat.js 继承的 react_chat_asset_version 会随该 GIF 的 mtime 更新;同时补充回归断言。定向 pytest 39/39、Ruff、Node 语法检查均通过。

Comment thread static/vrm/vrm-init.js
'/static/vrm/vrm-cursor-follow.js',
...(!lightweightEmbed ? [
'/static/vrm/vrm-interaction.js',
'/static/vrm/vrm-cursor-follow.js'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep VRM cursor tracking disabled in embeds

When mode=embed skips vrm-cursor-follow.js, VRMManager._initMouseLookAtTracking() falls back to the legacy mousemove path because CursorFollowController is undefined; that path installs a document mousemove listener and the animation loop still assigns vrm.lookAt.target to the fallback target even after disableMouseTracking() sets tracking false. VRM card embeds can therefore keep following the viewer's mouse despite the lightweight/static embed intent; either keep the cursor-follow controller loaded so it can be disabled, or gate the fallback path on the embed/disabled tracking state.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已处理,提交 7600458。VRM legacy fallback 现在完整遵守鼠标跟踪禁用状态:禁用时不初始化/处理 mousemove,移除已注册 listener 并清空 lookAt target;重新启用时可恢复 fallback。补充了对应静态契约测试。定向 pytest 39/39、Ruff、Node 语法检查均通过。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/unit/test_vrm_interaction_static_contracts.py (1)

24-40: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

让静态契约测试验证控制流位置喵

Line 36-40 只验证字符串存在于方法片段中。它不能证明 removeEventListener(...) 位于 if (!effectiveEnabled) 分支,也不能证明 _initMouseLookAtTracking() 只在启用路径执行喵。

未来把这些调用移到无条件路径时,测试仍可能通过。请按分支边界拆分源码片段,或使用 AST/VM 测试验证这两个控制流不变量喵。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_vrm_interaction_static_contracts.py` around lines 24 - 40, 更新
test_vrm_legacy_mouse_tracking_respects_disabled_state,使其按
setMouseTrackingEnabled(enabled) 中的启用与禁用分支拆分源码并分别断言:removeEventListener(...) 仅位于
!effectiveEnabled 分支,_initMouseLookAtTracking()
仅位于启用路径;不要仅在整个方法片段中检查字符串存在。保留现有对初始化和动画禁用状态的断言。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/unit/test_vrm_interaction_static_contracts.py`:
- Around line 24-40: 更新
test_vrm_legacy_mouse_tracking_respects_disabled_state,使其按
setMouseTrackingEnabled(enabled) 中的启用与禁用分支拆分源码并分别断言:removeEventListener(...) 仅位于
!effectiveEnabled 分支,_initMouseLookAtTracking()
仅位于启用路径;不要仅在整个方法片段中检查字符串存在。保留现有对初始化和动画禁用状态的断言。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cfd99e8b-d941-4031-9a89-b0b22843a652

📥 Commits

Reviewing files that changed from the base of the PR and between 08ebc51 and 7600458.

📒 Files selected for processing (4)
  • main_routers/pages_router.py
  • static/vrm/vrm-manager.js
  • tests/unit/test_avatar_return_button_cat1_static.py
  • tests/unit/test_vrm_interaction_static_contracts.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Project-N-E-K-O/N.E.K.O.-PC (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • main_routers/pages_router.py

@breakkh811-star

Copy link
Copy Markdown
Contributor Author

已处理本轮 CodeRabbit nitpick,提交 daeb5907test_vrm_legacy_mouse_tracking_respects_disabled_state 现在按 !effectiveEnabled 分支边界拆分源码:明确断言 removeEventListener(...) 仅在禁用分支,_initMouseLookAtTracking() 仅在启用路径,并保留初始化与动画禁用状态断言。定向 pytest 3/3、Ruff、diff 检查均通过。

@coderabbitai coderabbitai Bot removed the Needs Check! need doctor to check label Aug 5, 2026

@wehos wehos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

肘赢了、奈斯!!!

@wehos
wehos merged commit 9a224e9 into Project-N-E-K-O:main Aug 5, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants