Skip to content

fix(app-shell): Studio treats connector_action connectorConfig.input values as value slots - #28312

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-ug538h
Oct 31, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-ug538h

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Fixes #28164

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Studio 里连接器动作(connector_action)节点的「输入」每个值,现在和其他取值位一样,可以切换成 CEL 表达式,写进 {…} 模板记号时当场在表单里显示拒绝原因;调试运行也会在该步骤报出同一条拒绝。
  • 为什么改:fix(spec,service-automation,lint)!: registration and validate judge a connector_action's connectorConfig.input value slot #28150 之后发布时会拒绝输入里的 {…} 记号,但 Studio 读表达式台账时忽略了条目所在的块(connectorConfig),作者要到发布才看到错误,也没有写表达式的入口。
  • 风险与回滚:只改 Studio 前端三个读取点,不动 spec 与运行时;判词全部来自 spec 现有函数。回滚即 revert 本 PR。
  • 先看:flow-value-envelope.ts 的 isValueEnvelopeSlot、FlowNodeConfigField.tsx 的 isScalarValueSlot / valueSlotRefusals、flow-simulator.ts 的 configRefusal。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.connectorInputEnvelope-28164.test.tsx,预期 5 个测试全绿。
  • 需要你做的:无,席位落地。

What changes

The flow expression ledger roots connector_action input.* in the node's connectorConfig sibling block (block: 'connectorConfig', landed with #28150). Studio's three readers did not read the entry's block:

  • flow-value-envelope.ts isValueEnvelopeSlot now matches the entry's block through the spec's flowNodeExpressionBlock. It answers true for ['connectorConfig', 'input'] on a connector_action node, and false for the unreachable ['config', 'input'] it used to answer for. The Input key/value repeater therefore gets the text / CEL-expression toggle and its per-row refusal, like the other value maps.
  • FlowNodeConfigField.tsx: isScalarValueSlot accepts a field rooted in a declared sibling block (FLOW_NODE_SIBLING_EXPRESSION_BLOCKS) and asks resolveFlowNodeValueSlots with the node's sibling blocks. A typed connector input field (the ones an action's inputSchema produces, at connectorConfig.input.KEY) now renders the value-slot control. valueSlotRefusals hands flowNodeValueTemplateRefusals the node and keeps only refusals in the field's own block, so the spec's refusal of a {…} token shows under the value as it is typed. config fields behave exactly as before: still one key deep, and still judged by both config judges.
  • flow-simulator.ts: configRefusal takes the node, hands the value-slot judge its sibling blocks, and names the refusal's block in the line. The Debug run judges a connector_action step before mocking it, because the executor resolves connectorConfig.input before dispatch and refuses a {…} token there.

No i18n keys were added: the toggle label, placeholder and refusal sentences are the existing ones and the spec's own.

Tests

  • New FlowNodeInspector.connectorInputEnvelope-28164.test.tsx drives the real inspector render path through a host that applies each patch. For a typed field, a token typed into the Text input shows the spec's refusal (flowNodeValueTemplateRefusals, read from the installed spec) in the form, and a stored token shows it too. A plain literal shows none, and the toggle stores { dialect: 'cel', source } at the same key. For the repeater (an action with no inputSchema), a stored token and a typed token are both refused in place, and the toggle is offered on each row.
  • New flow-simulator.connectorInput-28164.test.ts: a token in connectorConfig.input fails the step with the spec's refusal naming connectorConfig.input.text. A literal plus a CEL envelope is mocked as before.
  • flow-value-envelope.test.ts: a new case pins the block reading (true for connectorConfig.input, false for config.input and for another node type). The six-map case changes to seven, on purpose. test(ui): pin the 19th flow value-ledger entry, connector_action input.* #28193 left it alone pending this card, and the new truth is that the designer table's connector_action connectorConfig.input key/value field is offered the envelope. The confirmation case that follows measures the new slot against the judge registerFlow applies there (FlowValueSlotSchema, through valueEnvelopeRefusals), and it gives the same sentences as the editor's AssignmentValueSchema for malformed envelopes and accepts the same literals. The ledger's 19-entry value list is unchanged.

Acceptance notes

  • A connector input field the resolver flattens from a nested object schema (connectorConfig.input.retry.attempts) is not a whole value slot, so it keeps its plain control. This matches config fields, which are value-slot controls only one key deep. The slot's refusal still reaches publish through the spec judge.
  • A typed connector input of kind number / select / boolean keeps its typed control with no expression toggle, as on config value slots, which offer the control only to text / textarea / expression fields.
  • The Debug run judges no other mocked node's value slots (create_record / update_record fields.*, http body). It mocks those nodes without reading their values, as before. Only connector_action was in this card's scope. Noted, not filed.

Verification

All readings on head ac2e380a, worktree off origin/main 6285203d.

