Skip to content

fix(create-plugin): 清掉脚手架的未用 lucide 声明,并让生成的 schema 接口真的可达 (#3755, #3759) - #3826

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-3755-3759-scaffold-dead-artifacts
Aug 8, 2026
Merged

fix(create-plugin): 清掉脚手架的未用 lucide 声明,并让生成的 schema 接口真的可达 (#3755, #3759)#3826
yinlianghui merged 1 commit into
mainfrom
claude/issue-3755-3759-scaffold-dead-artifacts

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #3755
Fixes #3759

两条都是 create-plugin 生成产物里「声明了但不可达」的死产物,且都落在 PR #3733 那道 import 闸门的盲侧 —— 它只拒绝「未声明的 import」,从不反过来查「没人 import 的声明」。#3742 / PR #3754 已落 main,本 PR 在其现状上动,未回退其锚点表(那张表管 devDependencies,与本 PR 的两处面不相交)。

核验基线:origin/main @ 5147d9305(worktree /home/user/objectui-3755,git worktree add ... origin/main,未依赖 FETCH_HEAD)。两单前提实测均仍成立:templates.ts:125 仍是 'lucide-react': '^0.563.0';仓内 23 处声明全为 ^1.28.0;grep "from './types" 空;exports. 一个键。


取舍与否决窗

分诊席与 PM 的干净缺省是两单都走方向 2(删除)。实读之后我对两单给出不同结论,依据如下 —— 这正是 dispatch note 授权的分叉("若 dev 实读后判方向 1 更当,须给证据")。

#3755 → 方向 2(删除),与缺省一致

lucide-react 从生成的 dependencies 移除,该 map 现在恰为四条 workspace:*

证据:

  1. 零个生成源文件 import 它(buildIndexFile / buildImplFile / buildTypesFile / buildTestFile 全部不碰)。
  2. 它被钉死,不是「落后但会追上」:0.x 的 caret 不跨 minor,^0.563.0 等价于 >=0.563.0 且小于 0.564.0,连 0.x 内的后续版本都拿不到。
  3. 仓内约定就是「import 才声明」:24 个提到 lucide-react 的 manifest 里 23 个真的 import 它(两种引号都数过 —— 只用单引号 grep 会漏掉 calendar/gantt/kanban 的双引号写法,初查时我漏过一次),没有任何包为「还没写的代码」预声明图标库。所以脚手架这条未用声明在仓内是孤例。
  4. 方向 1 要为一条死声明持续付维护费:把它锚到 ^1.28.0 就必须同步把 PR fix(create-plugin): 把脚手架 build 侧 devDependencies 锚到仓内工具链,并把整张清单钉进 parity 测试 #3754 的锚点表从 devDependencies 扩到 dependencies,即为一条永远没人 import 的声明维护一行锚点。删掉之后作者要图标就 pnpm add lucide-react,在本 workspace 里装到的自然是当前版本,与 23 个兄弟包一致 —— 不需要任何表。

补充说明(如实):@object-ui/components再导出 lucide 图标,所以不存在「改用 components 取图标」这条替代路径;删除后的效果就是作者自己按需装。

#3759 → 方向 1(补 entry 导出),与缺省相反

生成的 src/index.tsx 增加一行 export type { PascalSchema } from './types';,src/types.ts 产物保留

之所以推翻「删除」,是因为这条产品判断在仓内已经做过并且写进了文档,不需要维护者重新拍:

  1. create-plugin 自己的文档页把它写成 Best Practice —— content/docs/utilities/create-plugin.mdx:

    Export your schema types. The schema interface is the contract between a metadata author and your renderer, so make it importable rather than internal.

    也就是说脚手架违反的是它自己那页文档给作者的建议。删掉产物等于把这条建议也一并作废。

  2. content/docs/guide/plugin-development.mdtypes.ts 写进 plugin anatomy(文件表一行:"types.ts | Schema interfaces extending BaseSchema from @object-ui/types."),其 worked example 的 entry 末尾就是 export type { BoardSchema, BoardProps, BoardColumn, BoardItem } from './types';

  3. 仓内 4 个带 src/types.ts 的插件(charts / editor / kanban / markdown)全部从 entry 导出它,且 4 个的 exports map 都只有 . —— 说明 entry re-export 正是本仓让 schema 类型可达的既有手法,create-plugin 生成的 src/types.ts 是死产物:没有任何生成源文件 import 它,exports map 又只暴露 .,消费者拿不到那个 Schema 接口 #3759 正文里的方向 3(给 exports./types 子路径)确实是多余的。

  4. 「写了但 entry 不导出」这个形态在仓内是 0 例,脚手架产出的是一个仓内任何地方都不存在的形状。

  5. create-plugin 生成的 src/types.ts 是死产物:没有任何生成源文件 import 它,exports map 又只暴露 .,消费者拿不到那个 Schema 接口 #3759 正文自己也记了这一点:被 create-plugin.mdx 描述的是一个不存在的脚手架:提示词、产物目录、dev 脚本、配置文件、版本与依赖清单全部与真实生成器不符 #3715 删掉的旧文档虚构的 export * from './types'「恰好比真实模板更合理」。

具名 type-only 导出而非 export *:4 个在仓插件用的都是具名形式(kanban 显式列了 6 个名字),且 export * 会让作者以后往 types.ts 里加的每个类型都自动变成公共面。代价是作者新增类型要同时在 entry 补名字 —— 这是有意的,公共面应当是一次自觉动作。

#3759 的连带项:types.ts 改为 extends BaseSchema(这一条最需要否决窗)

这不是顺手扩范围,而是方向 1 的前置条件。原本那个手写的 { type; id?; className? } 在不可达状态下只是死重量;一旦 entry 导出它,它就成了每个脚手架插件已发布的 schema 契约面 —— 那时候发布一份 @object-ui/types 已经定义过的 base node 的手抄子集,就是 AGENTS.md 戒律 #0.1 说的「一份严格契约胜过 N 种方言」,而且这份子集静默丢掉了 BaseSchema 其余全部字段(namelabelvisible …)。所以:

  • import type { BaseSchema } from '@object-ui/types'; + extends BaseSchema,只把 type 窄化成注册键(packages/plugin-markdown/src/types.ts 是最近的模型);
  • 手抄的 id? / className? 删掉(BaseSchema 已有),不与 extends 并存;
  • 顺带把生成的 @object-ui/types 依赖变成被使用的声明。

否决窗:如果维护者认为脚手架不该预置 schema 类型面,那么正确的动作是把 #3759 退回方向 2(删 buildTypesFilesrc/types.ts),此时 extends BaseSchema 这一条自动随之消失,并且需要同步改 create-plugin/README.md:28plugin-development.md 的 anatomy 表。若只想否决 extends BaseSchema 而保留 entry 导出,我不建议:那会把一份 base-node 方言发布给每个脚手架插件。


新增的钉子:两道都做了「非空」自检

两条规则都是结构性的,不是字符串 grep:

  • 没有任何 versioned 运行时依赖可以在无人 import 的情况下被声明(workspace:* 豁免 —— 它按定义解析到本 workspace 当前版本,不会漂);
  • 没有任何生成的 src/** 模块可以从 entry 不可达(entry 是 exports map 暴露的唯一入口)。

关键点:这两条在修好之后的模板上都是对空集断言(已经没有 versioned 运行时依赖了;已经没有不可达模块了)。按 PR #5046 那个教训,「因为什么都没产出所以绿」不是闸门。所以每条各配一个自检:把删掉的缺陷原样种回去,断言规则点得出它的名字。

  • catches an unused versioned runtime dependency when one is present —— 种回 'lucide-react': '^0.563.0',断言返回 ['lucide-react'];并反向确认规则误伤真的被 import 的 versioned 依赖(否则它就变成「禁止 versioned」而非「禁止未使用」)。
  • reports the schema module as unreachable when the entry stops re-exporting it —— 把 entry 的 re-export 行剥掉,断言 src/types.ts点名

另外 derives the published schema interface from the protocols BaseSchema 钉住上面那条连带项,否则它无人看守、会被静默改回去。

fixture 三分类的实际落点(与派单预设不同,如实报告)

派单要求把「src/types.ts 存在」那条断言整条替换。这条要求预设了 #3759 走方向 2。实际走方向 1 之后,src/types.ts 仍然被写出,那条 exact-key-list 断言依旧成立且依旧正确,因此它属于三分类里的「不动」而非「换掉」—— 真正变的不是它的 verdict,而是它从来没有断言过可达性(这正是 #3759 点出的弱闸门)。所以做法是给它一个可达性兄弟,而不是替换它。若当初照字面替换,就会在方向 1 下删掉一条仍然有效的覆盖。


反向验证(方向先判后跑,三例全部与预判一致)

预判写在跑之前:两个 manifest/产物级闸门各应变红,而与之配对的规则自检应当保持绿(它们判的是规则本身,不是当前 manifest)。

A. 把 'lucide-react': '^0.563.0' 加回 DEPENDENCIES —— 预判 2 红:

× declares exactly the four workspace platform packages as runtime dependencies
× declares no versioned runtime dependency that the generated sources never import
AssertionError: expected { …(5) } to deeply equal { …(4) }
AssertionError: expected [ 'lucide-react' ] to deeply equal []
 Tests  2 failed | 17 passed (19)

B. 剥掉 entry 的 export type { ... } from './types'; —— 预判 2 红:

× writes no source file that is unreachable from the packages only entry point
× pins that entry-reachability is what makes a type consumable, via the exports map
AssertionError: expected [ 'src/types.ts' ] to deeply equal []
 Tests  2 failed | 17 passed (19)

C. 把 types.ts 退回手写接口(去掉 extends BaseSchema) —— 预判 1 红:

× derives the published schema interface from the protocols BaseSchema
AssertionError: expected '/**\n * ObjectUI\n * Copyright (c) 20…' to contain 'import type { BaseSchema } from \'@ob…'
 Tests  1 failed | 18 passed (19)

三例中配对的自检都如预判保持绿:A 里 catches an unused versioned … 因为种植 spread 成了 no-op 而仍返回 ['lucide-react'];B 里 reports the schema module as unreachable … 因为 .replace() 成了 no-op 而仍返回 ['src/types.ts']。这是设计使然,不是漏检。


验证

单测(仓库根,路径过滤,不加 --):

$ flock /tmp/os-heavy-verify.lock -c 'NODE_OPTIONS=--max-old-space-size=4096 pnpm vitest run packages/create-plugin --maxWorkers=2'
 Test Files  1 passed (1)
      Tests  19 passed (19)

改前基线 12 passed,新增 7 条(4 条闸门 + 2 条自检 + 1 条 BaseSchema 钉子)。

pnpm --filter '@object-ui/create-plugin^...' buildNo projects matched the filters —— 如实记录原因:该包只依赖 chalk / commander / fs-extra / prompts,没有 workspace 依赖,测试也只 import node builtins 与 ../templates,所以这一步没有可建的上游,不存在 TS2307 假红的风险面。

type-check + build:

$ pnpm --filter @object-ui/create-plugin type-check   # 无输出,通过
$ pnpm --filter @object-ui/create-plugin build
DTS ⚡️ Build success in 1525ms

生成产物冒烟(用真 CLI 走一遍,不是只断言数据):仓内既有测试不编译生成产物(全是纯数据断言),所以这一步实跑了一次而非复用。用构建出的 CLI 在 worktree 内 scaffold 出 packages/plugin-heatsmoke,pnpm install 后:

$ pnpm exec vite build
dist/index.js  5.19 kB │ gzip: 1.89 kB
dist/index.umd.cjs  4.60 kB │ gzip: 1.82 kB
✓ built in 6.79s

$ pnpm exec vitest run --root .
 Test Files  1 passed (1)
      Tests  1 passed (1)

关键一步 —— #3759 的修复在产物层成立,不只是源码层。生成的 dist/index.d.ts:

import { Heatsmoke } from './HeatsmokeImpl';
export { Heatsmoke };
export type { HeatsmokeProps } from './HeatsmokeImpl';
export type { HeatsmokeSchema } from './types';

dist/types.d.ts 一并 emit,内容为 export interface HeatsmokeSchema extends BaseSchema。即消费者 import type { HeatsmokeSchema } from '@object-ui/plugin-heatsmoke' 现在真的解析得到 —— 改前这个 import 无路可走。生成的 dependencies 实测为四条 workspace:*,exports 键实测为 ['.']

冒烟产物与被它改动的 pnpm-lock.yaml 已清除并还原,git status 只剩本 PR 的三个文件。

消费半径扫描(按规则被消费的地方扫,不是按被改的包):0.563 在仓内(除 lockfile 与无关的向量 fixture)已只出现在本 PR 自己的注释/自检里;content/** 无任何脚手架依赖区间声明(create-plugin.mdx 明确写了「Its dependency ranges are not listed here on purpose」),故 #3711 版本声明闸门与 doc-version-claims 均无需同步改动;create-plugin/README.md:28types.ts # Schema definitions 在方向 1 下依旧准确,无需改。

门禁自查:

$ node scripts/check-changeset-presence.mjs
✅  2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)
$ node scripts/check-changeset-no-major.mjs
✅  No changeset declares a `major` bump.
$ pnpm exec eslint packages/create-plugin --max-warnings=0    # 静默通过
$ grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]' templates.ts templates.test.ts changeset.md   # 零命中

changeset 档位 patch,与同族先例 PR #3754(#3742)和 #3716 一致 —— 生成产物变化对用户可见,但不改 create-plugin 自身 API。本仓 major 由 objectstack 对齐节奏决定,不在此声明。


越界发现(未在本 PR 修)

packages/cli/src/utils/app-generator.tscreateTempAppWithRouting() 生成的 layout import(:591-592)了 lucide-react,而它写出的 package.json(:963 起)显式声明了 react-router-dom没有 lucide-react —— 与 #3716 完全同类的缺陷(生成源 import 未声明的依赖),只是位于 packages/cli 而非 create-plugin,PR #3733 的闸门伸不到那里;同时它的工具链区间落后本仓一到三个 major(vite ^5.0.0 vs 仓根 ^8.2.0typescript ~5.7.3 vs ^6.0.3@vitejs/plugin-react ^4.2.1 vs ^6.0.5@object-ui/react|components ^0.1.0 而本仓已在 major 17),与 #3742 同类。已按 Prime Directive #10 单独建 issue(见 report),未在本 PR 处理。


Generated by Claude Code

…s schema interface reachable (#3755, #3759)

Two declared-but-unreachable artifacts in the generated plugin, both on the
blind side of the import gate #3733 added: that gate rejects an import nothing
declares, and never looked for a declaration nothing imports.

#3755 — the generated `dependencies` no longer pin `lucide-react`. It sat at
`^0.563.0` with no generated source importing it, so every scaffolded plugin
installed lucide 0.563.x for code that never referenced it: two majors behind
the 23 in-repo declarations (all `^1.28.0`), and unable to float even within
`0.x`, because a `0.x` caret does not cross minors (`>=0.563.0 <0.564.0`).
Removed rather than re-anchored — this repo declares an icon library where it
imports one (of 24 manifests mentioning it, 23 import it; none pre-declares it
for unwritten code), so `pnpm add lucide-react` lands the current version by
construction and no anchor table has to keep an unused entry honest. The map is
now exactly the four `workspace:*` platform packages, which cannot drift.

#3759 — the generated `src/index.tsx` re-exports the schema interface from
`src/types.ts`. The `exports` map exposes exactly one key (`.`), so the entry is
a consumer's only door, and nothing walked through it: no generated source
imported `./types`, and `<pkg>/types` / `<pkg>/dist/types` are closed by that
same map. The interface is the plugin's schema contract and it shipped dead —
while the generator's own docs page tells authors to "export your schema types
... make it importable rather than internal". Named type-only re-export, the
form all four in-repo plugins with a `src/types.ts` use.

That interface now extends `BaseSchema` from `@object-ui/types` rather than
re-declaring a subset of the base node. Unreachable it was dead weight;
published it would be a second dialect of a node the protocol defines, silently
omitting `name`, `label`, `visible` and the rest (AGENTS.md #0.1). Only the
`type` literal stays local. It also makes the generated `@object-ui/types`
dependency a used declaration.

Both halves are pinned structurally, not by string match: no versioned runtime
dependency may be declared that no generated source imports (`workspace:*`
exempt — it cannot drift), and no generated `src/**` module may be unreachable
from the entry. Each gate would pass over an empty result on today's templates,
so each is paired with a self-test planting the removed defect back and
asserting the rule names it.

Verified on the real artifact: scaffolded a plugin with the built CLI, then
`vite build` + `vitest run` green inside it, with `HeatsmokeSchema` present in
the emitted `dist/index.d.ts`.
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Aug 8, 2026 5:58pm

Request Review

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 28.1 KB 350 KB
Entry file index-dOJWzkVi.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.66KB 3.13KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 7.57KB 2.97KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 22.10KB 4.37KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 35.76KB 9.11KB
auth (createAuthenticatedFetch.js) 4.37KB 1.69KB
auth (index.js) 2.35KB 1.07KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 4.91KB 0.87KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 481.72KB 106.05KB
core (index.js) 2.96KB 1.13KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 139.51KB 35.97KB
fields (index.js) 230.82KB 56.70KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 2.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 4.52KB 1.96KB
layout (index.js) 38.53KB 10.71KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 3.67KB 1.12KB
permissions (evaluator.js) 4.41KB 1.44KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.55KB 0.71KB
plugin-ai (index.js) 15.71KB 3.79KB
plugin-calendar (index.js) 44.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.33KB 42.79KB
plugin-dashboard (index.js) 117.21KB 30.27KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 233.78KB 57.92KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 112.10KB 27.10KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 187.74KB 49.69KB
plugin-kanban (index.js) 48.30KB 13.28KB
plugin-list (index.js) 105.12KB 25.48KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.03KB 20.55KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.71KB 3.53KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 2.71KB 1.34KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Collaborator Author

✅ 验收通过(objectui 分片 PM,session_01GTRjn8xBqp75dk7kFupVRt)—— undraft + auto-merge。

说明:实施 dev 在容器重启中丢失,其 PR body 即完整报告,PM 按 body + git 实物独立核验。

#3759 方向反转裁定:采纳方向 1(entry 导出),推翻我给的方向 2 缺省。 认领评论开的分叉条件(「实读后判方向 1 更当须给证据」)被充分满足:该产品判断仓内已做过并写进文档 —— create-plugin.mdx 自己把「Export your schema types」写成 Best Practice、plugin-development.mdtypes.ts 写进 anatomy、仓内 4 个带 types.ts 的插件全部 entry 导出且「写了不导出」形态仓内零例。删产物等于作废自家文档建议 —— 证据链完整,无需维护者重拍。连带项 extends BaseSchema 同采纳:导出后手抄 base-node 子集即 #0.1 的第二方言,这是方向 1 的前置而非扩围;否决窗已在 PR body 写明。#3755 走方向 2 与缺省一致(0.x caret 钉死 + 23:0 仓内惯例)。

验证质量:两道新门皆对空集断言故各配「种回缺陷」自检(PR #5046 教训);反向验证三例含配对自检保持绿的设计说明;冒烟用真 CLI scaffold 到 dist 层证明可达性(dist/index.d.ts 的 re-export 实据)。fixture 处置偏离派单预设(「整条替换」预设了方向 2)——方向 1 下原断言仍有效,补可达性兄弟而非替换,偏离有理采纳。19/19 CI 零失败;changeset patch 同 #3754 档;越界发现(cli app-generator 同类缺陷)已按 PD#10 另立。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 8, 2026 18:07
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit c852682 Aug 8, 2026
20 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-3755-3759-scaffold-dead-artifacts branch August 8, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment