Skip to content

Automations pillar: the rail groups flows by trigger object with a trigger-kind glyph and a status dot; the Enabled switch and the Trigger / Run as / version meta move into the item header; Variables / Runs / Problems / Debug become tabs #12454

Closed

Description

@objectstack-fleet

Source

Epic #12446, decisions 1, 3 and 5. Measured on objectui main a2225f91 at /studio/app.objectstack.hotcrm/automations: a full-width band "Off by default · review before enabling [switch] Enabled" above the rail; the rail lists 23 flows flat, each wrapping to two lines with "On" / "Not running here" at the right; the canvas column opens with a "Visual orchestration · click a node to configure" chip beside the flow name, then an info bar (Trigger / Status / Run as / v plus Variables, Runs, Problems, Debug buttons) inside a bordered card, then the canvas; the Configuration aside is w-72.

The maintainer asked for the rail to group by object (ruling quoted on the epic). The grouping key was measured in the hotcrm source: a record-triggered flow's start node config.objectName; a scheduled flow's first data node object (contract_renewal → crm_contract, opportunity_stagnation → crm_opportunity, forecast_snapshot → crm_forecast by what it writes); a screen flow's launching action object (campaign_enrollment → crm_campaign, schedule_followup → crm_lead); an autolaunched subflow's first data node (campaign_lead_member_enroll → crm_campaign_member). The 23 flows group into Account 2, Campaign 2, Campaign Member 2, Contact 1, Contract 2, Forecast 1, Lead 4, Opportunity 7, Quote 1, Task 1.

Target

  1. Rail (shared rail card): group headers in the object order the Data rail uses (alphabetical by label), each with its count; rows carry a 14 px trigger-kind glyph (bolt = record-triggered, clock = scheduled, pointer = screen, corner-arrow = autolaunched subflow), the truncating flow label, and a 6 px status dot (green = on, gray = not running here) whose title holds the status words. A legend row at the rail's foot explains the four glyphs and two dots. Grouping is computed client-side from the flow's own definition as served (start node object; first data node; the action that references the flow); a flow with no object lands in a trailing "No object" group. Search filters within groups.
  2. Item header row: a primary-soft tile with the automations glyph, the flow label at 18 px / 600, the api name as a mono chip, then "Trigger · screen", "Run as · user", "v1" as 12 px muted meta separated by dots; at the right the Enabled switch (36 by 20 px, green when on) with its label, whose title carries "Off by default · review before enabling", a divider, a more button. The full-width band retires.
  3. Tab row: Canvas, Variables, Runs, Problems (with an amber count pill when problems exist), Debug — underline tabs replacing the info-bar buttons; the Variables, Runs and Problems panels open as the tab's body (or as today's sheets, if their content cannot host inline; the card author decides and says which in the PR).
  4. Canvas: dotted-grid sidebar-tinted background; node cards 260 px wide, 8 px radius, a 28 px kind-colored tile (start green, screen pink, get-record blue, decision amber, loop violet, end gray), the label at 13 px / 600, the kind at 10 px uppercase with the object api name in mono; the selected node has the primary border and ring; a floating zoom control (−, percentage, +, fit) at the bottom right. Node layout and edges are the existing engine's; only the card styling changes.
  5. Configuration aside per the shared inspector card: eyebrow "Node · Decision", the node label, close; a decision node shows each outcome as a card with the target node name and its CEL condition in a mono textarea; "Add outcome" as a dashed button.

The flow-status truth (flowStatusTruth-11779), the enable toggle's refusal paths (authorRefusal-11785, heldIncomplete-11786), the canvas chip ruling (flowCanvasChip-11665: no literal flow token in the zh header; the api name on hover) and the narrow-row fold (narrowRow-11795) are all kept.

File surface

packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (AutomationsPillar: band, rail, canvas header, info bar, aside), FlowStatusDot, a small flowGrouping.ts for the object key with a unit test, packages/app-shell/src/views/metadata-admin/i18n.ts (group labels reuse object labels; new keys for the legend and the "No object" group).

