更新日志

Swift Web 框架的版本发布历史,包含 CLI 工具、框架模块与文档站的所有变更记录。

本文件按月汇总 Swift Web 5 仓重大变更,月内按 framework / starter / standards / cli / docs 5 仓拆分。只记录重要新特性 / 重要重构 / 重要 BUG 修复 / Breaking Change / 跨仓事件。完整变更请查 git log。


2026-09

framework v0.140.0 → v0.155.0 · starter v0.35.13 → v0.37.0 · standards v0.13.27 → v0.13.89 · cli v0.21.1 → v0.23.1

本月聚焦缓存与部署一致性、API 生成可靠性及双工具协作;同步收口时长单位,补齐影视 SEO、认证控制和播放质量埋点。

framework

  • ⚠️ 时长与上传 API 收口 — 组件、composable 与模块配置的数字时长统一为毫秒,周期配置改用 Nm / Nh / Nd 或 always(ISR TTL 仍为秒);上传族 isSmall → thumbnail、retryNum → retries、threadNum → concurrency,回顶层级 token 改为 --sw-back-top-z
  • ⚠️ ISR TTL 明确设限 — 禁止 isr: true,声明值限定为 60–3600 的整数秒;对外 s-maxage 封顶 60 秒,避免多层缓存叠加放大陈旧内容(#394 / #414)
  • 🚀 影视结构化数据 — useSeo 新增 video / media / itemList,输出 VideoObject、Movie / TVSeries / TVEpisode 与 ItemList,并接入视频 sitemap;调用方提供真实业务数据(#381)
  • ⚠️ 请求配置统一 — 新增 request.transport 支持 base64 / binary;nitroApiFetch 直接读取 runtimeConfig 并消费全局 request.headers,退役 swTimeout / apiTransport 扁平键及业务桥接插件;明文业务失败保留真实 errorCode(#383 / #391 / #392 / #409)
  • ⚠️ API 生成边界重整 — 文档源配置归入 nuxt.config.ts 的 swiftConfig.apiDocs,凭证使用 API_DOCS_TOKEN;OpenAPI 优先按 tags 分组,生成物标记 @generated,手写接口放 app/api/manual/ 并自动注册;YAPI 支持参数模板路径,拉取、解析或命名失败时保留旧产物(#402 / #403 / #404 / #406)
  • 🚀 认证与系统信息控制 — auth.deviceLogin 可单独关闭设备登录,auth.enabled 统一控制自动登录入口;自动重登拆分身份 cookie 与用户资料,客户端系统信息按 clientRefreshTtl 复用(默认 300 秒)(#410 / #412 / #413)
  • 🐛 播放异常与签名续播 — 收敛 iOS 全屏和切换异常;SwVideoPlayer 与 SwVideoFeed 的 hls.js 路径在分片签名过期或网络错误时受限重拉同一地址并续播(#398 / #405 / #408)
  • 🐛 图片与加密资源容错 — SwImage 缺少地址时降级占位,避免整页 SSR 500;加密资源忽略过期请求结果,缓存读写失败降级到资源加载(#380 / #397 / #421)
  • 🚀 会话与播放质量埋点 — 自建通道增加来源、UTM、落地页和设备上下文,30 分钟无活动后换新会话;新增首帧、起播耗时、缓冲累计与 play_id,修复首屏重复 PV,并补记 hls 致命错误(#415 / #417 / #423 / #425)
  • 🚀 外链与预览控制 — 新增 useExternalRedirect 提供安全外链中转逻辑;SwVideoPreview 增加 settled 汇总终态,useHoverPreview.closeOnScroll 支持原位预览场景(#400)

starter

  • 🔄 部署统一单进程 — 测试与生产均采用 PM2 fork 单进程,配套进程配置应用与 nginx 缓存探针,避免多实例 ISR 快照交替;页面按类型声明明确 TTL(standards#86 / framework#414)
  • 🔄 接口接入模板更新 — 手写接口示例迁入 app/api/manual/,移除运行时环境桥接插件;API / 埋点代理携带 X-Site-Id,代理入口跟随项目 API_PREFIX

standards

  • 🔄 Claude / Codex 共用规则 — 共用入口收敛到 AGENTS.md,补齐 Codex MCP 薄壳;skills 镜像统一为实体目录,消除 Windows symlink 检出差异(#72)
  • 🔧 MR 提交与收尾完善 — 提交前核对默认分支基线,阻止复用已合并分支;审核跟踪按实际 reviewed SHA 判定,明确 Closes / Refs 与 issue 收尾边界(#70 / #73 / #78)

cli

  • ⚠️ 手写 API 命令对齐 — sw add api 改为生成 app/api/manual/ 顶层函数模块,sw_project_apis 根据 @generated 区分生成物
  • 🐛 项目创建与配置修复 — 新项目使用 skills 实体镜像,关闭 dev mock 时保留测试夹具;补齐 transport、设备登录与系统信息复用配置,并提示 JSON 配置可能被 nuxt.config.ts 覆盖

docs

  • 🚀 使用指南补齐 — 新增 useExternalRedirect 三语参考,补全组件 CSS token 表;API 生成、渲染 TTL 与部署指南同步新契约
  • 🐛 文档站构建配置修复 — catch-all 文档页改用显式 prerender 规则,移除不存在的 ~/api 自动导入,PWA 名称与描述改从站点配置派生

跨仓事件

  • 🔧 核心五仓接入 MR 门禁 — 普通开发统一短期分支 → MR → dev,接入自动审核及检查;npm 发版保留维护者本机显式操作,docs 保留 dev 部署(framework#416)
  • 🔧 Nuxt 安全升级 — framework、starter 与 docs 升级 Nuxt 4.5.2,修复开发工具与 SSR 相关安全问题,并校验消费链兼容性(framework#386)

2026-08

framework v0.95.0 → v0.140.0 · starter v0.32.0 → v0.35.13 · standards v0.4.4 → v0.13.27 · cli v0.16.4 → v0.21.1

特大月(5 仓合计 1000+ commits)。月初收尾 ISR 缓存正确性战役(canonical 策略反转为「默认跟随访问域名」);随后主线转向工程治理三役——规则三层化、e2e 进 CI 门禁、feature-branch flow 迁移(dev/vN 退役);framework 侧完成 PWA 体系大修与移动端播放兼容批。

framework

  • ⚠️ SwVideoPreview 默认播满 60 秒即停 + loop 默认改 false(#286,0.101.0)— 两条行为 BC。预览地址的常见形态是「运营没单独配预览资源时,回退正片播放地址」,而组件此前没有任何时长上限且默认循环 ⇒ hover 多久就流多久,等于付费正片能被当预览看完。这个口子对所有 applier 都开着,只能靠每个业务方自己想起来堵。
    新增 maxDuration(默认 60,0 = 不限),按累计播放时长计(暂停 / 缓冲不计入),到点 hls.stopLoad() + pause()(保留最后一帧)并 emit capped。60 的依据:实测业界策展预览片素材本就 55s~2min(腾讯 112s / 优酷 55s),60 秒对它们几乎不触发(走 @ended 自然收尾);而 60 秒之于 90 分钟正片是 1.1%,靠 hover 累积看完不可能。loop 同期翻为 false —— 实测两家均不循环,循环本质是「素材太短」的补丁,且它与上限是一对(6 秒素材配 60 秒上限会重播 10 次)。
    顺带收口取源为空时的静默:此前三条路径(fetchPlayUrl: null 却没传 url / id 为空 / 拉取结果无可用地址)都是 emit 完 loading 就再无音讯 ⇒ 消费方只能永远停在 loading 态(cinebay 的加载扫描线因此无限扫)。统一 emit 新事件 empty(不用 error——「本来就没有预览源」是业务合法态)。
    迁移:需要循环显式传 loop、需要更长显式传 maxDuration;applier 侧自写的「N 秒后 v-if 卸载播放器」兜底与「超时强解 loading」hack 都可整段删掉
  • 🐛 useHoverPreview 内置触摸门控(#287,0.101.0)— 源码注释此前写着「触摸设备无 mouseenter,天然不触发(无需额外守卫)」,这是错的:浏览器为兼容只监听鼠标事件的老站点,会在 tap 后补发一串兼容性鼠标事件(mouseover / mouseenter / mousemove / click)。实测(Pixel 7 画像 + 真实触摸输入)还暴露出比"多弹一下"更重的后果:tap 之后根本不会有 mouseleave —— 手指离开屏幕不产生「指针移出」,要等下次 tap 别处才补发 ⇒ 移动端点一下卡片,浮层弹出来后一直挂着,而不是「闪一下就被导航冲掉」。
    判定优先按 PointerEvent.pointerType(判「这一次交互用什么发起」),拿不到才回落 matchMedia,并留 allowTouch opt-out。别单独用媒体查询判:(hover:hover) and (pointer:fine) 判的是「设备主要输入能力」,二合一设备上双向误判 —— iPad + 触控板返回 true(手指 tap 照样放行)、触摸主导 + 外接鼠标返回 false(鼠标 hover 被误杀,比原 bug 更糟)。调用方建议从 @mouseenter="show" 改为 @pointerenter="show" 才能吃到精确判定
  • ⚠️ --container-padding 加宽屏阶梯(≥1280 → 48px,≥1600 → 96px)(#284,0.100.0)— 视觉变更:宽屏内容区四周出现留白。这是 #283 的续修:把默认上限提到 1920 后,用户在 1920 CSS 视口验收发现「看着没以前好看」——根因是 1920 的容器在 1920 屏上等于满铺,max-width 形同虚设,内容只被 24px 的 padding 内缩、观感贴边。
    业界实测定案(playwright 在 1920 视口量线上 DOM):与我们同形态(无侧栏、居中容器)的 bilibili,留白不靠 max-width、靠 padding —— max-width: 2260px; padding: 0 140px,且 padding 按断点递增(1440 视口时降到 60px)。YouTube(内容 240→1920)与爱奇艺(192→1897)看着"左边有留白"其实是侧栏占位、内容区本身满铺,与我们非同类,不作对标。
    ⇒ 职责划分(本次的核心结论):--content-max-width 定「最宽到哪封顶」(只对 2K/4K 屏起作用);--container-padding 定「任何宽度下边上留多少」。此前一直在调 max-width,方向错了。
    顶档取 96 而非 bilibili 的 140:140 是配合其 2260 上限设计的(主场 2560 屏),我们 1920 在 1920 屏即到顶,再留 140 会偏空。
    迁移:无需任何 applier 改代码(实测七个 applier 无一覆盖过该变量)。想收窄内容区的站,--content-max-width 与 --container-padding 必须一起调 —— 只改前者会在宽屏被 96px padding 二次挤窄(设 1280 实际只剩 1088)。示例见 starter overrides.css 示例 3。
  • ⚠️ --content-max-width 默认 1200px → 1920px(#283,0.99.0)— 视觉变更,全站内容区变宽。1200 是「文章站 / 营销站」传统档(Bootstrap .container 1320 / Tailwind max-w-screen-2xl 1536 同派),而本生态消费方以内容站为主,宽屏下明显偏窄。
    判据是生态自己投的票,不是业界对标:anibay / cinebay / yc001 三站各自独立在 overrides 里收敛到 1920(yc001 写 120rem,同值)。默认值站在 1200 等于让每站都记得写那一行 —— 漏写就是 bug(cinebay#7 验收当场才发现)。业界数据只作佐证:内容站无一使用 ≤1536 的窄容器(iQIYI 1808 / bilibili 2260 / YouTube 2864,Netflix 与 Disney+ 干脆不限)。
    要理解的语义:1920 在 1920 屏上等于满铺(只剩 --container-padding 的 24px),2560 屏上才居中留白 —— bilibili / YouTube 在 1920 屏同样满铺,且那三个站都没觉得需要另调 padding。长文本页不受影响:正文行长由页面自己的 max-width 约束(starter 的 8 个静态页均为 44rem),与站级容器无关。
    迁移:不想变宽的站在自身 overrides.css 写回 --content-max-width: 1200px(一行)。已写 1920 覆盖的站不必立刻删(同值幂等),下次改 overrides 时顺手清理。
  • 🚀 构建期拦下「声明不缓存却被可缓存通配吞掉」(#277,0.98.0)— 存在可缓存通配时,它覆盖的每个路径都被缓存,子路径写 isr: false / cache: false 都挡不住(缓存包装在 app 初始化时按「已注册 handler 的路由模式」一次性决定,每请求合并出的 routeRules 不参与该决策)。这类页面 lint / typecheck / build 全绿、显示也正常,只有 curl 响应头看得出来。
    按 ssr 分档,不是一律报错:ssr: false 放过(返回构建期生成的 SPA 空壳、按定义与请求无关,实测同一页两个不同 query 的 HTML 字节完全相同 ⇒ 缓存无害);ssr: true(或不声明)报错——它会真 SSR 渲染,且同时骗过 eslint no-query-in-cacheable-ssr(那条规则的前提是「文件声明了 isr/swr/cache/prerender」,而它声明的是 isr: false)⇒ 能合法读 query 却被缓存 ⇒ 内容错配。分档让误报为零,故 error 级站得住、不需要 opt-out 机制
    0.98.1 修了它自己的一处误报:redirect / proxy 规则不渲染页面(前者发 3xx、后者转发上游),被通配缓存不产生内容错配,却被 0.98.0 当成违规拦下。上线当天就在 yc118 的真实构建里撞到(一条 /home 重定向)。⚠️ 顺带一条教训:0.98.0 发版前我判断「全生态命中 1 处、零误报」,依据是扫各仓 nuxt.config 的静态 routeRules——那看不见页面级 defineRouteRules 展开成的 glob。判「生态里有没有某种规则形状」只能真跑一次 build
  • 错误 toast 与上报解耦(#282,0.97.0)— errorHandler 新增 toast 旋钮:错误时是否给终端用户弹可见 toast。默认 false = 静默上报(对齐 Sentry / Bugsnag 业界默认;此前 0.87.0 起启用即无条件弹「系统出现了一个错误」,对内容站沉浸浏览是纯打扰)。要旧行为显式 { "errorHandler": { "enabled": true, "toast": true } }。POST 上报路径不变。消费方背景:湾系四仓升级被此项卡拍板(bay-admin#39 / snapbay#11 / bayverse#4),本条落地后解锁
  • ⚠️ origin / canonical 策略反转(#278 续,0.96.0 – 0.96.1)— 上月 0.95.0 的修法是「以 NUXT_PUBLIC_SITE_URL 为主路径」,实践中被推翻,理由有三:开发者常不知道正式生产域名、生产域名会换、一个产品往往有多个域名。新策略:
    L1  显式 useSeo({ siteUrl })   单页覆盖
    L2  NUXT_PUBLIC_SITE_URL       配了它才收敛到该域名(opt-in,属运营决策)
    L3  useRequestURL().origin     默认:跟随用户实际访问的域名
    

    真正的修复落在 L3 能不能工作上——isr → cache 翻译时固定注入 varies: ['host', 'x-forwarded-proto'],让被缓存的页面拿回 Host。代价是这两个头进缓存 key ⇒ 条目数 ≈ 合法域名个数(对多域名产品正是想要的);「任意 Host 造条目」应在反代层挡(server_name 列全 + default_server 返 444)。连带把「未配 NUXT_PUBLIC_SITE_URL」从告警降为正常状态——只有存在 prerender 页时才必须配
  • ⚠️ SwInput 升级为 wrapper 结构(#305,0.108.x)— 皮肤(边框 / 背景 / focus 态)从内层 input 上移到新增的 wrapper 元素,结构 BC:applier 把 --sw-input-* 变量或选择器写在内层 input 上的会退回默认皮肤。适配前先升 ≥0.108.3——0.108.2 及更早存在 class/style 落点错位,变量会落错层
  • 🐛 PWA 体系大修:manifest 从来没被 link 进 head(#355 等,0.122.0–0.128.0)— 全生态所有 PWA 站点的 manifest 一直在生成、却从未被页面引用(@vite-pwa/nuxt 只注册组件不挂载,「注册 ≠ 被消费」,只有查线上 DOM 才看得见)。同批:manifest 补 background_color(深色站冷启白闪)/ lang / description(#357);iOS 主屏预填名与 standalone 判定修正(#352 / #353);BC:framework.pwa 收窄为纯布尔,manifest 内容迁至 swift.config.json(#359,0.125.0);SwAddToHomescreenGuide 适配 iOS 26 新工具栏 + 默认皮肤重做(0.128.0)
  • 🔄 裸源发布试验与撤回(#289 → #362,0.124.0–0.126.0)— dist/runtime 曾改发裸 TS/.vue 源(意图让消费方 IDE 直读源码),实测撤回:裸源让部分消费链类型解析劣化、发布产物形态变化牵连既有规则。0.126.0 恢复全编译并加 assert-publish-shape 四条发布态守卫,防产物形态再静默漂移
  • 🚀 键盘可达性批(#331,0.130.0)— 可排序表头内容包进 <button>(W3C APG 范式,结构 BC:#header-* slot 内容成为 button 后代、只能放 phrasing content,th:hover 视觉选择器需改指向 button.th-inner);SwTable 挂 @row-click 但行内无可聚焦元素时 dev 告警(WCAG 2.1.1);贴片按钮 div→button、扫码器 focus ring。9 个 applier 实测零适配
  • 🔄 升级 pinia 4 + 删除 ESM alias hack(0.131.0)— Pinia 3.x 时代的 ESM 兼容 alias 整段移除;连带暴露个别 applier 自声明 pinia 的存量违规(重复框架模块构建期护栏会拦)
  • 🚀 移动端播放兼容批(#365 等,0.132.0–0.133.0)— iPhone 改为优先原生 HLS:hls.js 默认走 ManagedMediaSource,而 UC 等第三方内核「只推时间轴不渲染画面」(真机实测);补齐内联播放属性(webkit-playsinline / x5,防 iOS 强制全屏);新增劫持型浏览器拦截 blockHijackingBrowsers(UC / 夸克 / QQ / 百度默认拦截换提示、微信有意不拦,#hijacking-browser slot 可自定义)
  • 🚀 触屏进度条两态手势(#372,0.138.0)— 播放中可在收起态进度条上横向起手直接拖动 seek,不必先唤出控制条;收起 / 展开两态各自独立的手势语义
  • 🐛 可缓存页 Set-Cookie 剥离 + 声明冲突护栏(#374 / #375,0.139.x)— ISR 等可缓存页渲染期写的 Set-Cookie 会进缓存副本、向后续所有访客重放,nitro plugin 统一剥离 + dev 告警;页面级 defineRouteRules 与 config routeRules 同 key 冲突改为构建期报错。升级跳过 0.139.0 直上 0.139.1
  • 🚀 SwSelect 远程搜索(#376,0.140.0)— 新增 remote / loading props 与 @search 事件,搜索词交由业务侧异步取数

starter

  • ⚠️ 模板默认改为「跟随访问域名」 — (footer) 下 8 个静态页 prerender: true → isr: true,NUXT_PUBLIC_SITE_URL 由必填改为可选。原因是 prerender 在构建期没有真实请求、拿不到 Host,origin 只能来自那个变量 ⇒ 只要有一个 prerender 页,就被迫配置、被迫收敛。isr: true(缓存到下次部署)运行时开销差别可忽略,却不需要该变量
  • 🔧 CI 模板长出 e2e 门禁(standards#48 配套,0.35.0–0.35.1)— verify 与 e2e 同 stage 并行;e2e 按「改动是否落在适用面」的路径过滤触发(页面 / 布局 / 中间件 / server route / 框架配置 / 依赖),改组件样式的 MR 只跑 verify;发布 MR 必跑全量兜底
  • 🐛 0.35.9 事故版与 CI 契约测试(0.35.10)— 一次脚本正则(re.S 贪婪匹配)把 .gitlab-ci.yml 吞剩 3 个 job 发了出去:ci/lint 合法、单测照绿——「删除型 bug 对『验存在』的测试免疫」。0.35.10 修复并新增 ci-jobs-contract.spec.ts(job 逐个在 + 总数 + 行数下限),随模板带给所有 applier

standards

  • 🔧 CI 里调 pnpm 必须用 npx --yes pnpm@11,禁止 npm i -g pnpm — runner 是共享 shell runner(多项目并发跑在同一台机器、同一个全局 node 环境),全局装等于动全局 bin,并发时一个 job 能把另一个 job 正在用的 pnpm 二进制掀掉。实测事故:两条 pipeline 同一秒创建、同落一台 runner,其中一条第四步炸 pnpm: No such file or directory,而它前三步用同一个 pnpm 都正常、重跑即绿。排障判据:verify 红在「某步报 pnpm/node 二进制 not found」且前面几步用同一二进制都成功 = 基础设施 flake,先重跑别查代码
  • 🚀 sw-standards sync 自助同步 CLI(#32,0.10.0)— applier 一条命令自助同步规则(marker 段 / skills / 薄壳),替代「等维护者集中推送」;输出规则变更摘要,--check 带退出码语义
  • 🔄 规则三层化(#43)— 下游约定文件从「单文件巨石」拆为三层:AGENTS.md 常驻索引(P0 红线 + 选型表 + 细则通道)+ .claude/skills/sw-* 按需加载细则 + standards rules/ 主源;sync 目标家族同步扩展(agents / skills / 薄壳三类),Codex / Copilot 经 .agents/skills 镜像同享
  • 🚀 lint 执法批 — prettier 基座 semi: true + singleAttributePerLine(0.11.0,全生态存量重排);stylelint 新增 hover-media-gate(:hover 必须包 @media (hover: hover),配合触摸端 hover 粘滞修复)与 component-token-prefix;eslint root-class-sw-prefix 升 v3(根 class 名字必须与组件名对得上)

cli

  • 🐛 sw config set 拒绝合法的对象配置(#46,0.16.5)— framework.pwa 与 framework.errorHandler 在 framework 侧的类型是 boolean | XxxOptions,却被错列进 cli 的「纯布尔键」白名单 ⇒ sw config set framework.pwa '{"enabled":true}' 被当成非法形状拒绝写入。改为按 union 逐层校形状(叶子键 / 子字段 / 父对象整体 set 三种入口都覆盖)
  • 🐛 pwa 对象配置反被判成「关闭」、删掉 @vite-pwa/nuxt(#47,0.16.6)— 上一条的回归。#46 之前对象值在写入前就被拒、这条路径不可达;摘掉布尔守卫后对象值合法了,但 applier 派发端仍是 getNestedValue(...) === true ⇒ 对象恒判为 false ⇒ 走 disablePwa()。配置写着 PWA 开启、package.json 里的依赖却被删,且提示语淹没在成功回显里。修法是照抄 framework 自己的 resolvePwa 归一(boolean → 自身;对象 → 看 .enabled,缺字段即关)
    ⚠️ 教训:从校验白名单里移除一个 key,等于给下游放行了它没见过的形状 —— 移除前要查这个 key 下游有没有按旧形状假设写的消费者。同型的 cli#39 当年选择在写入端拒绝来回避,#46 拆掉那道拒绝却没补派发端,于是原样复发
  • 🔧 bin 路径去掉 ./ 前缀(0.16.7)— 消除每次 npm publish 刷的 "bin[sw]" script name ... was invalid and removed 警告。措辞有误导性(听着像 bin 被删了,实际只是剥前缀),零行为变化,改的是「每次发版都刷一遍的噪音」
  • ⚠️ AI 调用安全批(#48 / #49,0.20.0)— sw upgrade 加 --check / --yes,非交互(MCP / 管道)写操作不再零确认、退出码分层 0/1/2(三条 BC);MCP 全部 15 工具补 annotations(只读 / 写 / 破坏性外观区分)
  • ⚠️ pwa 装卸职责移交 framework(0.17.0–0.19.0)— cli 的 pwa feature 不再装卸 @vite-pwa/nuxt(由 framework 统一携带);framework.pwa 配置形态随 framework#359 收窄纯布尔,删 validatePwaShape

docs

  • 🐛 /composables/use-hover-preview 自上线起线上一直访问不到 — docs 是 SSG 站、prerender 路由靠 crawler 从已有链接爬,而该页既不在侧边栏、正文也无人链接 ⇒ 零入边 ⇒ 从未被生成,线上返回首页 fallback。阴险处在于构建 / 测试 / lint 全绿,本地 pnpm dev 直接敲 URL 还完全正常(dev 按需渲染、不走 crawler),只能靠人肉发现。已补侧边栏条目,并加孤儿页守卫:每个 content 页必须至少有一条入边(侧边栏 / catalog.ts / 其它页正文链接,三选一即可 —— 强求「都进侧边栏」会误伤后两类合法形态)
  • 🚀 guide 跟进流程演进(三语) — 新增「测试同步与门禁」章(e2e 适用判定 / verify 门禁 / 覆盖率 ratchet / 登录态注入);Git 协作规范整章重写为 feature-branch flow;生产部署页改运维 runbook 形态(首次上线 9 步 checklist + 第 N 次一个命令)

跨仓事件

  • 🔧 feature-branch flow 迁移(standards#51 / #52)— 9 个 applier 默认分支统一 dev/main,dev/vN 长期分支全部退役;只保留 dev/main(集成 / 测试)与 main(生产)两条长期分支,其余短期分支合并即删;生产发布 = dev/main → main 发布 MR,mr-review 对发布 MR 出「🚀 发布摘要」(D5)、对触及 server/ / CI / 依赖等风险路径的 MR 不自动合需人工(D6);starter CI 新增 release-guard 提示 job。分支命名与 upstream-first 定调为推荐并默认、不强制——机械层只保护两条长期分支本身
  • 🔧 e2e 进 CI 门禁 + 覆盖率 ratchet(standards#48 / #49)— e2e 正式成为 applier 合并门禁(与 verify 并行、按路径触发、发布 MR 全量兜底);覆盖率逐仓 ratchet 只升不降;登录态 e2e 由 setup 走 UI 登录一次 + storageState 复用(TS-003);首批接入 yc118 / yc124

2026-07

framework v0.58.1 → v0.95.0 · cli v0.10.0 → v0.16.4 · standards v0.3.2 → v0.4.4 · starter v0.21.0 → v0.32.0

主题 / 语言切换器收口与 0.64 架构正交化打底,中旬 CSS 变量两层命名模型与 token 表面扩面固化设计语言,下旬管理台组件(SwTable)、SwSelect 搜索/创建、tracker 自建通道与自助注册连发;starter 电影三件套 + 通用页脚模板落地;设计体系(Claude Design / Open Design 双轨 + 20 卡管线)全量上线;月末 OpenAPI 双源与 ISR 私有护栏、表单控件族统一高度 + SwInput、SwVideoFeed 预载省流开关收尾。

月末最后一周是「ISR 缓存正确性」战役(#271 起):先发现自托管 node-server 上 isr 完全不生效(nitro core 根本不消费它),继而连锁挖出通配污染、fs 驱动父子路径冲突、多动态段规则被丢弃、零段父路径漏配、被缓存页丢 Host 致 canonical 变 localhost 五个全绿却静默失效的坑——逐个补上构建期护栏。

framework

  • 🚀 主题能力重构(epic #191)— theme 配置收敛为单旋钮 theme.mode(system / toggle / dark / light)+ color-scheme 解耦 + resolvedTheme;内置切换器 SwThemeSwitch(仅 toggle 模式渲染,token / icon slot / 作用域插槽三档定制);toggle 模式注入防 FOUC inline bootstrap
  • 🚀 SwLangSwitch 内置语言切换器(#192)— 自 gate(i18n 启用且 locales ≥ 2 才渲染)+ 联动 cli 语言配置 + SEO 前缀切换,修 SSR 直出前缀语言页选中态
  • 🚀 加密 useCookie 覆盖 + framework-api.json 结构化 props(#203)— framework 的 useCookie(自动 cachePrefix + AES)注册 auto-import 同名覆盖 Nuxt 内置;framework-api.json 组件层新增结构化 props 数组 + tsLayer 三级兜底回读源码
  • ⚠️ 0.64.0 架构正交化 BC(#206)— ModuleOptions 删 theme 布尔糖 + sitemap 并入 seo 套件;YAGNI 收缩公开 API;safeExternalUrl / safeInternalPath 守卫上收 framework
  • 🚀 dev mock 双端化(#208,0.65.0)— registerApiMock 放宽为 dev 期 SSR + CSR 双端拦截,universal plugin 成推荐范式,prod 双端删净不变
  • 🚀 组件基线样式口径固化(#210,0.66.0)— 「基线样式非零样式」(丑但能用合格、看起来坏了不合格)入样式规范;SwRail gap 退化默认修正、SwFormField 补状态反馈基线
  • 🐛 修复批(0.66.x) — nuxt-schema-org 钉 6.1.3(修 client 不 hydrate 崩溃);贴片期 autoplay 声画错乱(#211:贴片展示期压制 autoplay,skip() 统一起播出口)
  • 🔄 CSS 变量两层命名模型 + token 表面扩面(#219 / #213,0.68.0)— 语义层 Shadcn 裸名豁免、组件级一律 --sw-<组件>-<prop> 全名(--modal-*→--sw-modal-* 等迁移,0.x 直改不留 shim);token 新增 --foreground-soft / --gradient-brand,深色站 --shadow-* 覆盖与 currentColor 图标着色口径固化
  • 🔧 WebSDK v1.1.6 vendored 升级(#225,0.70.0)+ seo-tdk-length lint(TDK 治理:title/description 字面量显示宽度静态预检,warn 级)
  • 🚀 SwTable 数据表格(#227 → #234 管理台强化 → #235 类型导出,0.71–0.73)— 管理台首选组件:columns 配置 + #cell-<key> 插槽、受控列排序(v-model:sort 三态)、行选批量(v-model:selected 含 indeterminate)、loading 保结构遮罩、斑马纹 / 紧凑密度 / 粘性表头;SwTableColumn 等公开类型 barrel 导出;自防全局 table 样式入侵
  • 🚀 SwSelect searchable / creatable(#226,0.71.0)— Combobox 分支:输入过滤 + chips 多选 + 「创建 "xxx"」输入即建(multiple + searchable + creatable 即 tag-input 形态);连带 SwVideoFeed 播放速率 / 线路切换 API(#229)
  • 🚀 tracker 自建通道 + 首屏 pageView(#228 / #236,0.71–0.73.3)— 无 WebSDK 站点用自建 endpoint 批量上报(batch + sendBeacon 兜底);SSR 场景首屏 pageView 补报(0.73.3 修补报 watch 的 TDZ 崩溃 hotfix,⚠️ 0.73.2 勿停留)
  • 🚀 sw-hit-area 触摸热区 opt-out(#230,0.72.0)— 紧凑控件免除 44px 拉伸 + 伪元素热区扩到 44×44(「视觉小 + 外包热区」惯例内置);🐛 SwVideoFeed 手势中断吸附回弹(#231)、SwModal 关闭钮 ✕ → 内联 SVG(#232)
  • 🚀 userStore.register 自助注册(#233,0.74.0)— 与 loginByUsername 对称复用 setInfo 链,成功即进登录态(bayverse 用户系统驱动)
  • 🐛 修复批(0.74.x) — sitemap XSL 标题 undefined(#237:site.name 从 app.head.title 兜底);SwCarousel 手动导航重置 autoplay 计时相位 + 键盘焦点暂停(#238:刚选的片不再被临近 tick 换走)
  • 🚀 SwVideoFeed 下拉刷新(#241,0.75.0)— pullToRefresh opt-in:首条顶部下拉超阈值触发 @refresh,受控 refreshing 收尾 + #refresh-indicator slot 自渲染品牌指示器(悬浮不位移内容,仅 touch);snapbay「起浪…」signature 的底座
  • 🐛 useSeo lint 补齐 error.vue 覆盖(#240,0.74.2)— require-useSeo-in-pages 此前只匹配 app/pages/**,与文档声明不符;补 isErrorPageFile 后全局错误页缺 useSeo 同样报 warn(错误页 noindex 是硬要求)
  • 🚀 generate-api 双源:OpenAPI 3 接入(#242,0.76.0)— source adapter 架构,自研 server 的「API 文档 → 请求代码」自动链与 YAPI 源并行
  • 🚀 ISR 私有数据护栏 L2–L4(#243 / #245,0.77.0–0.78.0)— generate-api 按 visibility 分文件 + manifest + private 元数据注入;eslint isr-no-private-api 机检 ISR/prerender 页调 private API(判据收敛 SSR 执行路径消事件处理器误报);request dev 期 SSR 调 private 警戒;generate-api --check 漂移检查
  • 🚀 表单控件族统一高度/字号 + SwInput(#244,0.78.0)— 语义 token --control-height(32px) / --control-font-size(14px),SwInput / SwSelect / SwSegmented 同行混排默认等高等字号(⚠️ SwSelect 36→32px·字号 16→14、SwSegmented 42→32px 有意视觉 BC);新组件 SwInput(表单基线盒子 + 触摸设备防 iOS 聚焦缩放),starter LoginForm 迁移作参考实现
  • 🚀 SwVideoFeed 预载可控(#246 / #248,0.79–0.80.0)— preload?: boolean | number:默认预载后 2 条视频各前 5s(⚠️ 原窗口 ±1 条各 30s 全量预载,CDN 流量大降);广告条跳过不占名额、尾部截断、挂载窗前伸;false 完全关闭
  • 🐛 滚轮惯性尾巴过冲修复(#247,0.80.0)— Windows 精密触控板一次滑动窜多条:锁定解锁改 240ms 静默窗 + 力度回升绝对下限;deltaY 补 deltaMode 归一化(Firefox 鼠标滚轮一格即翻条)
  • 🚀 埋点扩容三连(#249 / #250 / #251,0.81.0)— track 事件名放宽为「预置枚举 + 任意自定义字符串」并按通道分流(自定义名仅自建 endpoint 入库,WebSDK 通道枚举外名 dev 警告后忽略);视频播放心跳 + 累计观看时长 watch_time;广告关闭埋点 useAdTrack.reportClose(含 close_reason)
  • 🚀 useHoverPreview 机制层收编(#253,0.83.0)— 卡片 hover 放大预览的意图状态机(300ms 弹出 / 140ms 关闭 / 顺移保持 / 滚动即关)+ computePreviewBox 定位纯函数;浮层视觉仍归业务自绘,starter 删本地副本改引 framework
  • 🔄 token 与几何三件套 — 媒体遮罩语义 token --scrim / --scrim-top(#254,0.84.0,一行消费免 no-hardcode disable);SwRail 箭头垂直锚点 --sw-rail-arrow-top(#252,0.82.0);SwModal 视口安全 width / max-height + class 透传落 content(0.85.0,per-dialog 定制的官方通道)
  • ⚠️ SwSegmented 默认视觉对齐业界灰槽形态(0.86.0,视觉 BC)— 连带修「选中项 hover 被通用 hover 规则压成低对比黑字」
  • 🚀 内置文案多语言化(#261,0.88.0)— 新增 sw-i18n 内置文案字典 + useSwText,19 个组件的内置文案 / aria-label 全量接入(此前硬编码中文,非中文站露馅)
  • 🚀 @swift-web/framework/store 子路径导出(0.90.0)— 让「同名覆盖」的扩展模板真正成立:业务 store 与 framework store 同名时,唯有显式 import 才拿得到 base,否则指向自己形成无限递归
  • 🐛 ISR 在自托管 node-server 上完全不缓存(#267,0.92.0,本月最重要的修复)— nitro core 只规范化 swr、不消费 isr(仅 vercel / netlify / zeabur 三个平台 preset 认它),自托管上写了 isr 等于零缓存、每请求全量 SSR。改为构建期把 isr 翻译成等价 cache 键并存(平台走 CDN、自托管走服务端缓存,两边都对);同时把缓存挂上有界 LRU(1000 条 / 50MB / 单条 2MB),把「随机 query 撑爆进程内存」从 OOM 降级为命中率下降。业务侧写法不变,仍只写 isr
  • 🚀 渲染策略构建期护栏四连(0.89–0.95)— 这类失效的共同点是 lint / typecheck / build 全绿、页面看着也正常,只有 curl 产物才看得出,故一律做成构建期硬校验并给可粘贴的修法片段:#262(通配规则把渲染语义补进父路径,0.89.0;0.89.1 修三处判据缺陷、0.89.2 排除 Nuxt 内部路由)/ #274(fs 缓存驱动 × 父子路径同时可缓存 ⇒ ENOTDIR,0.93.0)/ #276(路径含 ≥2 动态段时页面级 defineRouteRules 被 Nuxt 整条丢弃,0.94.0)/ #279(可选段页面的零段父路径拿不到缓存包裹,0.95.0)
  • 🚀 可缓存页禁读 query(#271 配套)— 新增 eslint no-query-in-cacheable-ssr(error)+ no-ineffective-route-rules;护栏 L5 拦「可缓存页 SSR 携带用户态」;dev 期大响应告警在根因处报出「哪个接口多大 / 多少条」。配合反代层 path-only cache key,缓存爆炸由「止血」转为根治
  • 🐛 被缓存的页面 canonical 退化成 localhost(#278,0.95.0)— cachedEventHandler 进 handler 前只保留 cache.varies 白名单里的请求头,Host 被丢掉 ⇒ useRequestURL().origin 落到 http://localhost,canonical / og:url 全错,且只有「被缓存过的」页面才错
  • ⚠️ 移除全局触摸最小高度,改 sw-hit-area opt-in(#265,0.93.0,视觉 BC)— 原先给所有 a / button 加 min-height: 44px,落地一年积累 38 处绕行。调研 13 个主流库的发布态 CSS:这种 blanket 规则零例;规范约束的是热区而非视觉盒、合规线是 AA 的 24px 而非 AAA 的 44px、inline 文本链接明文豁免——三层全反了。改为伪元素扩热区,视觉不变
  • 🔧 其它 — WebSDK vendored 升 v1.1.7(#280,新增四类硬件信息事件自动采集;facade 12 个方法 + 28 个事件契约不变);播放器 autoplay 默认关闭 + 尊重 prop + 静音降级,连带补「在播但封面还盖着」的兜底自愈(#281);useLocal / useSession 泛型不再塌成 unknown

starter

  • 🐛 中转页 DOM XSS 加固 — ?url= 跳转补 http / https scheme 白名单(连带沉淀 standards 通用规则)
  • 🚀 theme.mode 适配 + SwLangSwitch 接入 + Cursor 开箱配置 — swift.config 单旋钮 + 顶栏改 framework 内置切换器;.cursor/mcp.json 入库
  • 🚀 电影三件套 demo 全量落地(#48–#51,0.26–0.28)— /movie 楼层 / 列表 / 详情参考实现:版式三旋钮 + 全版式插位广告 + 卡片信息层 v2 + 选集面板 + 弹幕全链路 + 前贴片广告示范(play_ads → SwAdPreroll 归一)
  • 🚀 通用站点页脚模板(#52,0.29.x)— 数据驱动 AppFooter(品牌区 / 链接组 / 圆形图标链接 / 友链可选模块,5 常量改数据不动布局)+ (footer) 分组路由 6 个静态页(about / contact / ads / terms / privacy / faq,prerender)+ 顶部导航字体层级与激活态优化 + 闪电新 logo 统一
  • 🔄 审计修复批(0.26.1)— 登录方式切换迁 SwSegmented + 站内回跳守卫收敛 framework safeInternalPath
  • 🚀 合规占位页补齐(0.30.0)— (footer) 新增 18 U.S.C. § 2257 合规声明与滥用报告(DMCA)两个结构占位页(noindex + prerender),页脚「政策」组注释链接解开即用,面向成人内容站合规标配
  • 🚀 卡片 hover 放大预览(Refs fw#253,0.30.3)— 热播推荐楼层切 16/9 横版 + MovieHoverPreview 浮层 + MovieCard / MovieFloor 的 preview prop(默认开);机制层随后上收 framework,starter 删本地副本改引 useHoverPreview / computePreviewBox
  • 🔄 审计修复批(0.31.0)— deploy 不再冲掉服务器上手填的 .env;占位符域名归位;noindex 页排除出 sitemap;TabBar 死链默认值;error-report 端点挪出 /api/(避开 applier 的代理遮蔽);评论发布框头像改 onMounted 回填以消 ISR 页 hydration mismatch
  • 🐛 扩展 store 模板修法(0.32.0,配套 fw 0.90.0)— 改用显式 import 从 @swift-web/framework/store 拿 base,修「同名覆盖时 base 指向自己」
  • 🔄 排序参数 query → path 段(#271 范式落地)— movie/list/[id]/[[order]].vue + 边界校验;连带补 nuxt.config routeRules 兜底(该页 defineRouteRules 被 Nuxt 静默丢弃,即 fw#276 的形状)

cli

  • 🐛 Windows 必现失败修复(#31)— spawnSync 补 shell,修 sw create / run 在 Windows 必现失败
  • 🐛 升级与超时误报修复 — sw upgrade 补 --latest 修 0.x 跨 minor 假成功;npm pack 超时误报修正 + 上限 300s(#36)
  • 🚀 sw_project_apis MCP 工具(#40)— 解析 applier app/api 生成物,AI 直接查后端接口清单
  • 🔄 配置联动 BC 批(0.15.2 – 0.16.1)— framework.sitemap 迁 framework.seo.sitemap;sw add page 模板 TDK 引导升级(中文口径注释 + TODO 占位,0.16.0);schema 移除 tracker.autoPageClick(随 fw#228,0.16.1)
  • 🐛 修复批(0.15.x)— sw info 缺字段崩溃 / config set 校验残口 / 损坏 swift.config.json 走 CONFIG_PARSE_FAILED 错误码
  • 🐛 输入白名单加固(#45,0.16.2)— sw add / sw config 拦原型链键 / 非法标识符 / 路径穿越 / 原型污染。⚠️ 首版正则误伤了 Nuxt 动态路由段 [id] / [...slug](自造回归,0.16.3 放行)
  • 🔄 --text 模式兑现「纯文本」承诺(0.16.2)— 统一剥 ANSI 转义;连带修 KNOWN_DESCRIPTIONS 跨仓漂移 + sw info 的 framework 版本读取口径对齐 version-check

standards

  • 🚀 v0.4.x 规则增补 — 「用户可控跳转必过 scheme 白名单」/ SOP「issue 已存在→认领」/ no-hardcode 引入期姿势 / --brand-* 业务 token 命名空间 / mocking 双端化
  • 🚀 v0.4.3 TDK 治理 — 新增 eslint 规则 seo-tdk-length(warn 级字面量预检)+ 「TDK 长度写时就写足」规则节(显示宽度口径)
  • 🔄 组件规则同步批 — SwTable / SwSelect searchable·creatable(SEL-003)/ sw-hit-area 紧凑控件 opt-out(含 chips/tab 正当场景界定)/ userStore 写状态清单补 register / 深色站 shadow 覆盖与 currentColor 图标着色 / SwInput 与 --control-* 表单控件族入组件优先表 / SVF-006 下拉刷新受控收尾
  • 🔄 渲染策略规则大改(v0.4.4 及以后)— 新增「可缓存页 SSR 禁读 query」硬规则 + path 化的四个结构性前置条件 + 「触摸目标约束热区不约束视觉尺寸」整节改写(含 13 库调研结论);订正零段父路径的根因表述——nitro 里 routeRules 匹配器与 h3 handler 路由器对 /P 是否命中 /P/** 行为相反,原文只写了一半

docs

  • 🚀 demo props 覆盖率闭环(#84)— 覆盖率规则落地 + 四批缺口回填收官,终值 278/278 = 100%
  • 🚀 「设计体系」栏目上线(#85 – #88)— 三语 7 篇(设计语言 / Figma 工作流 / Claude Design 上手 / 协作 / 治理),Figma 与 Claude Design 双轨等重;「认识 Open Design」接入本地 agent 设计系统 bundle;设计卡片总览页 20 张实卡 iframe 预览 + 双资源包下载
  • 🚀 部署文档补视频转码契约 — HEVC 必配 H.264 双 codec 变体(mermaid 选档流程图 + 单 URL 前端契约 + 双独立 URL 反模式 + AV1 演进预告)
  • 🐛 修复 39 条失效的同页锚点(#90,占全站 113 条的 34%)— 根因是 heading id 由 @nuxtjs/mdc 生成,规则反直觉(吞 .、连续 - 折叠成一个、数字开头补 _);连带新增 docs-anchors.spec.ts 全量校验并对复刻算法本身锁了 8 条实测值
  • 🐛 修 6 组文档事实错 + 新增表格结构护栏(审计 07-28)
  • 🚀 新增「自托管下 isr 如何真正生效」(三语)— 配套 fw#267,并修正原文对缓存位置的描述

跨仓事件

  • 🔧 连续审计周期(07-02/03/04 三连 + 07-07/08 两连 + 07-13 深审)— swift-web-audit 多轮批量修复,07-13 批叠加 TDK 治理四路联动(framework lint + cli 模板 + standards 规则 + docs),发版链贯穿 framework 0.62–0.69 / cli 0.13–0.16 / starter 0.24–0.26 / standards 0.4.1–0.4.3
  • 🔧 设计体系双轨管线(07-09 – 07-17)— framework scripts/design 流水线(ds-build 源码派生 20 卡 + brand-inject 品牌注入 + od-build Open Design bundle)→ Claude Design 底版 / yc001 品牌双项目 + docs 站资源包与实卡预览,全链单一事实源 = framework 源码
  • 🔧 ISR 缓存正确性战役(07-29 – 07-31,framework 0.89 → 0.95 + starter + standards + docs + 8 个下游站)— 由「反代层要不要做 HTML 缓存」一路挖出五个全绿却静默失效的渲染策略坑,逐个补构建期护栏、改规则主源与三语文档、并把 8 个消费方全部升上来。教训沉淀成一条判据:「站不慢」不能作为「缓存规则生效了」的证据——反代层的固定 TTL 会掩盖应用层的漏配,判据只能是产物 curl 出来的响应头
  • 🔧 设计体系派生改源码直读(fw#257)— ds-build 的组件卡 CSS 从各 .vue 的 <style> 块直读,消除手抄快照漂移

2026-06

framework v0.16.1 → v0.58.1(42 个 minor + 20 个 patch)· cli v0.5.6 → v0.10.0 · standards v0.2.0 → v0.3.2 · starter v0.14.4 → v0.21.0

组件大爆发月:广告组件家族(12 个 SwAd*)+ WebSDK 埋点底座、轮播 / 横排 / 视频流 / 网格组件族(彻底去 swiper)、播放器广告与付费墙、SwEditor 富文本,叠加 module setup 分层重构、配置体系整改、pnpm 11+ 全生态闸门、obfuscate CSR 裸样式根治等跨仓事件。

framework

  • 🚀 广告组件家族 + 统一埋点底座(epic #94)
    • 全月落地 12 个自渲染广告组件:图片类 SwAdBanner / SwAdMrec / SwAdIcon、文字卡片类 SwAdText / SwAdMarquee / SwAdNative、弹窗 / 悬浮类 SwAdSplash / SwAdPopup / SwAdFloating、播放器位 SwAdPreroll(前贴片,play_ads 协议归一)/ SwAdPause(暂停广告)、合规角标 SwAdLabel,内置曝光 + 点击埋点;图片广告可选文案 + CTA overlay
    • 集团 WebSDK 上报底座:useTracker(28 个 WebSdkEvent)/ useAdTrack(广告字段自动组装)/ useAdFrequency(频控走加密缓存)+ tracker.client 插件(懒加载 / 自动 pageView / 配置缺失静默降级)
    • :track 组件内置埋点(SwLink / SwButton / SwCarousel / 播放器,#123)+ 通用曝光 useExposure
  • 🚀 轮播 / 横排 / 视频流 / 网格组件族(#106)— SwRail(原生横滚 + scroll-snap)/ SwCarousel(transform 翻页 + 无缝 loop + autoplay + dots / 缩略图指示器)/ SwVideoFeed(抖音式竖划短视频流,裸 hls 视频池 + 虚拟化)/ SwGallery(响应式网格 + 加载更多)/ SwPagination(页码翻页,starter 向上归并)
  • 🚀 播放器广告 + 付费墙 + 弹幕 — SwVideoFeed 信息流广告条 + 入口贴片(强制观看 prerollAdForceWatch,#179);SwVideoPlayer / SwVideoFeed 试看墙 paywall(#174)+ 重看试看片段 replayPreview(#186);SwVideoPlayer 内置弹幕 danmaku(条件懒加载 + 主色 token)
  • 🚀 SwEditor 富文本(#187)— 保留 Tiptap 内核重写封装:v-model / @提及 #话题 / 内置 emoji 面板 / 图视频上传(emit-to-business)/ 配菜式工具栏 / token 化默认皮肤
  • 🚀 新组件与皮肤上移 — SwSegmented / SwSelect(平铺单选 / 下拉选择)、SwBreadcrumb(headless 面包屑 + BreadcrumbList JSON-LD);modal / toast 默认皮肤 token 化上移进 framework(#173),applier 删副本即得
  • 🚀 registerApiMock dev 期请求 mock 层(#188)— 明文层声明式拦截(dev-only + client-only + prod DCE 删净)+ 内置 login / system-info 预设;build 产出 framework-api.json(四层 API JSDoc 数据源,cli MCP 消费)
  • 🔄 module.ts setup 分层重构(#99)— 抽 setup/ 七层(types / defaults / resolve-options / diagnostics / register-config / register-runtime / configure-build),module.ts 收敛为薄编排 + 装配快照护栏测试
  • ⚠️ BC 集 — userStore login() → autoLogin() + 新增公开 loginByDevice();useLoginDialog 的 show → open;SwAdSide → SwAdFloating 改名;广告弹窗按场景拆分 SwAdSplash / SwAdPopup;player API 命名对齐 HTML / 业界惯例
  • 🐛 obfuscate 破坏 CSR CSS preload 根治(#169)— 生产混淆吞 Vite css preload url 致 SPA 导航整页裸样式,0.39.4 关 stringArray + 默认关 inlineStyles(框架级修复,升级即得)
  • 🐛 SSR / 安全修复批 — deviceId 改 secure-context 安全的 randomUuid()(修非 HTTPS / LAN HTTP 500);useSeo prerender 页 origin 回退 NUXT_PUBLIC_SITE_URL(#117,修 OG / canonical 烤成 localhost);cacheAesKey 长度 / auth cookie 名构建期 fail-fast

starter

  • 🔄 广告体系换血 — 彻底去 swiper,自建广告组件全删改用 framework SwAd* 组件族;开屏广告迁 SwAdSplash(system/info.layers 驱动)
  • 🚀 登录与能力上移收编 — yc001 登录组件 UI / 结构回灌(LoginForm + login.vue);modal / toast 皮肤副本删除走 framework 内置;PaginationBar 退役归并 SwPagination
  • 🐛 sitemap 收敛 framework 内置 — 删自建 sitemap 管线(根除自写文件服务路由的路径穿越隐患),统一走 framework 的 @nuxtjs/sitemap
  • 🔧 CI / 部署 / mock 工程化 — verify 门禁 job(type-check + lint)+ CI 改 pnpm;deploy/ 运维三件套 + pnpm deploy:prod(独立目录 build、rsync 不带 --delete,根治首屏裸样式窗口);内置业务 dev mock 预设(movie / search 整套)

standards

  • 🔄 rules 单一事实源重构 — 拆单文件为 rules/ 多主源 + 双装配清单(_claude / _mr),下游 CLAUDE.md 瘦身职责分离
  • 🚀 stylelint no-hardcode 强制(#17)— color 类属性禁 hex 字面量(error 级)+ Tailwind at-rule / 函数白名单
  • 🚀 统一开发流程 SOP + applier CI/CD + 部署规范 — issue-dev-sop 主源落地(issue 即方案 / 按 task 原子提交 / 自测留证),治理类 wiki 全弃;applier MR 门禁工作流 + 长期分支同步纪律 + 测试 / 生产部署规则
  • 🚀 usage-review-rules 大扩充 + 交互体验规范 — 收编 utils / store / composable 层 20+ 条编号规则(CACHE / REQ / AES / DB / STORE 等);新增前端缓存加密 util / 广告位与打点 / dev mock 护栏 / 文档中等信息密度等规则;交互与体验规范 UX-001~010(#25)

cli

  • 🚀 theme applier + MCP 富文档 — theme feature applier(#20,theme.enabled 自动 toggle 暗色 marker 块);sw_framework_docs 读 framework-api.json(四层 API + gotcha 关联 + 框架配置层)
  • 🚀 create / config 能力补全 — sw create 询问启用 dev mock(选否删预设);sw config + MCP 全量覆盖 swiftConfig + auth 危险项二次确认;applier 创建补 pnpm 11 守卫 + 生成 .npmrc

docs

  • 🚀 组件族三语文档批量新增 — 轮播族(SwRail / SwCarousel / SwVideoFeed)三语 + DemoBox;「广告底座与打点」指南三语
  • 🚀 llms.txt / llms-full.txt 构建期生成(AI 友好文档入口)

跨仓事件

  • 🔧 pnpm 11+ 全生态统一闸门 — 各仓 engines.pnpm ">=11" 下限、去 corepack / packageManager 钉死、pnpm 字段迁 pnpm-workspace.yaml、CI 改装 pnpm@11
  • 🔧 release 链路安全化 — 4 发版仓统一 npm version(pnpm version 忽略 tag prefix 的坑)+ release 闸门加 typecheck 硬门 + release script 安全加载 .env(杜绝 secrets 打到 stdout)+ 删各仓 .env 收敛 ~/.zshrc 单一凭证源
  • 🔧 配置体系整改(framework#164)— 项目常量进 nuxt.config、.env 只留环境相关、运行时零必填 env(根除 cluster 非主实例配置为空的雷),framework / starter / standards 联动落地
  • 🔧 测试大补齐 — framework e2e 夹具场景数门槛入规 + 全组件夹具扩充(#143–156 群,e2e 240 全绿);starter 页面 smoke 消覆盖率 0/0 盲区;cli 参数组合 + 边界测试

2026-05

framework v0.7.0 → v0.16.0(9 个 minor + 数十 patch) · cli v0.2.7 → v0.5.1 · standards 首发 v0.0.1 → v0.1.3 · starter 首发 v0.14.0

5 仓体系(framework + starter + standards + cli + docs)成型并加速迭代的关键月,覆盖 ISR 安全增强、Cookie 加密、SEO 链路收归、SwButton 回归 vue idiom、verdaccio 私服上线、starter / standards 首次发 npm 包等多个跨仓事件。

framework

  • ⚠️ useSeo 单一入口 + 修 <title> 重复(v0.16.0 BC,refs framework#89)
    • 删 system.client 链:旧版 hydration 后用后端 header 调 useSeoMeta 覆盖页面 title/description,导致 <title> 重复成 站点名 | 站点名 + description 被后端值盖掉
    • SEO 全显式单一入口:useSeo 不再从后端 systemStore.header 兜底 title/description/keywords/og_image(缺失改 dev console.warn,不静默兜底)
    • titleTemplate 交还 Nuxt 原生:移除 ModuleOptions.head.titleTemplate + useSeo 的 disableTitleTemplate 入参;applier 改在 nuxt.config.ts 的 app.head.titleTemplate 配站点名后缀(源自 swift.config.json 的 project.title)
    • JSON-LD WebSite.name 取 runtimeConfig.public.siteName,不再读后端 site_title;og:image 兜底仅本地 /og-image.png
    • 升级 applier 须:每页显式传 title/description + nuxt.config.ts 配 app.head.titleTemplate + runtimeConfig.public.siteName
  • 🚀 sitemap.xml 精细化 + i18n strategy 检测(refs framework#85,配套 #87)
    • GAP1:sitemap siteUrl 由 NUXT_PUBLIC_SITE_URL 锁定,跟 useSeo runtime origin 解耦(sitemap 是搜索引擎目录,必须稳定主域名;canonical 跟用户访问域名一致)
    • NUXT_PUBLIC_SITE_URL host 格式校验:合法 URL + http/https 协议 + 纯 origin(不带 path/query/hash)。dev console.warn / build console.error,不阻断 build。能拦下漏协议(example.com)/ 占位符(<your-domain>)/ 错协议(ftp://)/ 带 path(https://x.com/api)等脏数据
    • GAP2 简化版:检测 @nuxtjs/i18n strategy === 'no_prefix' → dev console.warn 引导改 prefix* strategy(hreflang 互链自动配置由 framework#88 跟踪)
    • GAP3 默认 exclude 私有路径:sitemap 默认排除 /login、/register、/mine/**、/profile/**、/admin/**、/dashboard/** 等通用私有路径,避免跟 useSeo({ robots: 'private' }) 自相矛盾
    • 新增 ModuleOptions.sitemap.exclude?: string[] 让 applier 追加业务自定义私有路径(与 framework 默认合并,不是替换)
    • 新增 docs:sitemap 配置 / NUXT_PUBLIC_SITE_URL 配置 / ModuleOptions.sitemap
  • ♻️ useSeo origin 兜底链简化为单一事实源 + CSR 一致性诊断(refs framework#87)
    • 4 层兜底(L1 explicit → L2 systemStore.info.site_url → L3 runtimeConfig.public.siteUrl → L4 useRequestURL().origin)→ 1 个事实源 + 1 个显式逃生口
    • 主路径:useRequestURL().origin(SSR Node 端从 Host/X-Forwarded-* 解析 / CSR window.location.origin)
    • L1 explicit input.siteUrl 保留为「显式逃生口」(多副域名想强制 canonical 收敛到主域名时用)
    • CSR hydration 阶段一次性比对 <link rel="canonical"> 与 window.location.origin,不一致 = nginx 透传配错 → dev console.warn / prod console.error + 修复指引 + docs URL(nginx origin 透传配置)
    • SystemInfo.site_url 字段保留供业务读取(如「最新地址」跳转链接),不再参与 SEO origin 决策
    • NUXT_PUBLIC_SITE_URL 仅 build-time 用(prerender / sitemap)
    • 行为变化但 API 签名不变 —— 旧依赖 L2/L3 兜底的项目需确认 nginx 透传 Host / X-Forwarded-Host / X-Forwarded-Proto,否则 canonical 会拿到内网地址(诊断 console 会立刻报警)
  • 🔧 publishConfig 切 verdaccio(v0.14.0 / v0.14.1,refs framework#77 / #78 / #79)
    • framework 切自托管 verdaccio 私服(npm.djatm.cloud),下游 applier 装包不再经 GitLab npm registry
    • prepublishOnly 钩子在发版时从 publish manifest 剥离 scripts.preinstall,避免消费方 install 时误触发 pnpm 检查脚本
    • workspace 配置 @swift-web/standards: false 防 consumer 跑 standards 的 preinstall
  • ⚠️ defineRouteRules 硬校验 + 删默认 error.vue(v0.13.0 双 BC,refs framework#71)
    • applier 须显式开启 experimental.inlineRouteRules,未开启时 framework 模块 setup 阶段直接报错
    • 此前是 silent no-op:applier 写了 defineRouteRules 但实际无效,ISR / SSR 行为切换会暴露既有问题
    • 删 framework 默认 error.vue,errorComponent 完全交 applier 自定义
    • framework 内部 createError 直接抛错,不再 fallback 渲染兜底页
  • 🐛 SSR / 错误处理强化(v0.12.7 ~ v0.13.0 系列)
    • SystemInfo onError 默认改为 fail-fast throw,删 SSR 阶段 deviceId guard 让 onError='throw' 真实生效
    • createError 改用 error.data: { source, title, cause } 结构化携带诊断信息,不再靠 message 字符串拼接
    • SSR 期空 apiBase fail-fast 明确报错,不再 silent 跳过
    • SSR 期 deviceId 用固定值 'node'(后端约定),跟客户端逻辑解耦
    • SSR error.vue 渲染时 client 不再后台拉 systemInfo + title 含完整 API 路径
    • 整体让 SSR 失败立刻可见,不再积累隐性损坏
  • ⚠️ SwButton API 重设计(v0.12.0 BC,refs framework#56 / #57)
    • 自 v0.6.0 起 SwButton 使用 onTap callback prop + 100ms 内置节流 + 主动 filter onClick,反 vue idiom + 反业界惯例(el-button / antd / mui / reka-ui 都不做内置节流,全部 emit @click)
    • 删 onTap callback prop,改用标准 @click event:<SwButton :on-tap="fn"> → <SwButton @click="fn">
    • 删 wait prop + 100ms 内置节流,async 期间防 double-submit 改由父组件管 :loading 状态机
    • 删 inheritAttrs:false,vue 标准透传,class / style / aria-* 自动透传到原生 <button>
    • 新增 nativeType: 'button'|'submit'|'reset'(form submit 必备)/ autofocus / icon(左侧图标 Vue 组件,loading 时被 spinner 替换)
    • 新增默认 loading spinner::loading="true" 没传 #loading slot 时自动渲染(约 10 行 CSS,1em + currentColor 自适配按钮文字大小颜色)
    • 配合 standards mr-review SB-001(@click 绑 async handler 必须传 :loading)+ SB-002(form submit 必须传 native-type="submit")兜底
  • 🚀 测试基础设施(v0.12.7 ~ v0.12.12 系列)
    • 接入 vitest coverage(v8 provider + json-summary reporter)
    • 重写 SwButton e2e 覆盖 disabled / loading / type / icon 主要 props
    • utils/debug-log.ts 单测覆盖率 0 → 89.47%
    • framework e2e gotoPage helper 绕开 @nuxt/test-utils createPage hydration 时序问题
  • 🔧 release 流程 + 工程基础设施(v0.12.0+)
    • release script 拆三:release:patch / release:minor / release:major,裸 release 报错强制选版本(防 v0.12.0 BC 误发 patch 教训)
    • release script 显式传 --tag-version-prefix=fw/v,绕开 pnpm 不读 .npmrc 的 bug
    • 锁 packageManager pnpm@11.0.8
    • playground devServer 端口 3500 → 3000(monorepo 端口统一)+ host env-aware
  • 🐛 业务组件小修复(v0.12.x patches)
    • SwQrcodeScanner 加 decode timeout 兜底,修非二维码图永挂 loading 真用户 bug
    • upload-chunk 空文件(size <= 0)silent skip + 无任何回调,致消费方 pending 永锁(refs framework#60)
    • SwImage URL.createObjectURL 内存泄漏(refs framework#61,已含在 SwImage 重构)
    • SwTiptapEditor template 内联 type cast as 在下游 applier rollup 解析失败 → 移到 script setup computed
  • ⚠️ framework 接管 head 元素(v0.10.0 / v0.11.0 BC,refs framework#51)
    • <html> htmlAttrs 收归 framework(v0.11.0):lang 单一事实源 framework.i18n.defaultLocale;data-build-id / data-build-time 按 CI_COMMIT_SHORT_SHA → VERCEL_GIT_COMMIT_SHA → GITHUB_SHA → 'local' 优先级读环境变量
    • i18n plugin 自动注入 <html lang>(refs framework#51),替代 starter 在 nuxt.config.app.head.htmlAttrs.lang 写死
    • <title> titleTemplate 收归 framework(v0.10.0):默认 '%s | %site_title',%site_title runtime 替换为后端 system.info.header.site_title
    • useSeo 取消 site_title 当 title 兜底,避免与 titleTemplate 叠加产出 siteTitle | siteTitle 的首页重复 bug
    • useSeo({ disableTitleTemplate: true }) 单页关闭 titleTemplate 注入(适营销落地页 / 错误页 / 全屏专题页)
    • 新增 eslint 规则 swift-web/require-useSeo-in-pages:app/pages/**/*.vue 必须显式调 useSeo,阻断 AI / 开发者漏写
    • applier 的 app.head.htmlAttrs 整块 + 顶部 buildId / buildTime 常量都可删
  • ⚠️ Cookie / 登录态 / 设备认证安全加固(v0.9.0 BC,refs framework#48 / #45)
    • AccountInfo 从 cookie 搬到 localStorage(加密),密码不再随每个 HTTP 请求飞到 header,DevTools Cookies 面板不再可见明文 JSON
    • 🔴 修复「记住我」被绕过的隐私 bug:0.8.x 起 framework 在 loginByUsername / loginByQrcode 内部总是无条件调用 setAccount 写 cookie 30 天,无视消费方"记住我"意图;0.9.0 通过 options.remember 让用户意图真正生效
    • AccountInfo 接口新增必填 remember: boolean 字段;loginByUsername / loginByQrcode 签名 extra?: Record → options?: { remember?, extra? },remember 默认 true 保持兼容
    • 核心 cookie(token / deviceId / channel_code / share_code)全部 AES-CBC 加密 + 默认 secure: true(localhost / 127.0.0.1 浏览器自动豁免)
    • 新增 userStore.clearAccount() action(单独清 AccountInfo 不动 tokenInfo)+ useTheme.setTheme(theme) action
    • useCookie wrapper 扩展支持 maxAge / sameSite / secure / path / domain / default / watch;解密失败自动 fallback 兼容旧明文 cookie
    • 新增 eslint no-direct-cookie-in-app 规则编译期拦截 app/ 下直读写敏感 cookie
  • 🚀 ISR 安全增强 + path-aware lint plugin(v0.8.0 BC,refs framework#44)
    • 针对 ISR 路径上的"设备 token 通过 Pinia payload 烤进缓存"等用户态泄漏隐患做系统性重构
    • device + auth 身份从 SSR 期完全挪到 client hydrate 后建立,新增 auth.client.ts plugin 作为唯一建立点
    • system.server.ts 简化:删 SSR 期 userStore.login() + 内置 IGNORE_PATHS,保留 systemInfo 拉取 + initCode
    • useAuthReady composable 让业务 request() 透明等到 auth.client 完成
    • framework module.ts 自动注入 experimental.inlineRouteRules: true 让 page 级 defineRouteRules 真正生效
    • 新增 @swift-web/framework/eslint subpath export,3 条规则:require-define-route-rules / no-isr-on-paid-paths / no-isr-on-user-state-paths
    • 0.8.1 path-pattern 改 segment 级匹配,覆盖嵌套路由;0.8.2 规则 options 支持自定义 segments;0.8.3 ModuleOptions.auth 扩展 boolean | AuthOptions 支持 auth: false 关掉整套 client auth init
    • BC:systemInfoIgnorePaths: string[] 删除,改 systemInfo: boolean | { enabled?, endpoint?, ignorePaths? };迁移示例 ['/'] → false,['/p'] → { ignorePaths: ['/p'] }
  • 🔄 SwImage / SwAsyncText 重构(v0.7.x ~ v0.8.x BC,refs framework#34 / #35 / #61)
    • 移除 @nuxt/image 依赖,新引入外链图 provider 抽象
    • SwDecodeImage 删除,其加密能力收纳进 SwImage 统一图片入口(清理 .cursor-scale / .cursor-scale-av 业务专属样式)
    • SwDecodeText 改名 SwAsyncText,并切到 useDecryptedAsset composable(依赖 #34)
    • fix URL.createObjectURL 没对应 revokeObjectURL,加密图片列表场景内存泄漏(#61)
    • SwImage 能力补齐:外层 click 事件(覆盖 overlay)、title prop(hover tooltip / SEO)、placeholder 扩展 string | { dark, light } | false、#placeholder slot、@load / @error 透传、hover-zoom class
  • 🚀 PWA SW 配置改业界主流(v0.7.7,refs framework#43)
    • skipWaiting: true(新 SW 立即激活,不等所有 tab 关闭)
    • clientsClaim: true(新 SW 接管所有 client)
    • 图片 runtime caching 改为 StaleWhileRevalidate 策略(先返缓存 + 后台更新)
    • 对齐 Workbox 推荐 + el-ui / antd-pro 等业界 PWA 默认行为
  • 🚀 useSeo 长度阈值改用显示宽度算法(v0.7.5,refs framework#39)
    • 原 validateSeoLengths 用 JS .length(UTF-16 code units)对 ASCII / CJK 一视同仁
    • 但 50-160 字符阈值按 Google SERP 英文字符宽度标准设计,CJK 在 SERP 视觉宽度约英文 2 倍
    • 引入 displayWidth 函数(CJK Unified Ideographs / Extension A-H / 全角符号 / CJK 标点算 2,ASCII 算 1)
    • title / description 走 displayWidth;keywords 检查数量和总长度保持 .length
    • 阈值数字(10/60/70 / 50/160/200)不变,单位含义升级为"显示宽度"
  • 🔄 codegen 抽离到 framework(v0.7.0)
    • 把 starter 的 optimize-images / generate-icons / check-og-image 等构建脚本抽到 @swift-web/framework/codegen 子模块
    • 下游 scripts/*.ts 退化为一行薄封装(import + 调用)
    • 核心逻辑跟随 pnpm update @swift-web/framework 升级,applier 不再需要"复制 starter 脚本到自己项目"的旧维护模式
    • framework 提供纯函数 + 回调接口(如 generateIcons 的 onFaviconConflict callback),终端交互留在调用方
    • starter 五个脚本完成迁移

starter

  • ⚠️ 适配 framework#89 SEO 单一入口(v0.14.2)
    • nuxt.config.ts 改用 Nuxt 原生 app.head.titleTemplate: \%s | ${swiftConfig.project.title}`+runtimeConfig.public.siteName(站点名源自 swift.config.json的project.title`,单一事实源)
    • 同步带 starter#24 修复:.npmignore 排除发包专用 template-integrity.spec.ts,防泄漏到 sw create 派生的 applier
  • 🚀 首发 npm 包(v0.14.0)
    • starter 此前是 git-only template(cli 用 SSH git clone 拉模板),不发 npm
    • v0.14.0 起作 npm 包发版,给 cli 用 npm pack 取(配合 cli 0.5.0)
    • prepack / postpack 钩子处理 publish manifest:reset version 0.0.0、设 private:true、去 publishConfig / release scripts
    • 保证发出来的包是"新项目"模板状态而非业务实例
  • 🔧 publishConfig 切 verdaccio + 升下游依赖
    • 升 framework ^0.14.0 + standards ^0.1.1
    • .npmrc 切 verdaccio
    • 锁定 Vue 全家桶单版本修复生产构建 SSR 500
    • patch vue-router 5.0.7 修复 @nuxt/test-utils 下的 TypeError
  • 🔧 加 pnpm 11+ preinstall 阻塞
    • check-pnpm.mjs 在 preinstall 阶段校验 process.env.npm_config_user_agent
    • 未达 pnpm 11 / 用 npm / 用 yarn 立即 exit 1 + 中文引导
  • 🔧 systemInfo onError 改 throw + nuxt-config 适配 fw 0.13
    • 跟 framework fail-fast 策略对齐
    • 开启 experimental.inlineRouteRules 配合 fw v0.13.0 硬校验
    • 升 framework 0.13.0
  • 🚀 error.vue dev 详情结构化(配合 fw v0.12.9-0.12.11)
    • dev 模式 error.vue 展示 error.message 详情
    • 改用 error.data 结构化展示替代 message 字符串拆分
    • 详情标题改红色(不再用前置圆点)
  • 🚀 LoginForm 复用 framework 账号存储(配合 fw v0.9.0)
    • 删 self-maintained useLocal('login-username' / 'login-password' / 'login-remember') 三项
    • 改用 framework userStore.setAccount / getAccountInfo / clearAccount
    • 通过 loginByUsername(u, p, { remember: isRemember.value }) 把"记住我"勾选意图正确透传给 framework
  • 🚀 home 首页重写 + 视觉组件(v0.7-0.8 期)
    • 重写首页 + icons 演示页
    • 新增 LogoMark / LangSwitch / ThemeSwitch 业务组件
    • 闪电 LOGO 重生成图标

standards

  • 🚀 首次上线发版 v0.0.1 → v0.1.3(最新一波)
    • v0.1.1:切 verdaccio publishConfig
    • v0.1.2:preinstall 加 cwd-in-node_modules guard(防 consumer install 误触发)
    • v0.1.3:prepublishOnly strip preinstall
  • 🔄 目录重构 common-standards/ → rules/(marker 协议 v1 → v2 BC)
    • 文件命名去前缀编号:10-rendering-strategies.md → rendering-strategies.md
    • _order.json sections 结构控制拼接顺序(替代靠文件名编号)
    • marker v2 加版本号防回退(v1 BEGIN/END 包夹 → v2 加 <!-- swift-web/standards@version -->)
    • 同步下游 4 仓的字面量引用 common-standards/ → rules/
  • 🚀 component-review-rules 体系(陆续完善)
    • 按组件名纵向组织 mr-review 规则的新章节
    • 首版 SwButton 两条:SB-001(@click 绑 async handler 必须传 :loading 状态机,防 double-submit)+ SB-002(form 内提交按钮必须传 native-type="submit")
    • 后续陆续扩展到 18 条,覆盖 SwImage / SwModal / SwUploadImage / SwTiptapEditor 等组件的常见 review 失误
    • 后续逐条机械化为 eslint 规则进 @swift-web/standards/eslint
  • 🚀 eslint 规则集演进(v1 → v4 跨期)
    • v4(fw v0.12.x):SwButton SB-001/002 机械化兜底
    • v3(fw v0.10.0):require-useSeo-in-pages
    • v2(fw v0.9.0):no-direct-cookie-in-app
    • v1(fw v0.8.0):require-define-route-rules / no-isr-on-paid-paths / no-isr-on-user-state-paths
    • 三档分级:必改(block PR) / 重要(讨论) / 次要(review 总结)
  • 🚀 客户端安全主源章节(配合 fw v0.9.0)
    • 5 条 review 规则:cookie secure、敏感字段禁 cookie、remember 透传、不绕开 wrapper、加密非安全屏障
    • 客户端加密安全模型文档化:明确"加密 ≠ 安全屏障"(cacheAesKey / apiKey 在 client bundle 暴露),真正安全依赖 HTTPS + 后端鉴权
    • 三语 /guide/client-encryption-boundary 同步上线
  • 🚀 ISR 安全 mr-review checklist + discuss-rendering v3(配合 fw v0.8.0)
    • 渲染策略 §三 用户态泄漏(最严重风险)专章
    • SWR 降级为 ISR 别名(简化判断复杂度)
    • 决策树补 prerender (SSG) 行
    • rendering-quick-guide 实践型指南
  • 🚀 standards 仓上线 + npm 包发版(refs standards#1 / #3 / #4)
    • 抽出 swift-web 通用规范作单一事实源 —— 渲染策略 / SSR 安全 / 公私 API 边界 / AI 提交标记 / 客户端安全等规则不再分散在 framework / starter / docs 的 CLAUDE.md
    • 统一在 standards/rules/*.md 维护,_order.json 显式控制拼接顺序
    • pnpm sync 脚本通过 marker 协议把规则段注入下游 4 仓的 CLAUDE.md
    • 作为 npm 包 @swift-web/standards 发版,对外暴露 /eslint 子路径
    • 含 navigate-to-must-return(Nuxt navigateTo 不能裸调)/ root-class-sw-prefix(无 class 自动放过 + 多根独立判定)等机械化规则
    • /prettier + /stylelint 子路径让各仓配置走 import base + spread override 模式

cli

  • 🔧 适配 framework#89(v0.5.5)
    • applyProjectVars 移除 titleTemplate 占位符替换(starter 改用读 swift.config.json 的模板字面量,sw create 派生项目天然拿到自己的站点名,无需字符串替换)
    • add.test.ts store 演示输入改 shopping-cart,避开旧 user store 命名触发 pre-release-doc-check 跨仓字符串误报
  • 🚀 sw create 改 npm pack 模式(v0.5.0,refs framework#79)
    • 此前 sw create 通过 SSH git clone @swift-web/starter 仓拉模板,要求新机器配 GitLab SSH key + 有对应 repo 权限
    • v0.5.0 起改用 npm pack @swift-web/starter 从 verdaccio 拉 tgz 解压(配合 starter 首次发 npm 包,见 starter 节)
    • 新机器零 GitLab 依赖:模板每次拉 latest,不再担心版本滞后
    • applyProjectVars 替换 package.json / nuxt.config.ts / README.md 三处占位符的逻辑不变
  • 🔧 publishConfig 切 verdaccio + install 脚本删 AUTH 段(v0.4.0 / v0.5.0)
    • cli 自身发版切到 verdaccio
    • install.sh / install.ps1 删除 NPM_TOKEN AUTH 段(verdaccio access:$all 后匿名安装 OK)
  • 🐛 sw info 补 errorHandler 行 + sw run 失败补 exit(1)(v0.3.x)
    • sw info 输出补全 errorHandler 配置项展示
    • sw run 子进程失败时正确传递 exit code
  • 🐛 sw add page 默认渲染策略改 ISR(v0.3.x)
    • 默认 ssr: true → isr: 3600,对齐 swift-web "ISR 是主力"的设计初衷
    • 性能优先,必要时再走完整 SSR
  • 🔧 release script 拆三 + 裸 release 报错(v0.3.1+)
    • 对齐 framework 拆 release:patch / release:minor / release:major,裸 pnpm release 报错 + 提示三选一
    • 防 BC 改动"按 enter 默认 patch"误发(framework v0.12.0 已踩坑,cli / standards 同步对齐)
    • release script 显式传 --tag-version-prefix=cli/v
  • 🔄 命令层输出统一走 core/output(v0.3.1)
    • 之前各命令文件零散调 console.log / console.error
    • 统一改 output.success / output.error / output.warn / output.info / output.hint
    • 配合 --text / --json 模式实现 interactive / text / json 三态输出
    • setNestedValue 泛型化
  • 🚀 接入 ESLint flat config(v0.3.x)
    • 跟 framework / starter / docs 统一 lint 体系
    • 接入 @swift-web/standards/eslint
  • ⚠️ configKey 改名(v0.3.0 BC)
    • swiftWebFramework → swiftConfig,配置项 key 缩短
    • 注释 + 测试 fixture 同步更新
    • 项目模板 nuxt.config.ts / swift.config.json 同步迁移
  • ⚠️ 删 sw init-mcp 命令(v0.3.0 BC)
    • MCP 配置改为通过文档指导 applier 手工写 .mcp.json,不再由 cli 命令生成
    • 配合 sw_framework_docs MCP tool 在 cli 内部一站提供

docs

  • 🔧 publishConfig + .npmrc 切 verdaccio
    • 升下游依赖 framework ^0.14.0 / standards ^0.1.1
  • 🔧 加 pnpm 11+ preinstall 阻塞
    • 跟 starter 同款 check-pnpm.mjs
  • 🔧 跟 framework 0.10 / 0.11 / 0.12 / 0.13 BC 同步文档
    • SwButton API 重设计 → seo / 组件文档全面更新
    • titleTemplate / htmlAttrs 接管 → framework/seo 文档章节新增
    • defineRouteRules 硬校验 / removed default error.vue → routing / error-handling 重写
    • SystemInfo fail-fast / createError 结构化诊断 → 文档同步更新
    • 7 个组件文档同步 v0.12 API 重设计
  • 🚀 三语 client-encryption-boundary 新增(配合 fw v0.9.0 cookie 安全)
    • 明确"加密 ≠ 安全屏障"
    • cacheAesKey / apiKey 在 client bundle 中暴露,真正安全依赖 HTTPS + 后端鉴权
    • 与 standards 客户端安全主源章节同步
  • 🚀 docs framework/module-options systemInfo 文档迁移(配合 fw v0.8.0)
    • 旧 systemInfoIgnorePaths 章节替换为新 systemInfo schema 文档 + 迁移说明
    • systemInfo Store 自动初始化章节更新到新 API
    • 简介示例配置移除 systemInfoIgnorePaths,改 systemInfo
  • 🚀 三语 rendering-quick-guide 新增(配合 fw v0.8.0 ISR 安全)
    • 5 分钟决策矩阵 + 详情页决策树 + 反模式速查 + 示例代码 + review checklist
    • 与原 /guide/rendering-strategies(理论篇)并列
    • 让实践派开发者快速决策选 ISR / SSR / CSR / SSG

2026-04

framework v0.4.x → v0.6.x · cli v0.2.1 → v0.2.7

SEO 标志性发布 + 组件大规模重命名 BC + 业务组件三态 prop 模式统一。

framework

  • 🚀 auth 安全加固(v0.6.5)
    • initCode 渠道码 URL 注入防护:?switch=1 路径下从 URL 注入的渠道码会被中间件拒绝,防恶意链接劫持渠道归因
    • logout 清理同步:登出时同步清渠道码 cookie / IDB 解密缓存 / 约定登录凭证 localStorage 三处状态
  • 🚀 useSeo dev 体验完善(v0.6.1 ~ v0.6.4 系列)
    • v0.6.4:SEO 指南页从 framework 内部 wiki 迁出到公开 docs 站
    • v0.6.3:告警 console 输出紧凑化 + 链接到 SEO 知识库 wiki
    • v0.6.2:dev 长度警告加页面 URL + 新增 silenceLengthWarnings: true 静音开关(私有页 / 工具页用)
    • v0.6.1:JSON-LD 切换到 @unhead/schema-org/vue 导入路径(解决与 nuxt-schema-org 的签名差异)
  • 🚀 SEO 标志性发布(v0.6.0)
    • useSeo() composable 一站式 SEO 元信息:每个 page 一次调用自动输出全套 og:* / twitter:* / canonical / JSON-LD
    • origin 4 层兜底:显式 → systemStore.info.site_url → runtimeConfig.public.siteUrl → useRequestURL(解决多副域名 + 反代未配齐 X-Forwarded 头时 canonical 漏内网地址)
    • image 4 层兜底链:显式 → header.og_image → header.img → /og-image.png
    • robots prop:'private' (noindex,nofollow) / 'noindex' (noindex,follow) / 任意原始字符串
    • JSON-LD 默认输出 WebSite + WebPage schema;type:'article' 时加 Article schema
    • 强制启用 @nuxtjs/sitemap + nuxt-schema-org + @nuxtjs/robots 三子模块(不可关闭,仅 aiBotPolicy 选项控制 GPTBot/ClaudeBot/CCBot/PerplexityBot 等 AI 训练 bot)
    • SwImage 新增 preload prop 自动注入 <link rel="preload" as="image">,配合 loading="eager" + fetchpriority="high" 用于详情页 hero 大图 LCP 优化
    • 后端 system.info.header.og_image 字段(运营 CMS 上传 1200×630 PNG/JPG);旧 img 字段保 0.6.x 兼容期 0.7.0 移除
  • 🐛 业务组件多项修复(v0.5 / v0.6)
    • useLoginBy iOS Safari 误判 WebView:原 /Version\/[\d.]+(?: Chrome\/)?/ 正则 Chrome/ 可选分组导致 iOS Safari Version/X.X Mobile/... 命中后被误判走 redirect 登录;修复为强制要求字面 <空格>Chrome/
    • SwModal:description 在同时传入默认 slot 时不渲染(aria-describedby 警告),现在传入 description 即始终渲染
    • useToast / useModal:crypto.randomUUID 在非 HTTPS 环境(如 http://0.0.0.0)不可用,添加 Date.now + Math.random 降级兜底
    • SwTiptapEditor:移除模板绑定中的 as Editor 类型断言,修复 vite-plugin-vue-tracer 解析报错
  • 🚀 SwImage 能力补齐(c-image 迁移缺口,v0.5)
    • 外层 click 事件(覆盖 overlay 区点击)
    • title prop(hover tooltip / SEO)
    • placeholder 类型扩展为 string | { dark, light } | false,对象形式走 CSS-only 主题切换
    • placeholderClass prop + 内置最小化占位兜底样式
    • #placeholder slot(slot 优先于 prop);@load / @error 事件透传
    • hover-zoom class(opt-in)+ CSS 变量 --sw-image-hover-zoom-scale
  • 🚀 新增组件(v0.5)
    • SwAddToHomescreenGuide:H5 PWA 添加到主屏幕引导,从屏幕底部滑入非阻断式 bottom-sheet,iOS Safari / Android Chromium 各给对应步骤,桌面 / WebView / 国产浏览器静默不弹;rememberFor prop 支 'session' / 正数 N(N 天内不再弹);CSS 变量 --sw-add-to-homescreen-guide-bg / --sw-add-to-homescreen-guide-radius / --sw-add-to-homescreen-guide-z 定制
    • SwQrcodeScanner:图片二维码识别,含 trigger / preview 插槽 + 完整事件流
    • SwQrcodeGenerator:二维码生成,自定义尺寸 / 容错级别 / 前景背景色 + PNG 下载
    • SwFormField 简单模式:name 可选,新增 required / hint / error prop,作为表单字段布局容器使用,不依赖 vee-validate
  • 🚀 业务组件「三态 prop」模式统一(v0.5)
    • onRecord / fetchPlayUrl 等 prop 支持三种语义
    • undefined → 走默认 API(SwVideoPlayer 默认 POST /movie/doHistory、SwAudioPlayer 默认 POST /audio/doHistory、SwVideoPreview 默认 POST /movie/play)
    • function → 覆盖默认行为
    • null → 显式禁用
    • 业务方零配置即可工作,需要走自己 API 时传 function,明确禁用传 null
  • ⚠️ 组件大规模重命名 + API 重设计(v0.5 BC)
    • SwBtn → SwButton:CSS class sw-btn → sw-button;新增 type 语义类型 prop + loading prop + #loading / #icon / #icon-right 三插槽
    • SwAlink → SwLink:sw-alink → sw-link;安全修复 target="_blank" 自动加 rel="noopener noreferrer",外链额外 nofollow
    • SwPlayer → SwVideoPlayer:仅 rename,API 不变
    • SwPlayerAudio → SwAudioPlayer:rename + 完全重写对齐 SwVideoPlayer。新增 url / type / linkCode v-model / initialSeekTime(替代 seekTime)/ 14 emit / 6 expose(含 switchLink 保留进度),删 playMode,修「切换线路 N 次 → N 个 timeupdate 监听堆叠」
    • SwPlayerPreview → SwVideoPreview:rename + 能力补齐。fetchPlayUrl 三态默认走 /movie/play,新增 url 直传跳过 fetch + mp4/webm 支持 + reload() 应对 URL 过期
    • AudioRecordParams 类型变化:新增 event / view_time / code 字段(向 VideoRecordParams 对齐),自定义 onRecord 需更新类型签名
  • 🔧 reset.css / theme.css 增强(v0.5)
    • 新增 scrollbar-width: thin 全局细滚动条,消费项目开箱生效
    • 暗色模式两个选择器加入 color-scheme: dark,浏览器滚动条轨道等系统 UI 自动切换为暗色
    • dexie / qrcode 自动注入 Vite optimizeDeps.include,pnpm 严格模式下消费项目不再需要手动配置

starter

  • 🚀 useSeo() 全量替代 useSeoMeta(配合 fw v0.6.0)
    • starter 6 页全部迁移到 framework 接管的 useSeo()
    • local-seo/require-seo-meta ESLint 规则强制每页必填 SEO
    • 私有页(profile / login / register / mine 等 4 页)设 robots: 'private' / 'noindex'
  • 🚀 public/og-image.png 占位图 + prebuild check-og-image 检查(配合 fw v0.6.0)
    • 1200×630 PNG 占位图放进 public/
    • scripts/check-og-image.ts 在 prebuild 阶段验证,缺失则 build 失败
    • 防 applier 删 og-image.png 后社交分享卡片 broken
  • 🚀 @phosphor-icons/vue(v0.5 期)
    • 1300+ 图标、6 种风格作为标准图标库加入直接依赖
    • 替代之前依赖 framework 自带图标方案
  • 🚀 modal.css 默认视觉样式(v0.5 期)
    • SwModal 默认视觉样式(遮罩、居中卡片、按钮、入场动画),亮 / 暗主题自动适配
    • 可在 custom.css 中覆盖 --sw-modal-* CSS 变量定制
  • 🔧 CSS rem 单位强制(配合 fw v0.4)
    • stylelint declaration-property-unit-allowed-list 强制布局尺寸(width / height / padding / margin)用 rem
    • 跟随浏览器字号缩放提升无障碍
    • border-* 和定位属性保留 px
    • 整工程从硬编码 px 切到 rem 单位制
  • 🔧 auth 中间件增强(配合 fw v0.4)
    • guest.global 中间件支持 ?switch=1 参数,允许已登录用户进入登录页切换账号
    • logout 后凭证自动清除
    • Guest 中间件匹配改用 startsWith,修复子路径未被正确拦截

cli

  • 🐛 sw upgrade 私仓认证修复(v0.2.7)
    • 原本 sw upgrade 用 npm view @swift-web/framework version 拉版本,没透传 ~/.npmrc 的 _authToken,私仓访问 401
    • 修复后正确传递 token,能从私有 registry 取得最新版本号
  • 🚀 MCP 工具 sw_framework_docs(v0.2.6)
    • 动态查询 framework 中可用的组件 / composable 清单
    • 让 Claude Code 等 AI 工具不再凭印象引用旧组件名(避免如 SwBtn 已改名后 AI 还在生成 SwBtn 的失误)
    • 配合 sw init-mcp 生成 .mcp.json(后续 v0.3.0 删 init-mcp 改文档指导)
  • 🚀 i18n-applier 对称化 + scanBusinessI18nUsage(v0.2.4 / v0.2.5)
    • enable / disable 流程对称,对齐 PWA / Tailwind 幂等原则
    • 新增 scanBusinessI18nUsage 模块扫描业务代码 i18n API 残留
    • 精简 enable 汇报;列出 disable 残留
  • 🚀 sw config sync 命令(v0.2.3)
    • 重跑所有功能开关 applier(i18n / pwa / tailwind 等),把 swift.config.json 与 nuxt.config.ts 强制对齐
    • 用于:手工改了 swift.config.json 后同步项目文件 / 升级 cli 后回灌新的开关默认值
  • 🚀 Tailwind v4 applier(v0.2.1)
    • sw init 交互扩展支持 Tailwind v4 一键启用
    • 自动注入 @import "tailwindcss" + 必要 vite 插件 + tailwind.css + stylelint 白名单
    • 六步注入幂等可重跑,关闭时自动回滚
  • 🚀 swift.config.json 精简(v0.2.1)
    • 移除冗余字段,与最新 ModuleOptions 形状对齐
    • sw add page 模板加 useSeo 占位与 framework SEO 强制启用对齐
  • 🚀 @swift-web scope 迁移到 group registry(跨 v0.2.x)
    • 从 project-level(432 / 435 分别 framework / cli)迁到 group-level(group 754)
    • 单 token 访问全部包;安装脚本(install.sh / install.ps1)同步更新
    • 简化 token 管理(之前每个包一个 deploy token)

docs

  • 🔧 Sidebar 调整
    • 各组件文档页同步 v0.5 组件重命名(SwBtn → SwButton 等)
    • 新增"渲染模式快速指南"入口(指向待新增的 rendering-quick-guide)
  • 🚀 6 个中文 markdown frontmatter 扩长达标
    • 按新 useSeo 长度阈值(中文 25-80 字 = 英文 50-160 字符)
    • use-add-to-homescreen / use-login-by / quick-start 简繁各 3 个
    • SEO 长度建议表加"显示宽度"说明 + 中英对照
  • 🚀 24 页 useSeo() 迁移(配合 fw v0.6.0)
    • docs 自己也跟着 starter 走
    • 英文页 silenceLengthWarnings: true(英文从中文翻译过来,长度不可控,length 警告对它们无意义)
  • 🚀 三语 framework/seo.md 同步(配合 fw v0.6.0)
    • 完整 useSeo() API 文档、origin / image / robots / JSON-LD 详细说明、SEO 强制启用机制
    • /guide/seo 附录 A 提供 MR review 自检清单 + eslint 规则名映射

2026-03

5 仓首发月。

framework

  • 🚀 首发 v0.1.0
    • 20 个无样式核心组件:SwButton / SwImage / SwModal / SwToast / SwUploadImage / SwPlayer / SwQrcodeGenerator 等
    • 8 个 composable:useModal / useToast / useTheme / useUploader / useLoginCheck / useLoginDialog / useLoginBy / useUserActive
    • 2 个全局 store:userInfo(用户信息 + Token 管理)/ systemInfo(系统配置)
    • 主题系统:light / dark / auto,localStorage 持久化
    • 路由守卫鉴权体系:guardedPaths / guestPaths 配置
    • 全局错误监控:Vue runtime 错误捕获上报
    • 生态集成:@nuxt/image / @vite-pwa/nuxt / @nuxtjs/i18n

starter

  • 🚀 首发
    • Nuxt 4 项目工程结构 + ESLint + TypeScript 严格模式
    • 内置 CI/CD(Dockerfile + GitLab CI 流水线)
    • SEO 基础设施(useSeoMeta() / sitemap / OG 图片生成)
    • 作为 swift-web 唯一的下游业务模板源

cli

  • 🚀 首发 v0.1.0
    • sw create <project-name> — 从 starter 模板生成完整 Nuxt 项目
    • sw config — 交互式管理 swiftWebFramework 配置项(启用 / 禁用各子模块)
    • sw add <type> — 代码生成器,快速生成页面 / 组件 / store 文件模板
    • --text 模式 — 在不支持彩色输出的 CI 环境降级为纯文本输出

docs

  • 🚀 首发
    • 基于 Nuxt Content 搭建官方文档站
    • 自定义 docs 布局 + 导航(DocsNavSidebar / DocsToc / DocsPageHeader / DemoBox / ApiTable 等专用组件)
    • 完成 20 个 Sw* 组件的 Props / Events / Slots 文档页与交互 Demo
    • 完成 useModal / useToast / useTheme 等 composable 文档页
    • 完成框架配置参考页(Module Options)
    • 支持亮 / 暗 / 跟随系统三种主题,PWA 离线访问
    • 三语言切换(简体中文 / 繁体中文 / English)