Skip to content

fix(app-shell): Studio's action editor keeps a new field-value row, and stores a script action's type - #26877

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/project-thread-infmae
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/project-thread-infmae

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread

Fixes #26735
Fixes #26734

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Studio 的动作编辑器(数据 › 对象 › 操作)两处修正。「更新字段」动作点「添加字段值」现在立刻出现一行,在填上字段名之前只留在编辑器里,填上后才写进 patch;「运行脚本」动作现在在作者切换到运行脚本、编辑脚本体或语言、填字段值时写入 type: 'script',「类型」下拉只显示动作真正存有的类型,没有时显示「—」。
  • 为什么改:以前「添加字段值」写进一个空键的行,空键被丢掉,行不出现,patch 永远是 {};「运行脚本」动作存下来没有 type,下拉却显示 Script,控制台读到无类型的动作什么都不执行。两种动作在 Studio 里做出来发布后都点了没反应。
  • 风险与回滚:低。不改规范、不改服务端、不加文案;只改设计器的写法。已有 type 的动作写法与以前完全一样。回滚即 revert 本 PR。
  • 先看:ActionDefaultInspector.tsx 里的 withScriptType 与 commitFieldValueRows;ActionDefaultInspector.scriptBodyLanguage-11921.test.tsx 里改成带 type 的两条期望。
  • 两分钟验证:在 Studio 某对象的「操作」里新建动作,点「添加字段值」,预期立刻出现一行;填字段 status、值 done,预期草稿的 patch 为 { status: 'done' } 且带 type: 'script'。
  • 需要你做的:无,席位落地。

What changes

