Skip to content

refactor(data-objectstack,plugin-chatbot,plugin-list)!: 台账燃尽批次 6 —— 12 个符号不再顶着 spec 的名字 (#3160) - #3220

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-3160-spec-symbol-batch6
Aug 2, 2026
Merged

refactor(data-objectstack,plugin-chatbot,plugin-list)!: 台账燃尽批次 6 —— 12 个符号不再顶着 spec 的名字 (#3160)#3220
os-zhuang merged 1 commit into
mainfrom
claude/issue-3160-spec-symbol-batch6

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #3160objectstack-ai/objectstack#4115 债务台账燃尽第 6 批。

台账 29 → 17,包数 14 → 11:@object-ui/data-objectstack@object-ui/plugin-chatbot@object-ui/plugin-list 三包整包出账

处置 符号
re-export DroppedFieldsEventPendingActionRowPendingActionStatus
结构性派生 ViewTab(取 schema 的 input 侧)
改名 CacheStatsMetadataCacheStatsMetadataSaveOptionsMetadataClientSaveOptionsSecurityPolicySecurityManagerPolicyValidationErrorDataApiValidationError
ALLOW ListViewUserFilters
路径跳过(非本仓授权面) ToolMessageContent

排版说明:本文中的泛型一律在 < 后加一个空格(Extract< A, B >)。GitHub 的 body 消毒器会把「< + 字母」当 HTML 标签在存储时吃掉,本 PR 首版就被吃掉了两处;加空格后 TypeScript 语义不变而能存活。


一、本批最该记的一条:分诊颗粒度是符号,不是簇 —— 又一次实证

issue 正文的已知情报写着「SecurityPolicy / DroppedFieldsEvent 大概率是协议形状的手抄件,优先派生」。对读之后只中了一半:

  • DroppedFieldsEvent 确实是手抄件,而且它的注释自己就承认了(见下)。
  • SecurityPolicy 与 spec 的那个一个键都不重合。spec 的是软件包供应链策略(autoScan / 许可证白名单 / 代码签名 / sandbox 限额),本地这个是浏览器侧的 CSP 头 + 审计日志 + 字段脱敏。同理 MetadataSaveOptions:spec 的两份(/system/kernel)都在描述把元数据写成文件(format/path/indent/atomic),本地这个是 MetadataClient.save()HTTP 信封(If-Match、actor、force、ADR-0033 draft/publish、package)。两对都是 Extract< keyof Local, keyof Spec > = never,已在 parity 测试里按这个式子钉住。

也就是说:同一句预判里的两条,一条派生、一条纯撞名。这与批次 5 记录的结论一致,只是这次方向相反(那次是「疑似撞名实测可派生」)。

二、三份 hand copy,三种把编译期检查关掉的方式

这批的漂移不是「少了一个键」那么简单,每一处都注销了一个本该生效的检查:

  1. DroppedFieldsEvent.reason 被拓宽成 string,理由写在注释里:「keeps reason as a widened string for forward-compatibility with reasons added server-side」。这正是 AGENTS.md [WIP] Enhance UI components for forms and layouts #12 禁止的消费端宽容 —— 而 AdapterProvider 的 toast 文案真的按 readonly_when 分支(#3794:「read-only」和「当前状态下不可编辑」是两句不同的话)。spec 加第三个 reason 时,唯一会提醒我们的信号被这行注释亲手删掉了。顺带:「so we don't pin a client type version」也是假的 —— spec 就是那个 client type version。
  2. PendingActionRow.status 被声明成 PendingActionStatus | string —— 与 string 求并吸收掉全部字面量,这个标注等于什么都没说;statusesForTab 完全可以返回一个服务端没听说过的状态。
  3. PendingActionRow[k: string]: unknown —— objectstack#4075 那个机制:索引签名让任何结构比较对 spec 都答「相同」,漂多远都一样。所以这一条只有守卫能抓到,parity 测试原理上抓不到(批次 5 的方法学第 7 条)。

另外 PendingActionRow 上的 created_at / updated_at 契约里没有、本仓也没有任何消费方读。一并删掉:真需要时该由 spec 建模,不是在这边加宽。

ViewTab 同理带一条渲染器侧宽容:visible 被声明成 string | boolean,而 getVisibleTabs 拿它跟字符串字面量 'false' 比。spec 把 visible 建模为 boolean,平台里没有任何生产方会发出那个字符串。派生之后该比较直接变成编译错误,而不是一段永远不会命中的死代码。

三、ViewTabinput 侧,判据写在调用形态里

spec 的 ViewTabz.infer,即 parse 之后的形状,pinned / isDefault / visible 三个 .default()全部变成必填。而 TabBar 拿到的是宿主从存量视图元数据里塞进来的 { name, label } —— 用 output 类型会让这个授权侧形状不可表达,正是 ObjectFieldGroup(#3169)和 OfflineConfig(#3199)踩过的 _input/_output 陷阱。

所以走 (typeof ViewTabSchema)['_zod']['input'],并沿用 packages/react/src/spec-input.ts 的技法从 schema 自身的 _zod 载体读 input 类型 —— 仍然是 spec 的绑定,不给 plugin-list 新增 zod 依赖。测试里把两侧都钉住了:parsed 侧 pinned/visible 必填、authored 侧可省,且两者键集完全一致(spec 加键会自动到位,退键会报红)。

四、ListView / UserFilters 进 ALLOW —— 用的是 AuthProvider 那条判据,不是「组件一律豁免」

批次 5 已经明确写过:AuthProvider 进 ALLOW 而 AuthProviderConfig 改名,理由不是组件豁免,而是失效模式本身(同一批里 FieldFieldContainer 就是被改名的组件)。按同一条判据对读:

  • spec 的 ListView / UserFilters 都是 type-only 的授权层元数据;
  • 本地两个都是渲染器,而且在声明处就绑住了那一层:ListViewProps.schema@object-ui/typesListViewSchema(它自己就是批次 1 论证过的 declared dialect),UserFiltersProps.configNonNullable< ListViewSchema['userFilters'] >;
  • 也就是说,这两个声明没有声明任何形状,自然也没有可漂移的形状 —— 「下一个 session 会当成权威去读的那个符号」在这里不存在;
  • 反向证据:本仓早就从另一侧做了消歧 —— @object-ui/types 把 spec 的那个 re-export 成 SpecListView;
  • 而改名的代价是重写全部消费方的 JSX 与包的头号导出,换来零缺陷修复。

ALLOW 不是白条:两条都配了会过期就报红的钉扎 —— spec 若不再导出这两个名字(ALLOW 就该删)、spec 的 ListView 若不再是授权元数据、组件若不再消费那个 spec 类型,测试都会红。

这一条是本 PR 里最值得维护者复核的判断。若倾向改名,机械改动很小:ObjectListView(与同包的 ObjectGallery 成对)与 UserFilterBar 都已跑过守卫、确认不是 spec 导出。

五、Tool / MessageContent路径跳过,并补上路径跳过的洞

这两个在 packages/plugin-chatbot/src/elements/,而那整个目录不是 objectui 的授权面:每个文件头都写着 Sourced from vercel/ai-elements (https://elements.ai-sdk.dev) — MIT. Vendored via the shadcn-style copy-into-source model. Do NOT edit business logic directly … To re-sync, fetch the latest from …(elements/ui/ 下另有两个同样形态的 shadcn 原件)。这与守卫已经在跳过components/src/ui/ 是同一类,守卫文件头对那条的措辞逐字适用:「upstream 3rd-party files overwritten by sync scripts, so a collision there is not ours to fix」。

改名在这里是错的:这两个名字就是上游的组件 API。改了会被下一次 re-sync 抹掉,并且让照着上游文档把 Tool / ToolHeader / ToolContent 组合起来写的人失败。

路径跳过比 ALLOW 粗,它开的洞是「objectui 自己写的文件藏进该目录后不被扫描」。所以本 PR 一并把洞堵上:新增的 provenance 测试要求该目录下每个文件都带 vendor banner,且那唯一一个 objectui 写的 barrel 只能是纯 re-export。变异测试第 5 向验证了这一点(见下)。

同时按批次 5 PerformanceConfig 的做法配了反向 pin:spec 若哪天退掉 Tool / MessageContent,守卫注释里那句「跳过的是这两条碰撞」就过期了,测试报红要求重读 —— 绕行方案不该活得比它的理由长。

六、一个刻意没有跟着改的名字

DataApiValidationError运行时 name 仍然是 'ValidationError'normaliseClientErrore.name === 'ValidationError' 嗅探 @objectstack/client 抛出的错误,@object-ui/reacterror-message 出口侧也这么判 —— 那个字符串是线上契约,改它是行为变更,而改符号只是源码改名。已加断言钉住,并在类的注释里写明。

这正是批次 4 提的那条施工规约(「在记录该碰撞的文件内部同样不要做全局替换」)的正面用法:renames 全部按标识符边界替换,toBe('ValidationError') / name: 'ValidationError' 这些字面量一个没动。


验证

  • 台账:--ledger 重生成后逐条 set-diff —— removed 恰为本批 12 条,added 为空,其余 11 个包的条目逐字节未变(批次 7 / objectui#3161 的 14 条一个没碰)。守卫绿:11 declared dialects, 17 untriaged collisions in 11 packages
  • 合并 main 后重验(本分支在飞期间 feat(types,core,app-shell)!: follow the managedBy: 'system''system-data' retirement (objectstack#3355) #3214 落地):pnpm install --frozen-lockfileturbo build 44/44turbo type-check --force 78/78
  • 测试:data-objectstack 19 文件/153、plugin-chatbot 17/251、plugin-list 19/284、core 19/153,全绿。合并前还跑过一次全量 turbo test(68/73,失败见下)。
  • 编译期钉扎真的被编译:plugin-chatbot / plugin-list 按 objectui#3181 约定新增 tsconfig.typetests.json 并从 type-check 串接(check-type-check-coverage.mjs 现报 6 个包有窄类型断言工程,原为 4)。data-objectstack 不需要 —— 它的 tsconfig.json 本来就不排除测试文件,tsc --noEmit 已经在编译这些断言;为了保住这个性质,它的 spec 名字探针改用 ts.sys + TS 自己的模块解析,而不是 node:fs(否则要把 @types/node 塞进一个浏览器侧适配器的类型环境)。
  • ESLint:改动文件 0 error(warning 全是 Assert< … > 型别名的 no-unused-vars,与已合入的 batch 5 parity 测试同形)。
  • 变异测试五向,全部报红:
    1. ViewTab 改回一份忠实手抄 → 守卫按名+按文件红(TabBar.tsx:42),同时 typetests 红(spec-symbol-batch6.test.tsx(154) TS2344);
    2. 撤销 ValidationError 改名 → 守卫红(errors.ts:176);
    3. 把已烧掉的 ViewTab 留在 DEBT → 腐烂棘轮红;
    4. 删掉 ListView 的 ALLOW 条目 → 守卫红(同时报出 ListView.tsx:456 与 barrel 的 index.tsx:16);
    5. 往被跳过的 src/elements/ 里丢一个 objectui 自己写的 export interface Tool守卫按设计放行(这正是路径跳过的洞),provenance 测试红并指出该文件没有 vendor banner。

顺带记录(未在本 PR 修)

  • objectui#3219:plugin-calendar/src/registration.test.tsxmain 上就是红的(@object-ui/reactvi.mocksubscribeDataChanges,文件级失败而非断言失败)。已把本分支全部改动 git stash -u 后在基线提交上复现确认。
  • plugin-listTabBar / TabBarSelect / ViewTab 在本仓没有任何消费方(只从 barrel 导出)。没有顺手删,那是行为/API 变更,不该搭在符号燃尽 PR 上。
  • data-objectstackSecurityManager 那一段注释还写着「Security module integration for @objectstack/spec v3.0.0」,装的是 17.0.0-rc.1;本 PR 只改了被撞名的那个类型,没有去动这段陈旧描述。

草稿 PR,未自行合并。按 objectui#3160 的完成定义,objectstack#4115 的跟踪评论与本 issue 的关闭都在合入之后。

…atch 6 — 12 symbols stop wearing spec names

objectui#3160, objectstack#4115 ledger batch 6. All three packages leave the
ledger (29 -> 17 collisions, 14 -> 11 packages).

Verdicts, per SYMBOL rather than per cluster — the batch's own triage note
predicted `SecurityPolicy` and `DroppedFieldsEvent` were both spec hand copies,
and only one of them was:

@object-ui/data-objectstack
  - DroppedFieldsEvent  -> re-export. The copy's comment said it mirrored the
    spec "so we don't pin a client type version" and widened `reason` to bare
    `string` "for forward-compatibility". The spec IS the client type version,
    and the widening deleted the only signal that would tell AdapterProvider's
    toast (it branches on `readonly_when`) that a third reason had appeared.
  - CacheStats          -> MetadataCacheStats   (spec's is ICacheService's)
  - MetadataSaveOptions -> MetadataClientSaveOptions (spec's writes a FILE)
  - SecurityPolicy      -> SecurityManagerPolicy (spec's is supply-chain)
  - ValidationError     -> DataApiValidationError, per the cross-package
    convention registered on objectstack#4115. The RUNTIME `name` stays
    'ValidationError': normaliseClientError and @object-ui/react's
    error-message both sniff err.name, so that string is a wire contract.

@object-ui/plugin-chatbot
  - PendingActionRow / PendingActionStatus -> re-export. Three drifts, each of
    which had DISABLED a compile-time check: `status: PendingActionStatus |
    string` (a union with string absorbs the literals), `[k: string]: unknown`
    (objectstack#4075 — makes every structural comparison answer "identical"),
    and created_at/updated_at, which the contract lacks and nothing reads.
  - Tool / MessageContent -> SKIP_PATH_SEGMENTS. They live in src/elements/,
    vendored Vercel AI Elements + two Shadcn primitives, the same class as the
    already-skipped components/src/ui/. The names ARE the upstream component
    API, so a rename is undone by the next re-sync. The hole a path skip opens
    is closed by a provenance test: every file there must carry its vendor
    banner, and the barrel must stay a pure re-export.

@object-ui/plugin-list
  - ViewTab -> derived from the spec schema's INPUT side (pinned/isDefault/
    visible carry .default()s and this reads authored metadata). Drops a
    renderer-side tolerance: `visible` accepted `string | boolean` and the tab
    bar compared it against the literal 'false', which no producer emits.
  - ListView / UserFilters -> ALLOW. The AuthProvider test, not "components are
    exempt": each is the RENDERER of the spec type whose name it shares and
    takes that type as a prop (ListViewProps.schema, UserFiltersProps.config),
    so neither declares a rival shape. @object-ui/types already aliases the
    spec's type as SpecListView from the other side.

Verification: `--ledger` regenerated and set-diffed — removed is exactly these
12, added empty, all 11 other packages byte-identical (batch 7's symbols
untouched). Guard green; turbo build 44/44 and type-check 78/78 --force after
merging origin/main; data-objectstack 153, plugin-chatbot 251, plugin-list 284
and core 153 assertions green. Five mutation directions all red: re-forking
ViewTab (guard by name+file, and the typetests pin), undoing the
ValidationError rename, leaving a burned name in DEBT, deleting the ListView
ALLOW entry, and dropping an authored `Tool` into the skipped vendored dir
(guard blind by design, provenance test red).

Pre-existing and unrelated, filed as objectui#3219: plugin-calendar's
registration.test.tsx fails on main (an @object-ui/react vi.mock missing
`subscribeDataChanges`); reproduced with this branch stashed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PRJtkgUAaVG11FsJQbvZWA
@vercel

vercel Bot commented Aug 2, 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 2, 2026 5:45pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation data-adapter dependencies plugin tests labels Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

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

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.47KB 3.09KB
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.12KB 3.41KB
auth (LoginForm.js) 17.86KB 5.29KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.43KB 2.09KB
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) 18.38KB 4.49KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 3.65KB 1.42KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.25KB 0.53KB
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) 476.12KB 104.47KB
core (index.js) 2.25KB 0.80KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 136.23KB 34.75KB
fields (index.js) 223.45KB 54.66KB
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.46KB 0.96KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 5.37KB 1.72KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 3.26KB 1.44KB
layout (index.js) 38.47KB 10.67KB
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.05KB 1.53KB
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.90KB 12.35KB
plugin-charts (index.js) 60.53KB 17.12KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 111.87KB 28.82KB
plugin-designer (index.js) 210.51KB 42.50KB
plugin-detail (index.js) 230.54KB 56.77KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 111.39KB 26.93KB
plugin-gantt (index.js) 162.26KB 39.53KB
plugin-grid (index.js) 185.10KB 49.04KB
plugin-kanban (index.js) 47.82KB 13.18KB
plugin-list (index.js) 104.86KB 25.30KB
plugin-map (index.js) 16.80KB 5.24KB
plugin-markdown (index.js) 13.65KB 4.67KB
plugin-report (index.js) 40.48KB 10.57KB
plugin-timeline (index.js) 25.76KB 7.32KB
plugin-tree (index.js) 8.34KB 2.82KB
plugin-view (index.js) 83.54KB 20.39KB
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.46KB 1.21KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 0.20KB 0.18KB
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

@os-zhuang
os-zhuang marked this pull request as ready for review August 2, 2026 18:01
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 2, 2026
Merged via the queue into main with commit c5ccbd5 Aug 2, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-3160-spec-symbol-batch6 branch August 2, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

data-adapter dependencies documentation Improvements or additions to documentation plugin tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

台账燃尽批次 6/8 · data-objectstack + plugin-chatbot + plugin-list,12 符号(objectstack#4115)

2 participants