Targeted tests and package checks
  • pnpm --dir ui exec vitest run over inspectors/, previews/ and the 31 other app-shell test files that import a changed module or its hosts (FlowNodeConfigField, flow-value-envelope, flow-simulator, FlowNodeInspector, FlowKeyValueField, FlowPreview, FlowCanvas): Test Files 405 passed (405), Tests 4763 passed, 1 skipped. Lock VERDICT command-exit 0.
  • pnpm --filter @object-ui/app-shell type-check (both tsc --noEmit and tsc -p tsconfig.test.json): VERDICT command-exit 0.
  • eslint over the six changed ui files: exit 0. pnpm check:new-line-citations: 0 new citations, exit 0.
  • Declared narrowing: the full app-shell suite (about 2,000 files) was started with 2 workers and stopped unfinished after about 50 minutes. CI's sharded Test UI runs the whole suite.
Ablation (one-shot)

With the fix committed, the three changed sources were restored from origin/main (tests kept) and the three new/updated test files were run: Test Files 3 failed (3), Tests 8 failed | 11 passed. Every new pin went red. Restored with git checkout HEAD, and git diff HEAD was empty afterwards. A first attempt was a no-op: its paths carried a ui/ prefix, which the vitest invocation guard refused. It was rerun with the paths written relative to ui/.

Derived gates (dispatch-gates --commands, 35 families)

Every line ran with stdin from /dev/null, and its exit code was recorded before any pipe. dispatch-gates --ran: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN. All 35 exited 0, including node scripts/check-sdui-manifest.mjs and its --self-test, pnpm --dir ui exec vitest run scripts/ (Test Files 169 passed, 2 skipped), pnpm check:type-check-debt (run under the verify lock after a first run timed out in the queue, exit 3 NOT MEASURED), and pnpm check:query-options-erasure (rerun without the 280 s per-gate cap that cut its first run, exit 124).


Generated by Claude Code

…s value slots in Studio

The flow expression ledger roots connector_action input.* in the node's
connectorConfig sibling block. Studio's readers ignored the entry's block,
so the Input section offered no CEL-expression editor and no in-form
refusal of a {…} token, and isValueEnvelopeSlot answered for the
unreachable config.input instead.

- isValueEnvelopeSlot matches the entry's block (flowNodeExpressionBlock).
- FlowNodeConfigField judges a typed input field through the value-slot
  judge with the node's sibling blocks, so it renders the text / expression
  control and the spec's refusal.
- The Debug run judges a connector_action node's input before mocking it,
  and names the block in the refusal.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibxVHVAdKszs18owvD6
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 31, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#3 · os-tesla · session_01L9qibz8HEj53Wx2uphTo2o

维护者速读

席位意见:读者改为按账本声明的 block 定位,判定仍由 spec 函数给出,调试与发布同一句拒收,可直接落地。

席位核对

ACCEPT · seat domain:ui#3 · head ac2e380a · 2026-10-31T04:28Z

  1. Shape: Fixes #28164, draft, base main; 7 files, +380/−34: flow-value-envelope.ts matches a value-role entry on flowNodeExpressionBlock(entry) === block (so ['config','input'] on connector_action no longer answers, ['connectorConfig','input'] does); FlowNodeConfigField.tsx slotBlockOf / withValueAt / valueSlotRefusals hand the node's sibling block to flowNodeValueTemplateRefusals(type, config, node) and filter by refusal.block; flow-simulator.ts configRefusal takes the node and judges connector_action before mocking; the six-map pin becomes seven (connector_action:connectorConfig.input, checked against FlowValueSlotSchema), the 19-entry ledger pin untouched; two new suites; changeset @object-ui/app-shell patch. Seat read of the diff.
  2. Premise measured: ablation reds 8 (dev); the order's premise (the judge was config-only, ['config','input'] unreachable) holds on main.
  3. Gates / check-runs: on head ac2e380a every latest check-run is success or skipped (44 / 11, 0 failure), mergeable_state clean. Dev: 35/35 derived gates exit 0, --ran 0 NOT-MEASURED (first runs of check:type-check-debt exit 3 lock queue and check:query-options-erasure exit 124 at the dev's cap, both re-run exit 0); 405 flow-designer files / 4763 tests; app-shell type-check 0 (os-dev-report 6538874579); writes relay 2, MCP 0.
  4. Accepted deviations: the full app-shell suite was left to CI (declared narrowing; CI green).
  5. Out of scope: none; StudioDesignSurface.tsx untouched, no i18n keys. Skills-docs: none — Metadata-protocol: none.
  6. Landing: check-governed-merges --pr 28312 NOT governed, 414 changed lines ≤ 3000; no contract review owed (Clause-②: no, no packages/spec path); changeset present. The seat readies it and arms auto-merge under the maintainer's 「按 pm-dispatch 审过的pr你可以自主落地」.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 31, 2026 04:30
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit 3d9175d Oct 31, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-ug538h branch October 31, 2026 05:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Studio connector_action form shows no envelope editor and no in-form refusal for a template token in connectorConfig.input

1 participant