ActionDefaultInspector (Studio › Data › an object › Actions), two writes:

  • Field values (Studio Data › Actions: "Add field value" adds no row, so an update action's patch cannot be authored in Studio (the published action is a no-op) #26735). "Add field value" committed ['', ''], and the patch writer drops every blank key, so no row appeared and an update action's patch stayed {}. The rows on screen are now a list held in the inspector: a row is written to patch once it names a field, and a row that names none (just added, or its field cleared) is held there and never written. The held list is stamped with the action, like the Body Shape Wrap choice, and is read only while its named rows equal the draft's patch; any other write to patch shows the draft's rows. Rows stay keyed by position, so a held row that gains its field keeps its inputs and the focus.
  • Script type (Studio Data › Actions: a "Run a script" action is saved without type, so the console treats it as not executable — clicking it sends no request #26734). The Type control showed str('type') || 'script', so a draft with no type read Script while nothing committed it. A "Run a script" action made from New (whose skeleton leaves type to the spec) was stored without one, and the console runs nothing for an action without type. The Type control now shows only a stored type ("—" when there is none), and withScriptType adds type: 'script' to every write that authors a script on a draft that holds no type: the "What it does" switch in both directions (the update direction already wrote it), each body edit, a language change and a field-value write. The Behavior panels still follow the spec's default route (ActionSchema.type defaults to script), so the editor for what the action runs stays on screen. A draft that already holds a type is written exactly as before.

No packages/spec change, no server change, no new string, no runtime fallback for an action without type.

Tests

  • ActionDefaultInspector.fieldValueRows-26735.test.tsx (new, 5 cases): from the New skeleton, Add shows a row and writes nothing; Field status writes patch: { status: '' } with the same input element; Value done writes { status: 'done' } and the draft parses with ActionSchema. A cleared field keeps the row on screen and takes it out of patch; removing a held row writes nothing; another write to patch shows the draft's rows; a typed action is written with patch alone.
  • ActionDefaultInspector.scriptType-26734.test.tsx (new, 6 cases): New → "Run a script" → a body stores type: 'script' and parses; a stored script with no type shows none in Type and its first body edit stores it; the first field value from New stores it; the spec gives a draft with no type the script route; controls: a typed script action's body and language writes carry no type, and an api action shows API.
  • ActionDefaultInspector.scriptBodyLanguage-11921.test.tsx: the two pins of the "Run a script" switch from the typeless New skeleton now expect type: 'script' in the write. They pinned exactly the write Studio Data › Actions: a "Run a script" action is saved without type, so the console treats it as not executable — clicking it sends no request #26734 reports.
  • Main-tree check (one-off, not kept): with the fix committed, the inspector was replaced by its origin/main blob (commitFieldValueRows count 1 → 0 on disk) and the two new files ran red, Tests 8 failed, 3 passed (11): every case except the two typed-action controls and the spec reading. Restored with git checkout HEAD, git diff HEAD empty.

Acceptance notes

  • "—" in the pinned Type control on the New skeleton. New's update skeleton (ObjectActionsPanel, outside this card's file surface) leaves type off on purpose, and its pin newActionPin asserts that. Until the author's first edit, the pinned Type control on that skeleton reads "—" beside the "Pinned to script" hint. The first field value or "What it does" switch stores type. Seeding type: 'script' in the skeleton would close that window; it is a change to ObjectActionsPanel and its pin, so it is left as an open question in the report.
  • Stored rows without type. The spec declares type with a script default, and the console reads the stored row, not its parse, so it treats any stored action without type as not executable. This PR stops Studio from writing new ones; it does not change the runtime, by the card's order.

Verification

All readings at head a9ea1105 (base e9e344a9), under scripts/pm/os-verify-lock.sh.

Touched package: @object-ui/app-shell
  • Dependency closure: pnpm exec turbo run build --filter='@object-ui/app-shell^...' plus formula, sdui-parser, lint and client, 63 tasks successful, VERDICT command-exit 0.
  • Type-check: pnpm exec turbo run type-check --filter=@object-ui/app-shell --concurrency=2, 64 tasks successful (app-shell's own task a cache miss, executed: tsc --noEmit and tsc -p tsconfig.test.json), VERDICT command-exit 0.
  • The two new test files: Test Files 2 passed (2), Tests 11 passed (11).
  • Narrowed app-shell run: every test file naming ActionDefaultInspector or ObjectActionsPanel (26 files). First run: Tests 2 failed, 224 passed (226), the two scriptBodyLanguage-11921 pins of the typeless switch's write, updated above. That file re-run: Tests 13 passed (13). The rest of app-shell is left to CI's Test UI shards.
  • ESLint with ui/eslint.config.js on the four touched files: exit 0, no output.
Derived gates
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 34 commands for the 5 changed paths; all 34 exit 0, each code captured before any pipe, among them check:nul-bytes, check:test-source-alias, check:cross-package-test-inputs, check:type-check-coverage, check:type-check-debt, check-sdui-manifest, check-empty-changeset, check-changeset-no-major and check-closing-keyword-parity (with this body as the event). pnpm --dir ui exec vitest run scripts/: Test Files 178 passed, 2 skipped (180), Tests 5065 passed, 2 skipped.
  • --ran reconciled: "34 derived famil(ies) accounted for — 34 run, 0 NOT-MEASURED".
  • pnpm --dir ui run check:new-line-citations: 0 new cross-file line-address citations.
  • Families CI runs over the whole tree (type-check lanes, lint, artifact rosters) are CI's; the PR's check-runs are the reading.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes. (lint is CI's)
  • 4. One issue, one branch off an up-to-date main, one pull request. (two cards on one inspector, bundled by the seat's claim)
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (not touched)
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QsR2jVG55iUTTWRd5tR6Di


Generated by Claude Code

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat note · domain:ui#4 · 2026-10-27T19:53Z

Test UI (9/16) on 5c79e064 is red on ResourceEditPage.discardDraftLabel-12690.test.tsx:171 (Unable to find an accessible element with the role "button" and name "丢弃草稿"). The red is not from this PR, which touches neither that page nor its strings. It is the lazy studio zh catalogue race that #26815 opened: the test reads a zh label before the catalogue loads. The same race reds PackageFormDialog.validationTiming on main. It is filed as #26863, and its fix is in flight, with this file named in its sweep. No fix exists on main yet. The seat re-runs the failed jobs once after the run completes.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · seat domain:ui#4 · session_01QsR2jTfvjNTaR29ehLk26T · 2026-10-27T20:05Z · head 5c79e064404a25c16e63e2de8a83db0152a357b6

  1. Shape: draft, base main, closes both cards: Fixes #26735 and Fixes #26734. Clause-②: no and Metadata-protocol: none match the claims (6450996132, 6451025473), in the body and in the changeset (@object-ui/app-shell patch). Five files, all inside the surface: ActionDefaultInspector.tsx, two new tests beside it, two expectations in scriptBodyLanguage-11921.test.tsx that now carry type: 'script', and one root changeset. No i18n row was needed. No packages/spec/**, server, or new key.
  2. Premise, measured: the seat read the diff.
  3. Gates, pinned to the head: 52 check-runs on the head: 43 success, 9 skipped, 0 failure, 0 pending (Test UI 9/16 passed on its one re-run after the app-shell: PackageFormDialog.validationTiming test reads the zh label before the lazy studio catalogue loads, and fails intermittently since #26815 #26863 race, seat note 6452081154). · check-governed-merges --pr 26877: NOT governed, 0 of 5 paths hit the register (407 changed lines). mergeable_state: clean.
  4. Accepted deviations:
    • two scriptBodyLanguage-11921 expectations change: the switch to "Run a script" now also writes type: 'script', which is this card's fix;
    • the main-tree check was a blob grep, not an ablation (8 of the 11 new cases are red on main's blob);
    • the local app-shell run was narrowed to 26 inspector/panel files; CI's Test UI shards are the reading;
    • the seat's review asked for one fix at a9ea1105: a moved doc comment, put back on SCRIPT_OPERATIONS in 5c79e064.
  5. Out of scope: the thread's open question (seed type in New's update skeleton) and its class-b finding (the console refuses a stored typeless action, though the spec defaults type to script) are filed as console: a stored action without type does not run, though the spec defaults type to script; New's update skeleton and older Studio rows are stored that way #26879. Skills-docs: is not owed.
  6. Prose face, checked sentence by sentence against the diff: each changeset claim matches a hunk and a test:
    • a new field-value row appears at once and is held until it names a field; a cleared row stays on screen, held, and leaves patch; a row without a field is never written;
    • every script-authoring edit stores type: 'script' on an action that has none; the Type control shows "—" until then; a typed action is written exactly as before.

Landing: no contract review is owed (no published schema, no governed text, Clause-②: no). The seat marks the PR ready and arms auto-merge. On MERGED, Fixes #26735 and Fixes #26734 close both cards.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 20:06
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 20:06
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 2720874 Oct 27, 2026
82 of 84 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-infmae branch October 27, 2026 20:42
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 tooling

Projects

None yet

2 participants