Skip to content

fix(app-shell): flow simulator evaluates a { dialect, source } edge guard (#3216) - #3217

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-3216-simulator-reads-expression-envelope
Aug 2, 2026
Merged

fix(app-shell): flow simulator evaluates a { dialect, source } edge guard (#3216)#3217
os-zhuang merged 2 commits into
mainfrom
claude/issue-3216-simulator-reads-expression-envelope

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#3216

缺陷

决策节点的一条出边,守卫存成 { dialect: 'cel', source: 'amount > 10' } 时,模拟器在时间线上报 Branch has no condition. 并跳过这条分支;变量给 amount = 20 也会落到 default 分支或直接死路,而引擎在真实运行时会正常求值这条守卫。

根因是 previews/simulator/ 里有两份手写的读法,都只认裸字符串:

  • flow-simulator.tscondStr
  • flow-sim-validate.tsedgeCondString

信封形式一律返回 undefined

为什么信封不是"边角拼写"

@objectstack/specExpressionInputSchema 是一个 ZodPipe:parse 时会把裸字符串改写成{ dialect: 'cel', source },而 FlowEdgeSchema.condition 用的正是它。也就是说,模拟器读不了的那种拼写,恰恰是平台自己对每一条作者写下的守卫产出的那种。仓内其它读同一字段的地方(conditionTextvalidateExpressionClient)一直两种都认——漏掉一条分支的只有模拟器这两处。

一个设计时调试器给出的路线和运行时不一致,比没有调试器更糟;而"不静默模拟与运行时不同的语义"正是模拟器自己写在文件头上的契约。

改法:收敛到一个读法

两处都改走 conditionText(previews/flow-canvas-layout.ts),即画布标签、FlowEdgeInspectorinspectors/flow-decision-edges.ts 的分支匹配已经在走的那一个。没有新增第三份手写读法——本 PR 之后,"边守卫怎么读"在本仓只剩一个答案,并且把这一点写进了 conditionText 的 JSDoc(第五份手写拷贝会把这一类缺陷原样带回来)。

行为上有两处变化,方向都是向运行时靠拢:

  1. 决策路由 —— 信封守卫会被求值,为真时选中该分支;时间线显示它实际执行的 CEL 源码,而不是 "no condition"。只带编译后 ast、没有 source 的信封(spec 阶段 M9.2)仍然报 "no condition":确实没有可求值的东西,如实说,而不是伪造一个结果。
  2. 预检诊断 —— validateFlowDraft 的"决策没有 default 分支"警告原先要求每条出边都是裸字符串守卫,守卫是信封的决策被静默豁免。它一样会死路,所以现在问题面板和画布横幅对这类流程也会给出警告。

类型

SimEdge.condition 改为 import type 引入 spec 的 ExpressionInput —— 这是 #3202FlowDesignerEdge 上摘掉的那份重述的最后一份拷贝。原来的 string | { source?: string } 两个方向同时是错的:

  • 过宽:它描述了一个没有 dialect 的信封,而服务端 FlowEdgeSchema 直接拒绝这种形状;
  • 过窄:正因为如此,多余属性检查会拒掉直接写成字面量的规范信封('dialect' does not exist in type '{ source?: string }')—— 持久化流程真正携带的那唯一一种形状,反倒是你写不出来的那一种。

所以是导入而不是重述:手工"修正"只会把漂移挪到下一个漏掉的成员(astmeta)上。

测试

  • previews/simulator/__tests__/flow-simulator.test.ts 新增 decision guards in the spec expression envelope (#3216):边固件不再手写信封,而是把作者输入喂给 FlowEdgeSchema.parse —— 断言的就是平台自己产出的形状,固件无法与 spec 漂移。覆盖 issue 正文的复现、"确实求值而不是一律为真"、ast-only 信封仍报 no condition、以及 flow-sim-validate 少判的那条诊断。
  • 新增 previews/simulator/__tests__/flow-sim-edge.types.test.ts,并登记进 tsconfig.typetests.json(CI 真的会编译的那个 project)。类型断言之外还有一条只有多余属性检查能观察到的:规范信封写成字面量必须能通过。
  • 修复前这些行为断言会失败(逐条验证过):
× selects the branch whose envelope guard is true (the issue repro)
AssertionError: expected [ 's', 'd', 'lo' ] to include 'hi'
× EVALUATES an envelope guard rather than treating it as always-true
AssertionError: expected undefined to be 'amount > 10'
× reports a dead-ending envelope guard as false, not as an absent condition
AssertionError: expected 'Branch has no condition.' to be undefined
× warns about a missing default when every guard is an envelope
AssertionError: expected false to be true
Test Files 1 failed | 1 passed (2)
Tests 4 failed | 29 passed (33)

修复后 Test Files 3 passed (3) / Tests 59 passed (59)。类型 pin 同样是有效的:把 flow-sim-types.ts 回退到 main 后,tsc -p tsconfig.typetests.json 在 4 条断言上报 TS2344: Type 'false' does not satisfy the constraint 'true'

验证

npx turbo run type-check --filter=@object-ui/app-shell --concurrency=2 # 29 tasks successful
npx vitest run --maxWorkers=2 packages/app-shell/src/views/metadata-admin/
# Test Files 115 passed (115) / Tests 1023 passed | 1 skipped (1024)
npx eslint packages/app-shell/src/views/metadata-admin/previews/simulator # 0 errors
node scripts/check-spec-symbol-derivation.mjs # ✅

已加 changeset(@object-ui/app-shell: minor —— 行为变更 + 公开类型收紧)。未触碰 scripts/check-spec-symbol-derivation.mjs(#3160 正在改该文件),也未触碰 content/docs/releases/

🤖 Generated with Claude Code

https://claude.ai/code/session_01PRJtkgUAaVG11FsJQbvZWA


Generated by Claude Code

… guard (#3216)
Two readers in `previews/simulator/` each hand-rolled `typeof c === 'string'`
and returned `undefined` for anything else, so a decision out-edge guarded by
the ADR-0089 expression envelope was reported as `Branch has no condition.`
and skipped — while the engine evaluates it normally at run time. That
envelope is not an exotic spelling: `ExpressionInputSchema` is a `ZodPipe`
that rewrites an authored guard string INTO `{ dialect: 'cel', source }`, and
`FlowEdgeSchema.condition` is that schema, so the shape the simulator could
not read is the shape the platform produces.
Both readers now go through `conditionText` — the one reader every other
consumer of the field already used (canvas labels, `FlowEdgeInspector`, the
Branches<->edges reconciliation) — so "how an edge guard is read" has exactly
one answer in this repo. `validateFlowDraft`'s "no default branch" warning
follows: a decision whose guards are envelopes was silently exempt from it.
`SimEdge.condition` mirrors the spec's `ExpressionInput` by importing it —
the last copy of the restatement objectui#3202 removed from
`FlowDesignerEdge` — pinned by compile-time assertions in the project CI
type-checks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PRJtkgUAaVG11FsJQbvZWA
@vercel

vercelBot commented Aug 2, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectuiIgnoredIgnoredAug 2, 2026 5:23pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)28.1 KB350 KB
Entry fileindex-CAgX_Dtf.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)8.47KB3.09KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)7.57KB2.97KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)22.10KB4.37KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.12KB3.41KB
auth (LoginForm.js)17.86KB5.29KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.43KB2.09KB
auth (SocialSignInButtons.js)9.60KB3.89KB
auth (UserMenu.js)3.40KB1.22KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)35.76KB9.11KB
auth (createAuthenticatedFetch.js)4.37KB1.69KB
auth (index.js)2.35KB1.07KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)4.91KB0.87KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
collaboration (CommentThread.js)18.38KB4.49KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)3.65KB1.42KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.25KB0.53KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)476.12KB104.47KB
core (index.js)2.25KB0.80KB
create-plugin (index.js)9.28KB2.98KB
data-objectstack (index.js)136.20KB34.74KB
fields (index.js)223.45KB54.66KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.32KB1.77KB
i18n (index.js)2.46KB0.96KB
i18n (pickLocalized.js)1.70KB0.83KB
i18n (provider.js)5.37KB1.72KB
i18n (useObjectLabel.js)26.14KB6.07KB
i18n (useSafeTranslation.js)3.26KB1.44KB
layout (index.js)38.47KB10.67KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.74KB
mobile (index.js)1.50KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.71KB0.42KB
mobile (useResponsiveConfig.js)1.36KB0.63KB
mobile (useSpecGesture.js)4.05KB1.53KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)8.75KB3.06KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)3.67KB1.12KB
permissions (evaluator.js)4.41KB1.44KB
permissions (index.js)0.91KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.52KB
permissions (usePermissions.js)1.55KB0.71KB
plugin-ai (index.js)15.71KB3.79KB
plugin-calendar (index.js)44.90KB12.35KB
plugin-charts (index.js)60.53KB17.12KB
plugin-chatbot (index.js)180.09KB42.72KB
plugin-dashboard (index.js)111.87KB28.82KB
plugin-designer (index.js)210.51KB42.50KB
plugin-detail (index.js)230.54KB56.77KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)111.39KB26.93KB
plugin-gantt (index.js)162.26KB39.53KB
plugin-grid (index.js)185.10KB49.04KB
plugin-kanban (index.js)47.82KB13.18KB
plugin-list (index.js)104.88KB25.32KB
plugin-map (index.js)16.80KB5.24KB
plugin-markdown (index.js)13.65KB4.67KB
plugin-report (index.js)40.48KB10.57KB
plugin-timeline (index.js)25.76KB7.32KB
plugin-tree (index.js)8.34KB2.82KB
plugin-view (index.js)83.54KB20.39KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.71KB3.53KB
providers (index.js)0.44KB0.22KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.67KB2.37KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)19.28KB6.38KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.02KB0.55KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)4.09KB1.74KB
sdui-parser (index.js)4.47KB2.03KB
sdui-parser (parse.js)10.04KB2.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)4.69KB1.48KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-retry.js)4.32KB2.02KB
types (index.js)2.46KB1.21KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)0.20KB0.18KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…aiming (#3216)
The behavioural suite's `specEdge` helper annotates its return as `SimEdge`,
and its JSDoc called that "a compile-time proof". It is not one here: the
package tsconfig excludes `**/*.test.ts`, app-shell's test tree is still
TEST_DEBT in the type-check ratchet, and vitest erases types — so no `tsc`
run reads that annotation. A comment claiming enforcement that nothing
performs is the objectui#3009 / objectui#3181 failure mode, in miniature.
The claim moves to where it IS compiled: `flow-sim-edge.types.test.ts`, in
`tsconfig.typetests.json`, now asserts `z.infer<typeof FlowEdgeSchema>`
extends `SimEdge` — an edge the server hands back is a thing the simulator
accepts, with no reconciliation and no cast. The helper's JSDoc says plainly
that its annotation is a statement, not a check, and points at the pin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PRJtkgUAaVG11FsJQbvZWA
@os-zhuangClaude

Copy link
Copy Markdown
ContributorAuthor

补一个第二次提交(a5c3220),是自查时发现自己写的注释在过度声明,顺手修掉:

flow-simulator.test.tsspecEdge 助手把返回值标注成 SimEdge,原注释称之为"编译期证明"。在本仓它不是:package 的 tsconfig.json 排除 **/*.test.ts,app-shell 的测试树在类型检查棘轮里仍是 TEST_DEBT,而 vitest 会擦除类型 —— 没有任何一次 tsc 读到那个标注。一条声称"这里被强制执行了"、实际却没人执行的注释,正是 #3009 / #3181 那类缺陷的缩影,不该由我再种一颗。

所以把这个断言搬到真的会被编译的地方:flow-sim-edge.types.test.ts(登记在 tsconfig.typetests.json 里)现在断言 z.infer< typeof FlowEdgeSchema > extends SimEdge —— 服务端交回来的那条边,就是模拟器能直接接受的东西,不需要任何调和、不需要 cast。助手上的注释改成如实说明"这是一句陈述,不是一次检查",并指向那条 pin。

验证:tsc -p packages/app-shell/tsconfig.typetests.json → exit 0;vitest run packages/app-shell/src/views/metadata-admin/previews/simulator/Test Files 2 passed (2) / Tests 34 passed (34)(比上一版多的 1 条就是新增的字面量断言用例)。PR 正文里"59 passed"是第一次提交时的计数,现在同样范围是 60。


Generated by Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Main entry (gzip)28.1 KB350 KB
Entry fileindex-CAgX_Dtf.js
StatusPASS

📦 Bundle Size Report

PackageSizeGzipped
app-shell (index.js)8.47KB3.09KB
app-shell (runtime-config.js)7.42KB2.32KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)7.57KB2.97KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)1.17KB0.53KB
auth (AuthProvider.js)22.10KB4.37KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.12KB3.41KB
auth (LoginForm.js)17.86KB5.29KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.43KB2.09KB
auth (SocialSignInButtons.js)9.60KB3.89KB
auth (UserMenu.js)3.40KB1.22KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)35.76KB9.11KB
auth (createAuthenticatedFetch.js)4.37KB1.69KB
auth (index.js)2.35KB1.07KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)4.91KB0.87KB
auth (useIsWorkspaceAdmin.js)1.61KB0.85KB
collaboration (CommentThread.js)18.38KB4.49KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)3.65KB1.42KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.25KB0.53KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)476.12KB104.47KB
core (index.js)2.25KB0.80KB
create-plugin (index.js)9.28KB2.98KB
data-objectstack (index.js)136.20KB34.74KB
fields (index.js)223.45KB54.66KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (i18n.js)4.32KB1.77KB
i18n (index.js)2.46KB0.96KB
i18n (pickLocalized.js)1.70KB0.83KB
i18n (provider.js)5.37KB1.72KB
i18n (useObjectLabel.js)26.14KB6.07KB
i18n (useSafeTranslation.js)3.26KB1.44KB
layout (index.js)38.47KB10.67KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.74KB
mobile (index.js)1.50KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.71KB0.42KB
mobile (useResponsiveConfig.js)1.36KB0.63KB
mobile (useSpecGesture.js)4.05KB1.53KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)8.75KB3.06KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)3.67KB1.12KB
permissions (evaluator.js)4.41KB1.44KB
permissions (index.js)0.91KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.52KB
permissions (usePermissions.js)1.55KB0.71KB
plugin-ai (index.js)15.71KB3.79KB
plugin-calendar (index.js)44.90KB12.35KB
plugin-charts (index.js)60.53KB17.12KB
plugin-chatbot (index.js)180.09KB42.72KB
plugin-dashboard (index.js)111.87KB28.82KB
plugin-designer (index.js)210.51KB42.50KB
plugin-detail (index.js)230.54KB56.77KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)111.39KB26.93KB
plugin-gantt (index.js)162.26KB39.53KB
plugin-grid (index.js)185.10KB49.04KB
plugin-kanban (index.js)47.82KB13.18KB
plugin-list (index.js)104.88KB25.32KB
plugin-map (index.js)16.80KB5.24KB
plugin-markdown (index.js)13.65KB4.67KB
plugin-report (index.js)40.48KB10.57KB
plugin-timeline (index.js)25.76KB7.32KB
plugin-tree (index.js)8.34KB2.82KB
plugin-view (index.js)83.54KB20.39KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.71KB3.53KB
providers (index.js)0.44KB0.22KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.67KB2.37KB
react (LazyPluginLoader.js)3.77KB1.33KB
react (SchemaRenderer.js)19.28KB6.38KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)1.02KB0.55KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)4.09KB1.74KB
sdui-parser (index.js)4.47KB2.03KB
sdui-parser (parse.js)10.04KB2.82KB
sdui-parser (types.js)0.29KB0.24KB
sdui-parser (validate.js)4.69KB1.48KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)0.20KB0.18KB
types (crud.js)0.20KB0.18KB
types (data-display.js)0.20KB0.18KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.87KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-retry.js)4.32KB2.02KB
types (index.js)2.46KB1.21KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)0.20KB0.18KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)0.20KB0.18KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.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 17:29
@os-zhuang
os-zhuang added this pull request to the merge queueAug 2, 2026
Merged via the queue into main with commit 39033a3Aug 2, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-3216-simulator-reads-expression-envelope branch August 2, 2026 17:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flow 模拟器把 { dialect, source } 信封形式的边守卫当成「没有条件」

2 participants

@os-zhuang@claude