Acceptance

  1. With HotCRM open the rail shows the ten groups and counts listed above, pinned by a unit test over the served flow definitions.
  2. The band is gone; the switch is in the item header and still toggles status with the same confirmation and refusal paths.
  3. Problems count shows as a pill on the tab; the four former info-bar buttons have no duplicate elsewhere.
  4. AutomationsPillar.*, FlowStatusDot.test.tsx, StudioDesignSurface.flowCanvasChip-11665, flowPresets-11861, newFlowTrigger-11788, packageLessFlows-11553 stay green or are updated in the same PR, each ablated once.
  5. Before/after screenshots at 1280 px, light and dark.

Constraints

  • Tailwind utilities and theme tokens only; no inline style.
  • Existing data-testids and i18n keys stay.
  • Gates: pnpm --filter @object-ui/app-shell test, lint, build.
  • Lands after the shared rail and inspector cards (the Blocked-by lines below).

Reference artboard

docs/design/studio-redesign/automations.html on objectui main (landed in #12458); automations.png is its 1280 px render. The folder's README carries the shared numbers and what a pull request against this card must show: two screenshots per artboard it touches (light and dark, 1280 px, cropped to the artboard's region), a deviation list with a reason per line, and the card's named tests green or updated. Where this card and the artboard disagree, this card's numbers win and the disagreement is reported here.

Blocked-by: #12459

Body refreshed 2026-10-15T09:53Z by the epic PM session: a Reference artboard section added now that #12458 is on main. Earlier refresh 2026-10-15T08:17Z: the Blocked-by line now names the layout skeleton card #12459, which supersedes #12447, #12448 and #12449.

Parent: #12446

Activity

  1. added
    enhancementNew feature or request
    pm:epicParent delegated to a dedicated epic PM — other PMs never dispatch into its subtree
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Oct 15, 2026
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (epic #12446 subtree)
    Session: session_01SJn1GEkrbbBQkhGC26wEDw
    Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-12454-automations-pillar-layout
    Worktree: objectui-issue-12454
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (region: AutomationsPillar and FlowStatusDot only), new studio-design/flowGrouping.ts and its unit test, presentation-only edits to packages/app-shell/src/views/metadata-admin/previews/FlowPreview.tsx, FlowCanvas.tsx, FlowRunsPanel.tsx, ProblemsPanel.tsx and metadata-admin/inspectors/FlowNodeInspector.tsx (on cf430cd the info bar, node cards and node aside live there, not in the pillar), StudioRail.tsx (additive only, if a needed slot is missing), packages/app-shell/src/views/metadata-admin/i18n.ts (new engine.studio.auto.* keys), the screenshots under docs/design/studio-redesign/after/ named 12454-*.png (the light and dark pairs the reference README asks for, filed as the skeleton PR filed its own), one .changeset/12454-*.md (stop on breach; explain in the report)
    Container & model: L, mode:subagent, model: opus
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: none
    Serial constraints cleared: objectui#12459 merged as PR objectui#12460 (cf430cd), which put the Enabled switch and the off-by-default sentence in the item header. In flight on the same file at claim time: objectui#12450 (DataPillar) and objectui#12452 (shell header nav), both this seat, regions disjoint from AutomationsPillar. objectui#12442 (seat 2) touches metadata-admin/previews/PagePreview.tsx, not the flow previews. No other open PR touches studio-design/ or the flow previews (3 open PRs read).

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12454,
    "status": "done",
    "branch": "claude/issue-12454-automations-pillar-layout",
    "pr": "#12481",
    "session": "session_01SJn1GEkrbbBQkhGC26wEDw",
    "premise_still_valid": true,
    "summary": "The Automations rail groups flows by object (new pure studio-design/flowGrouping.ts). Each group has a count and folds, and a search filters within groups. Rows carry a 14 px trigger glyph, a one-line label (the row title holds the whole label, the trigger kind and the status words) and a 6 px status dot; a legend sits in the rail footer. The item header carries Trigger, Status, Run as and version through one FlowMetaPills component shared with the designer's info bar, plus the Enabled switch, whose title begins with the off-by-default sentence. A Canvas / Variables / Runs / Problems (count pill) / Debug tab row replaces the info-bar buttons. Variables, Runs and Problems open as the tab body; Debug keeps the canvas beside the simulator. The canvas sits flush on the sidebar surface with a 20 px dot grid and the zoom control at the bottom right. The Studio look is scoped by FlowPreviewChromeProvider, so the metadata-admin designer keeps its info bar (checked with the verify skill's gallery). Measured on hotcrm 63db83e: 26 flows (not 23) in the card's ten groups, with Contract, Opportunity and Task each one higher. Screen flows name their object on the Start node, so no action metadata is read. Forecast Snapshot groups by the record it writes. Gap, held by the claim's file surface: node-card styling (NodeCard in flow-canvas-parts.tsx) and the aside restyle (InspectorShell in _shared.tsx, outcomes in FlowObjectListField.tsx) were not done; they are deviations 6 and 7 in the PR.",
    "tests": "All at HEAD 1de2c1d (each vitest run went through os-verify-lock). (1) pnpm exec vitest run --maxWorkers=2 over the 30 studio-design files that reach the pillar, rail, FlowStatusDot or flow previews, including flowGrouping.test.ts and the new AutomationsPillar.tabs-12454.test.tsx: Test Files 30 passed (30), Tests 273 passed (273). (2) The 28 metadata-admin flow preview, canvas and runs files, plus the other files naming the pillar or previews: Test Files 28 passed (28), Tests 409 passed (409). (3) Ablation at af28632 through objectstack scripts/ablation-replace.mjs: each anchor hit once, each mutation was verified on disk, and each file was restored to HEAD's blob with git diff HEAD empty. Ten legs, all red: grouping write step, flowGrouping 3 failed; dot status words, FlowStatusDot 6 failed; search within groups, railSearch-11794 3 failed; row title, railSearch plus tabs-12454 2 failed; header canvas hint, flowCanvasChip-11665 plus packageLessFlows-11553 4 failed; meta Status caption, narrowRow-11795 plus flowStatusTruth-11779 12 failed; refusal strip, authorRefusal-11785 3 failed; held notice, heldIncomplete-11786 2 failed; Start-node trigger write, newFlowTrigger-11788 plus flowPresets-11861 7 failed; Problems count pill, tabs-12454 1 failed. Tree clean afterwards. No build was needed: the tests import source.",
    "gates": "Local, at HEAD 1de2c1d; each exit code was captured before any pipe. pnpm --filter @object-ui/app-shell run type-check: VERDICT command-exit 0 (the script name echoed as type-check). pnpm --filter @object-ui/app-shell run build: exit 0, dist completeness 1094 files. eslint --no-inline-config on the 8 touched source files: LINT-EXIT=0, 0 errors and 19 warnings. Compared with eslint on the cf430cd bytes of the same files, StudioDesignSurface gains one react-hooks/preserve-manual-memoization warning and FlowPreview loses one no-explicit-any. node scripts/check-changeset-presence.mjs exit 0. pnpm check:i18n-keys exit 0. pnpm check:i18n-drift exit 0. pnpm check:i18n-designer-parity exit 0. pnpm check:i18n-dead-keys exit 0 (no auto or flowPreview key reported). pnpm check:new-line-citations exit 0. node scripts/check-changeset-no-major.mjs exit 0. node scripts/check-governed-queue-guard.mjs --test on the 11 paths: NOT GOVERNED. Dependency closure: turbo build --filter '@object-ui/app-shell^...' gave 28 of 28 successful, all cached. objectui has no dispatch-gates --ran reconciliation; the list above is derived by hand from objectui's package.json. CI check-runs on 1de2c1d at 11:25Z: 36 total. Completed success: Build Docs, Changeset Fixed Group Check, Changeset Bump Policy, label. Completed skipped: Test (coverage), dependabot, the coverage-shard placeholder. in_progress: Lint, Type Check, Test (shard 1/16 to 16/16), Test (dist pins), Build & E2E, Changeset Declaration, Changeset Overwrite Report, Changeset Claim Re-read, Repo Gates, Governed Surface Queue Guard, Spec Main Shape Gate, Line Citation Gate, Bundle Analysis, Live E2E (informational). CI convergence is the PM's.",
    "mcp_calls": "0",
    "api_writes": "2 relay strokes. (1) pr_create: POST /repos/objectstack-ai/objectui/pulls (draft) then POST /repos//issues/12481/assignees [os-sales], dispatched as POST /repos/objectstack-ai/objectstack/dispatches, run 38727065884, read-back identical at 12113 bytes. (2) This report: POST /repos//issues/12454/comments through post-stamped. Zero label writes. git push is not counted as a REST write.",
    "deviations": [
    "file surface: AutomationsPillar.railSearch-11794.test.tsx updated (the card names AutomationsPillar.* stay-green-or-update) and AutomationsPillar.tabs-12454.test.tsx added (pins acceptance 3). Both are outside the claim's literal list. flow-canvas-parts.tsx, inspectors/_shared.tsx and FlowObjectListField.tsx were NOT edited (stop on breach), so the target 4 node-card styling and the target 5 aside restyle are not done.",
    "artboard shows an api chip; not rendered because flowCanvasChip-11665 pins the API name to the tooltip (objectui#11665). The pin file is byte-identical to origin/main and green.",
    "the header meta keeps the 'Label:' captions and adds Status (Trigger: screen · Status: On · Run as: user · v1). Seven pinned tests read the header's Status: pill by text, and objectui#11779 keeps header, rail and Problems on one run status.",
    "no divider and no more button: the pillar has no flow action to put behind it.",
    "group-header chevron after the count, as the shared StudioRailGroup draws it; StudioRail.tsx is untouched.",
    "the legend is in the rail's pinned footer slot, says 'Autolaunched' for the corner arrow (the artboard says 'Subflow'), and lists Off and Refused only while some row reads so.",
    "'Add node' stays at the canvas top right while editable; the Problems pill takes the destructive tint when an error is among the problems.",
    "reverses the objectui#11794 wrapping label, as the card's truncating label asks; the whole name moved to the row title.",
    "the off-by-default sentence is the switch's title (first line) plus a visually hidden line. It is not wired as aria-describedby: the switch's description stays the objectui#12303 read-only reason, left as is for objectui#12453.",
    "the canvas hint moved off-screen: a visually hidden line in the header row, which also describes the Canvas tab, plus that tab's title.",
    "PM mechanism assumptions: 1 confirmed; 2 partly falsified (node cards are NodeCard in flow-canvas-parts.tsx); 3 partly falsified (aside header is InspectorShell in _shared.tsx, outcomes are FlowObjectListField); 4 confirmed; 5 falsified in the lighter direction (Start-node objectName covers every HotCRM screen flow, so no action read).",
    "the card's 23 flows are 26 on hotcrm 63db83e; the ten groups stand, and Contract, Opportunity and Task are each one higher."
    ],
    "files_changed": [
    ".changeset/12454-automations-pillar-layout.md",
    "docs/design/studio-redesign/after/12454-automations-dark.png",
    "docs/design/studio-redesign/after/12454-automations-light.png",
    "packages/app-shell/src/views/metadata-admin/i18n.ts",
    "packages/app-shell/src/views/metadata-admin/previews/FlowCanvas.tsx",
    "packages/app-shell/src/views/metadata-admin/previews/FlowPreview.tsx",
    "packages/app-shell/src/views/studio-design/AutomationsPillar.railSearch-11794.test.tsx",
    "packages/app-shell/src/views/studio-design/AutomationsPillar.tabs-12454.test.tsx",
    "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
    "packages/app-shell/src/views/studio-design/flowGrouping.test.ts",
    "packages/app-shell/src/views/studio-design/flowGrouping.ts"
    ],
    "line_budget": "n/a: no skills/** surface",
    "open_questions": [
    {
    "question": "Targets 4 (node cards: 8 px radius, 28 px tile, blue get-record, violet loop, grey end, humanised kind word) and 5 (aside: one 'Node · Decision' header, outcome cards with a CEL textarea, dashed 'Add outcome') live in files outside this claim's surface: metadata-admin/previews/flow-canvas-parts.tsx, metadata-admin/inspectors/_shared.tsx and metadata-admin/inspectors/FlowObjectListField.tsx. How should they land?",
    "options": [
    "A: a patch round on this PR, with the claim's file surface extended to those three files (presentation only; the aside needs an InspectorShell variant that drops its own header under the Studio inspector)",
    "B: a follow-up card in the epic subtree, after this PR merges",
    "C: leave them as listed deviations"
    ],
    "recommendation": "B, because the inspector shell and the object-list field are shared by every metadata inspector and need their own blast-radius review; A is fine for the node cards alone (one file, presentation only)."
    }
    ],
    "out_of_scope_findings": [
    "carrier: none — noted, not filed (observation): HotCRM decision nodes route by out-edge conditions, so the decision inspector's Branches table reads 'No items yet' while the canvas shows two conditioned branches. This is the inspector's two-mechanism design, not shown to be a defect. Dedupe words: decision branches no items yet edge conditions inspector.",
    "carrier: none — noted, not filed (observation): StudioDesignSurface already carried React Compiler preserve-manual-memoization skips at cf430cd (the compiler skips the component). One more is now reported at doCreateFlow; removing this branch's line there does not clear it, and its cause was not found."
    ]
    }

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 12454,
     "status": "done",
     "branch": "claude/issue-12454-automations-pillar-layout",
     "pr": "https://github.com/objectstack-ai/objectui/pull/12481",
     "session": "session_01SCz2zoDR7YzaAc82kFEYPx (cloud continuation of claim 6189041643, seat domain:ui#4 session_01SJn1GEkrbbBQkhGC26wEDw)",
     "round": "patch round 1 (REWORK 6192072808)",
     "premise_still_valid": true,
     "summary": "flowGrouping.ts no longer constructs a collator with the machine locale: the fallback `new Intl.Collator(undefined, ...)` is gone, GroupFlowsOptions.locale is required, and groupFlowsByObject builds `new Intl.Collator(locale, { sensitivity: 'base' })` from the locale the pillar hands in (useMetadataLocale(), already threaded at the call site). flowGrouping.test.ts pins locale-sensitive order (安装 / 保单: zh-CN pinyin vs en-US code point). Fix commit 21397be; origin/main merged as 2c87994 because git merge-tree reported an import-block conflict in StudioDesignSurface.tsx.",
     "tests": "Census machineLocaleCensus-9909: red on 1de2c1d (1 failed | 6 passed, offender flowGrouping.ts:150), green on 21397be and on 2c87994 (7 passed). flowGrouping + AutomationsPillar.* + flowCanvasChip-11665 + DataPillar.*: 24 files / 112 tests passed at 2c87994; the other 75 StudioDesignSurface.*.test.tsx: 38 files/187 tests and 37 files/323 tests passed.",
     "gates": "At 2c87994: app-shell dependency-closure build exit 0; app-shell type-check exit 0; eslint on the three touched files exit 0 (0 errors); check-changeset-presence exit 0. CI was in progress at report time.",
     "files_changed": [
      "packages/app-shell/src/views/studio-design/flowGrouping.ts",
      "packages/app-shell/src/views/studio-design/flowGrouping.test.ts",
      "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (merge resolution, import block only)"
     ],
     "deviations": [
      "Merged origin/main (2c87994) on a measured merge-tree conflict; no rebase, no force-push.",
      "The collation locale is useMetadataLocale() (the label locale), not useDisplayLocale().",
      "The cloud session's relay write answered 403 (repository_dispatch not permitted for its session type); the seat relays this report."
     ],
     "api_writes": "0 landed; 1 attempted (relay comment) refused 403.",
     "mcp_calls": "1 GitHub read (pull_request_read get_comments); claude-code-remote add_repo (read-only). No write tools.",
     "open_questions": [],
     "out_of_scope_findings": []
    }

    Relayed verbatim in substance by seat domain:ui#4 from the cloud session's final message (2026-10-15T13:26Z), because that session's relay write was refused (403).


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #12481 comment 6193278289 (head 6f07ae0, read 2026-10-15T13:31Z), after REWORK 6192072808 and two patch rounds. Targets 4 and 5 are carried by #12488.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portaldomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpm:epicParent delegated to a dedicated epic PM — other PMs never dispatch into its subtreepriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions