mcpField
W
wi-app

wi-app

github.com/wonder-image开发0170 次安装1 天前更新
代码仓库

关于 wi-app

wi-app 是用于在 wonder-image/app Composer 框架包中工作的 Agent 技能,强调它与独立站点的边界。它帮助开发者判断改动应属于框架、站点还是外部模块,并遵循项目架构与安全约定。

主要功能

  1. 01区分框架、站点与模块工作
  2. 02按任务定位架构参考资料
  3. 03说明模型与资源扩展规则
  4. 04涵盖 API、CSRF 与安全约定

适用场景

  1. 01编辑前判断请求对应的代码归属
  2. 02为任务查找相关框架参考资料
  3. 03核对组件或 API 改动的放置与验证规则

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wonder-image/skills --skill wi-app

安装后在 Claude Code 中输入/wi-app确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
architecture.md
component-catalogue.md
model-and-resource.md
permissions-and-users.md
scheduler.md
security.md
workflows.md

详细介绍

Wonder Image App

概述

使用此技能在 wonder-image/app 中进行开发时,应将其视为框架包,而不是独立应用。在修改代码、运行命令或决定新逻辑应放在哪里之前,务必明确区分框架与站点的边界。

术语表

wi-app 和 wi-site 的共用术语(两项技能中的措辞完全一致):

  • framework(框架) — wonder-image/app(Composer 包,github.com/wonder-image/app)。启用 wi-app 时位于仓库根目录;在站点内则位于 vendor/wonder-image/app/。
  • lib — wonder-image/lib(npm 包,github.com/wonder-image/lib)。JS / CSS 设计系统。源代码位于 node_modules/wonder-image/src/;编译后的副本位于 assets/lib/wonder-image/dist/。
  • scaffold(脚手架) — wonder-image/new-site(github.com/wonder-image/new-site)。站点模板。脚手架本身也是有效站点。
  • site(站点) — composer.json 依赖 wonder-image/app 的任何项目(即将框架安装在 vendor/wonder-image/app 下)。通常是脚手架或基于脚手架派生的项目。标准术语——优先使用“site”,而不要使用较早且混用的“consumer project” / “consumer app”。
  • module(模块) — 通过 Composer(或文件系统回退机制)发现的外部 Composer 包 wonder-image/<slug>。通过 module.json 和 ModuleInterface 入口提供自身的模型 / 资源 / 路由。
  • custom/ — 仅限站点使用的目录,用于存放项目页面、组件、布局、路由、配置和辅助程序。框架中绝不会出现此目录。
  • app/Models / app/Resources — 站点的 PSR-4 根目录(App\Models\... / App\Resources\...)。与框架的 class/App/Models / class/App/Resources(Wonder\App\Models\... / Wonder\App\Resources\...)不同。

何时切换到 wi-site

出现以下任意信号时,请切换到 wi-site——相关工作属于站点仓库,而非框架:

  • 仓库的 composer.json 未声明 "name": "wonder-image/app",而是在 require 下列出 wonder-image/app(框架作为依赖安装)。
  • 存在 docs/ai/PRODUCT.md(或尚未迁移的站点在仓库根目录存在 PRODUCT.md),其中声明这是 Wonder 站点(site_type: landing / corporate / blog / ecom / rsvp)——此文件只存在于站点中,框架本身绝不会包含该文件。
  • 仓库根目录下存在 vendor/wonder-image/app/——框架安装在 vendor/ 下,因此这是一个站点。
  • 请求的修改位于 custom/、app/Models、app/Resources、lang/、assets/{ASSETS_VERSION}/ 下,或位于框架仓库中不存在的路径。
  • 任务是“添加页面”“翻译字符串”“为此站点注册权限键”“编辑颜色令牌”“使用 .wi-* 组件 / lib 类”,或任何使用(而非扩展)框架的工作。
  • 如果你正准备修改 vendor/wonder-image/app/ 下的文件,请勿这样做。应将修改调整到 custom/ / app/ 中(仍属于 wi-site),或直接在框架仓库中提交修改(在该仓库中则适用 wi-app)。

从这里开始

  1. 编辑任何内容之前,先对请求进行分类。
  2. 判断修改属于框架、站点还是外部模块包。
  3. 只阅读与任务对应的参考文件:
    • 引导、注册表、路由、环境解析或模块加载:references/architecture.md
    • Model / Resource 扩展 API、架构、重复器字段和 CustomPageSchema:references/model-and-resource.md
    • 权限构建器 API、权限键和共享用户管理资源:references/permissions-and-users.md
    • 修改位置、验证和常见陷阱:references/workflows.md
    • CSRF、Cookie、身份验证辅助程序、上传、重定向、导出、SQL 转义、错误 / 日志安全、备份和用户同意:references/security.md

核心规则

  • 将 wonder-image/app 视为 Composer 库。实际运行时位于安装该库的网站中,即 vendor/wonder-image/app。
  • 除非确认其他情况,否则应假定 php forge ... 命令由网站执行。不要认为此包根目录中有 forge 可执行文件。
  • 新逻辑优先放在 class/App/*。只有运行时仍依赖 app/* 时才修改旧代码。
  • API 处理程序位于 app/http/api/*。不要在 app/api/* 中重新引入包处理程序;通过 Path::$api、Path::$appApi 和 Path::$apiDT 调用路由 /api/... 端点。
  • API bearer 由 Wonder\Api\Token\BearerVerifier 验证(签名、exp、针对 api_users.token 的 hash_equals、权限、IP/域名);应复用它,而不是手动解码 JWT。使用 ApiTokens::issue() 签发,使用 regenerateApiToken() 轮换。绝不要在 HTML 中打印 bearer(Credentials::appToken()、ApiTokens::pageToken()):页面打印 const API_TOKEN = '';,库会省略空的 Authorization。对于允许页面令牌的端点,如果请求未携带 bearer,且满足 Endpoint::sessionRequestAllowed()(同源、会话有效、对非 GET/HEAD 请求执行 Csrf::verify()),并且 BearerVerifier::verifySession() 通过,则该请求是 @system 页面访问;此时 isPageToken() 为 true,行可见性使用会话用户。令牌过期后要续期,网站页面应获取新的 CSRF(/api/csrf/),并更新 _csrf 和 <meta name="wi-csrf">;/api/token/page/ 仅为兼容性保留。仅限服务器的端点(部署、cron、外部触发器)应向 Handler::run() 传入 allowPageToken: false。api_activity 只保留 ApiTokens::fingerprint()。参见 docs/app/piattaforma/api.md#token。
  • 运行时回退值和种子负载应分开管理:
    • Wonder\\App\\RuntimeDefaults 用于渲染期间或组合内存配置时使用的运行时默认值。
    • Wonder\\App\\SeedDefaults 用于幂等的引导/种子负载,由 build/row、设置命令和基于种子的单例表单使用。
  • 编程时应考虑未来的集成与扩展。优先设计可由网站和外部模块复用、扩展、覆盖或集成的类和函数,而不是只解决眼前的本地问题。
  • 明确划分架构职责:
    • Model::tableSchema() 定义 SQL 结构
    • Model::dataSchema() 定义数据准备与持久化行为
    • Resource::formSchema() 定义后台输入项
    • CustomPageSchema 处理非 CRUD 后台页面
    • Repeater 处理可重复行及相关行同步
  • 表单输入始终必须通过 FormField 层级处理。 Wonder 前端主题(class/Themes/Wonder/)和 Bootstrap 后台主题(class/Themes/Bootstrap/)中的所有输入项,都必须通过 FormField / RepeaterColumn(或直接通过类型化的 Inputs\Input*)声明,并通过 Input::render($theme) 渲染。不得使用原始的 <input> / <select> / <textarea> HTML,也不得使用临时编写的渲染函数。缺少的输入类型应在框架层添加(类型化的 Inputs\Input*,通过 element() → FormField 中的辅助方法 → 各主题下的渲染器实现),而不是在调用处打补丁。完整理由及“缺少类型”的四步工作流程见 references/model-and-resource.md。
  • Wonder 日期渲染器只通过经过转义的 data-wi-* 属性描述 DatePicker、DateRange、DateTimeRange 和 SelectDate。它们的 jQuery UI 初始化应由 wonder-image/lib/src/build/frontend/js/form/input.js 中的 setInput() 负责;绝不要将字段值或边界值插入渲染器自带的内联脚本中。
  • 翻译通过 Wonder\Localization 处理:Set-up Traduzioni 页面会导出/导入 TranslationSource 的 Catalog(json、legal、model:<table>;模块通过 localization.sources 添加来源,网站通过 Catalog::set() 添加,设为 false 则移除);导入内容会先预览、存储在服务器端,且绝不会删除键。可翻译的模型实现 Translatable + HasTranslations,并通过 Model::translated($rows, $lang) 读取;值存储在 translations 中,状态为 automatic / reviewed / review,只有 wonder.content-translation 会写入 automatic 值(使用词汇表、记忆库和 Translator 驱动),且绝不会覆盖 reviewed 值。legal_documents 是唯一的法律来源(LegalDocument::make($type))。测试通过注入存储和驱动(Translations::useStore())进行,绝不调用 Google。参见 docs/app/concetti/traduzioni.md。
  • <wi-card> 已停用。 不要添加新的 <wi-card> 标签,也不要在新代码中调用 wiCard() / wiCardLink():在 app 中使用 Card,它会渲染 <div class="card">。编辑包含此标签的页面时,请将其替换。不要为 Card 添加更改标签的选项。保留库中的 createCard() 和 wi-card CSS 规则:迁移前,现有页面仍依赖它们。
  • 会话 CSRF 令牌由 Wonder\Http\Csrf 负责(token()、field()、verify();字段 _csrf,请求头 X-WI-CSRF,由 wonder-image ≥ 2.1.2-alpha.31 发送,基础布局中包含 <meta name="wi-csrf">)。两个主题的 Form 渲染器、Button::post()、POST Dropdown 项、Modal::form() 和 Resource 表单页面都会自行通过 Csrf::fieldFor() 输出该字段;GET 请求和无有效会话时不会输出。手写的 <form> 标签需自行添加 Csrf::field()。验证按路由进行:在路由或路由组上声明 ->csrf(),RouteDispatcher 随后会在 authorizeUser() 之后运行 Wonder\Http\CsrfGuard(令牌缺失或错误时返回 403);除 alert 外,所有 /api/backend/* 路由都已启用该功能;仅使用 Bearer 的路由绝不能启用。通过 POST 写入数据的页面处理程序必须在写入前调用 Csrf::verify(),并以 alert 929 失败;错误提示中绝不能包含“CSRF”或“token”(使用辅助方法 Csrf::ALERT、failureMessage()、oldInput()、flashFailure()、renderCsrfFailure())。绝不要对 GET 请求执行操作。AuthSession 委托给 Csrf;不要为新功能添加单独的令牌(customer-account 模块已移除 _contact_csrf,其表单使用 _csrf;Impersonation 保留其作用域令牌)。详情及其他安全约定见 references/security.md。
  • 共享组件上的确认操作使用库的 data-wi-confirm* 约定(wi.confirm(),返回 Promise<boolean>),绝不要使用 window.confirm 或手写 onclick(需使用 wonder-image 库 ≥ 2.1.2-alpha.31)。在库中,后台 modal(text, link, …) 是 wi.confirm() 的 @deprecated 别名;前端 modal(selector) 已弃用,应改用 wi.modal.open(id, { title }) / wi.modal.close(id)。核心 PHP modal()(app/function/backend/modal.php)以及 plugin.php 和 Backend\Table\Field 中的 onclick="modal(...)" 已在 main 分支移除(构成 app#129 中的破坏性变更,但尚未发布标签:v2.4.0-beta.5 仍包含它们);旧版 Delete 按钮现在会输出 data-wi-confirm* 并调用 ajaxRequest。新代码绝不调用 modal() 或选择 #modal。使用 Button::confirm($message, title:, ok:, variant:),以及带有 confirm、confirm_title、confirm_ok、confirm_variant 的 Dropdown 项。POST 操作应放在 <form> 上(Themes\Concerns\RendersPostForm 也会输出 CSRF 字段),其他操作则放在标签上。具有 'method' => 'post' 的 Dropdown 项会生成独立的 CSRF 表单;action() 会生成不带 href 的 <button type="button">。Modal::form($action, $method, $hidden) 会用 CSRF 表单包裹正文和页脚,页脚依次包含 Cancel 和 Save(cancel()、submit();手动调用 footer() 会替换它们),且必须在任何表单之外渲染(在 Resource 布局内会抛出 LogicException);在 Bootstrap 中单独渲染时,columns() / columnSpan() 会像 Resource 布局一样排列字段。日期输入会将带斜杠的值解析为 d/m/Y。内部部分各自提供一个公共方法(Modal::dialogClass()..footerClass()、Dropdown::toggleClass()、menuClass()、itemClass()),基于 HasPartAttributes / RendersPartAttributes 构建;这些类会附加到主题类名上,并统一放在一个 class 属性中。参见 docs/app/concetti/componenti/README.md。
  • 新组件或公共组件 API 必须在 docs/components/<category>/<slug>.php 中有对应的说明卡片;php tests/Docs/CatalogRenderTest.php 必须通过。主题支持情况由 ThemeSupport 计算,绝不要手动填写。参见 references/component-catalogue.md。
  • 修改引导流程、架构、路由、布局结构或面向开发者的约定时,应在同一工作中更新 docs/app/*。

任务路由

引导或运行时

先阅读 references/architecture.md,然后检查 wonder-image.php、class/App/Credentials.php、路由配置和相关注册表。对于解析 ROOT、加载 .env 或改变早期引导顺序的内容,请务必谨慎。

CRUD 资源、后台页面或 API 生成

先阅读 references/model-and-resource.md,了解 Model / Resource 扩展契约;然后阅读 references/architecture.md,了解注册表优先级和路由生成;最后阅读 references/permissions-and-users.md,了解 Resource::permissionSchema() 中引用的权限键。

表单输入(前端 Wonder 或后台 Bootstrap)

阅读 references/model-and-resource.md 中的“FormField hard rule”一节。任一主题中的每个输入项,都必须通过 FormField::key(...) / RepeaterColumn::key(...) 声明,或直接通过类型化的 Inputs\Input* 声明,然后经由 Input::render($theme) 渲染。新增输入类型时,应放在 class/App/ResourceSchema/Inputs/ 下,实现自己的 element(),在 FormField 上提供辅助方法,并使用 class/Themes/Wonder/ 和 class/Themes/Bootstrap/ 下的渲染器——不得在调用处编写专用 HTML。

默认组件或主题中的 UI / 样式

如果改动涉及框架自带的默认组件(class/App/Resources/.../*.php 视图、class/Elements/Components/ 下的非表单 Components、class/Elements/Media/ 下的 Media、class/Elements/Form/Components/ 下的表单 Components、class/Themes/{Wonder,Bootstrap}/ 下的 Wonder / Bootstrap 渲染器,或网站使用的任何 app/view/... 页面),权威 UI 规则手册是 wi-site/references/style-and-lib.md。wonder-image/app 中也适用优先复用 wonder-image/lib 的策略:不要在框架层发明新的 .wi-* 名称(这属于 lib 端的改动),不要在默认组件中固化特定网站的设计令牌,并确保兼容网站的 color.css / root.css。这也包括 Button、Badge、ButtonGroup 和 Dropdown 等共享操作基元。对于共享组件上类似链接的属性,优先使用通用的 concern class/Elements/Concerns/HasLinkAttributes.php,并将 href、target、rel、title、onclick、download 保存在 attributes 中,以便主题渲染器保持精简。在 wi-app 旁安装 wi-site,以便本地解析此参考文档。

组件卡片和目录

添加或修改 class/Elements/* 中的 Element 或其公共 API 时,请阅读 references/component-catalogue.md:其中说明了卡片位置和格式、验证测试、如何打开目录、PageAssets::once() 以及 lib 版本约束。

安全敏感代码

修改请求处理、会话、Cookie、上传、导出、重定向、SQL 辅助工具、日志记录或 API 身份验证前,请阅读 references/security.md。文档指出了各项契约的所属类;应复用该类,而不是在处理器或模块中重新实现检查逻辑。

权限、角色或用户管理

阅读 references/permissions-and-users.md。文档涵盖构建器 API(Permissions::reset()、Area::make()、Permission::make())、与模块权限的合并、运行时 $PERMITS 导出,以及共享的 UserManagementResource / BackendUserResource / ApiUserResource 流程。

模块系统

阅读 references/architecture.md。确保与 Composer 发现、文件系统回退、已启用模块状态,以及外部软件包的路由 / 模型 / 资源注册保持兼容。

控制台命令或本地启动流程

对于计划任务、cron 入口、任务提供者、保留策略、指标、站点地图迁移或 Google Places 位置同步(GoogleReviews),还应阅读 references/scheduler.md。

阅读 references/workflows.md。请记住,即使这些命令的源码位于此软件包中,预期的执行位置仍是网站。

验证

  • 使用 php -l 检查所有修改过的 PHP 文件。
  • 类移动或新增类时,运行 composer dumpautoload。
  • 如果改动影响引导、路由、控制台命令、资源、模型或请求处理器,请在站点中使用 php forge update --local 和 php forge start 进行验证。
  • 如果改动特定于 Herd,还要按照 references/workflows.md 中所述验证本地路由路径。

输出要求

  • 说明修复应归属框架、站点还是模块包。
  • 指明涉及的主要文件和注册表,不要笼统描述框架。
  • 如果框架根目录中的修改只有通过站点才会生效,请指出相应的集成验证需求。

评论

支持 Markdown