Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Studio Automations: on a read-only package, clicking a flow canvas node opens no inspector, so packaged flows' node configuration cannot be read (moved from objectstack-ai/objectstack#21575) #11546

Closed

Description

@objectstack-fleet

Filed by the triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015, session_01AavokzJ5DndAwitDXvKy4U). It moves objectstack-ai/objectstack#21575 here, where the fix lands. That card was filed by objectstack's domain:services seat 2 from the objectstack-ai/objectstack#12438 acceptance run. ⛔ Not a claim, ⛔ not a dispatch.

Graded here: bug · priority:p3 · domain:ui · area:studio · pm:queue.

Measured (objectstack main a3873542ca, console built at the pinned .objectui-sha 89cad75d5570, stock showcase)

  • In Studio → Automations on a read-only package (com.example.showcase), clicking any node on a flow canvas opens no inspector. The panel keeps its empty state.
  • It reproduced with two click methods, in two fresh browser contexts, across 30/30 showcase flows.
  • Positive control: the same click on an editable canvas (the Setup metadata-admin designer) opens the node inspector.

Why

objectui#11124 fixed the earlier read-only defect, where the inspector opened with editable inputs. Its comment in StudioDesignSurface.tsx promises that "node and edge selection still open the inspector read-only below". Selection now opens nothing, so an administrator cannot read a packaged flow's node configuration in Studio.

Where (read at origin/main)

packages/app-shell/src/views/metadata-admin/previews/FlowCanvas.tsx:

  • onNodePointerDown (about :408) returns early when the canvas is not editable, before e.stopPropagation();
  • the background's onBgPointerDown (about :457) then clears the selection.

Ruling

  • On a read-only canvas a node click selects. Only the drag is withheld. The selection then opens the inspector read-only, as objectui#11124 promised.
  • ⛔ No editable input appears. That would bring back objectui#11124's defect.
  • Pins:
    • a read-only canvas: a node click opens the read-only inspector;
    • the editable designer: drag and select as before;
    • objectui#11124's read-only-inputs pin stays green.

Why p3. A read surface is missing. Nothing is written and no lock is breached.

Not this card: objectstack-ai/objectstack#21332 (a cloned flow reaches no Studio surface), which is a different mechanism.

Activity

  1. added
    bugSomething isn't working
    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 3, 2026
  2. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8
    Session: session_01FjqrwXPfSMkSfkKYDSRkN2
    Account: os-zhuang (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-11546-readonly-canvas-select
    Worktree: objectui-issue-11546
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: the card body's ruling (filed by triage from objectstack-ai/objectstack#21575), read at objectui origin/main 2e818d0 as leads:

    • packages/app-shell/src/views/metadata-admin/previews/FlowCanvas.tsx (onNodePointerDown, about :408): on a read-only canvas a node click stops propagation and selects; only the drag is withheld;
    • packages/app-shell/src/views/StudioDesignSurface.tsx only if the selection does not already open the read-only inspector there;
    • new pins (read-only click opens the read-only inspector; the editable designer unchanged; objectui#11124's read-only-inputs pin green); one @object-ui/app-shell patch changeset.

    The dev stops on a breach and explains it in the report.
    Container & model: M, mode:subagent, model: opus (default judgment tier; dispatch-gates --tier --repo objectstack-ai/objectui printed "no path-derived mandate" for these paths)
    Clause-②: no
    Why: a read-only canvas regains selection; no editable input, schema, type or accept set moves.
    Thread-read: none
    Serial constraints cleared: read 2026-10-04T07:57Z.

    • No open PR touches FlowCanvas.tsx or StudioDesignSurface.tsx. objectui#10202 (hotlong, in flight) holds the Studio picklist page under views/metadata-admin/** and ObjectFieldInspector.tsx; this card does not edit them. objectui#11591 (Studio copy, StudioDesignSurface.tsx) is queued behind this card.
    • This seat's in flight: objectui#11577 (packages/plugin-detail) and objectui#11569 (packages/plugin-form) are claimed in this act, with disjoint files.
    • Scope: the maintainer opened p3 work on 2026-10-04 (「可以开始处理 p3 的任务了」).

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 11546,
      "status": "done",
      "branch": "claude/issue-11546-readonly-canvas-select",
      "pr": "https://github.com/objectstack-ai/objectui/pull/11603",
      "session": "session_01FjqrwXPfSMkSfkKYDSRkN2 — mode:subagent run of the PM session (identity = the claim branch)",
      "premise_still_valid": true,
      "summary": "Card premise reproduced in real Chromium at base 2e818d0. A scratch harness (untracked, deleted) mounted the registered FlowPreview the way the read-only Automations pillar mounts it, plus FlowInspector readOnly. On a read-only node, page.click and mouse down/up both left the selection none and opened no inspector. Event probe: pointerdown hit the node card; gotpointercapture, pointerup and click went to the viewport (role=application). Mechanism: FlowCanvas onNodePointerDown returned before e.stopPropagation(), so onBgPointerDown ran onSelect(null) and captured the pointer, and the browser fired the click at the viewport. Fix: in FlowCanvas onNodePointerDown, a design-mode press now stops propagation on a read-only canvas too, and only the drag start stays gated on editable. The Delete-key handler is unchanged (editable-gated). Outside design mode a node press still falls through to the pan, as before. With the fix: a read-only click selects node:find and the inspector shows 7 inputs, 0 enabled; the read-only drag still moves nothing; the editable designer selects and drags as before. StudioDesignSurface.tsx needed no change: selection already opened the inspector with the pillar's readOnly flag. Edges are a different mechanism: the edge hit-path and label pill stop propagation unconditionally when selectable, and a read-only edge click selected the edge at base already (3 inputs, 0 enabled). Nothing was changed there. objectui#11124's pins missed this because they fireEvent.click the node with no press, and happy-dom routes no event by pointer capture. The new __tests__/browserClick helper routes pointerup and click to the capturing element, as a browser does. Draft PR objectui#11603, assignee os-zhuang (read back).",
      "tests": "All at HEAD c47b708. (1) Chromium harness, base vs fix: ro node click none→node:find (7 inputs/0 enabled); ro mouse down/up none→node:find; ro drag not moved both; ro edge click edge:e_start_find both; editable click/drag unchanged (7 enabled / moved). (2) Pins: new StudioDesignSurface.automationsReadOnlySelect-11546.test.tsx (read-only: Label+ID disabled, no enabled input/textarea/select/contenteditable/combobox/switch/checkbox in the rail, no save; writable control: Label enabled, enabled-control count over 0) and a new FlowCanvas.test.tsx describe (ro click → onSelect calls exactly ['b']; ro drag captures nothing, writes nothing, pans nothing; editable click+drag control; non-design press still pans). objectui#11124's 'opens the flow inspector read-only: the node inputs are disabled' is untouched and green. (3) Ablation via objectstack scripts/ablation-replace.mjs under the lock: the fixed three lines were replaced by the base order (early return above stopPropagation), anchor 1→0, blob 82501d693e1d→95126d94e35d. Expected direction red was observed: 'Tests 3 failed | 29 passed (32)'. Red: host read-only pin (Label never appears), canvas ro click ('expected [ null ] to deeply equal [ 'b' ]'), canvas ro drag (viewport captured). All objectui#11124 pins green under the defect. Restore: blob == HEAD 82501d693e1d58384729c3cf61f9c29284399a98 and git diff HEAD empty. The subject resolves from src (relative imports), so no dist was on the path. (4) Narrowed vitest (lock): packages/app-shell/src/views/metadata-admin/ + studio-design/ + spec-symbol-parity + apps/console registry-inputs-spec-parity + scripts/__tests__ markdown-test-inputs / one-authority-per-exported-name-6273 / check-lucide-icon-record-names → 'Test Files 472 passed (472)', 'Tests 5352 passed | 1 skipped (5353)', VERDICT command-exit 0. Selection: imports of FlowCanvas/flow-canvas-parts/browserClick plus readFileSync/?raw readers naming the previews path. (5) CI at report time: 42 check runs on c47b708, 24 completed with 0 failure, 18 in_progress.",
      "mcp_calls": "0",
      "api_writes": "3 — each one POST /repos/objectstack-ai/objectstack/dispatches through the fleet-write relay (scripts/pm tools, executed as objectstack-fleet[bot]): pr_create → POST /repos/objectstack-ai/objectui/pulls (objectui#11603, body read back byte-identical 9706/9706); label-write assign → POST /repos/objectstack-ai/objectui/issues/11603/assignees (os-zhuang, read back MATCHES); post-stamped → POST /repos/objectstack-ai/objectui/issues/11546/comments (this report). Not REST: 2 git pushes of the branch (empty branch, then c47b708).",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: 承接者:无 · noted, not filed — a react-hooks/exhaustive-deps warning on FlowCanvas addNode useCallback (unnecessary positionOf dependency), identical at base 2e818d0 (polish; in the PR Acceptance notes)"
      ],
      "gates": [
        {
          "command": "pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build (lock)",
          "exit": 0,
          "verdict": "Scope: 29 of 47 workspace projects · os-verify-lock VERDICT command-exit 0"
        },
        {
          "command": "pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json) (lock)",
          "exit": 0,
          "verdict": "silent tsc; the && chain reached tsc -p tsconfig.test.json --listFilesOnly, which listed the helper and both pin files (3)"
        },
        {
          "command": "pnpm exec vitest run --maxWorkers=2 (narrowed set above) (lock)",
          "exit": 0,
          "verdict": "Test Files 472 passed (472) · Tests 5352 passed | 1 skipped (5353)"
        },
        {
          "command": "ablation-replace.mjs wrapping vitest on the 3 pin files (lock)",
          "exit": 1,
          "verdict": "Tests 3 failed | 29 passed (32) under the mutation (expected red); ok restored: blob == HEAD (82501d693e1d), git diff HEAD empty"
        },
        {
          "command": "pnpm --filter @object-ui/app-shell build + dist probe (lock)",
          "exit": 0,
          "verdict": "dist FlowCanvas.js 1 (positive control, carries the fix comment); browserClick* 0; __tests__ paths 0; *11546* 0"
        },
        {
          "command": "node scripts/check-control-bytes.mjs",
          "exit": 0,
          "verdict": "check-control-bytes: OK (scanned 7497 tracked text file(s); skipped 85 binary)"
        },
        {
          "command": "node scripts/check-new-cross-file-line-citations.mjs",
          "exit": 0,
          "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0"
        },
        {
          "command": "node scripts/check-changeset-presence.mjs",
          "exit": 0,
          "verdict": "1 changeset(s) added; 4 source file(s) of 1 released package"
        },
        {
          "command": "node scripts/check-changeset-claims.mjs",
          "exit": 0,
          "verdict": "No pending changeset names a file this change touches."
        },
        {
          "command": "node scripts/check-pending-changeset-literals.mjs",
          "exit": 0,
          "verdict": "No test source names a pending changeset."
        },
        {
          "command": "node scripts/check-changeset-no-major.mjs",
          "exit": 0,
          "verdict": "No changeset declares a `major` bump."
        },
        {
          "command": "node scripts/check-changeset-overwrite.mjs",
          "exit": 0,
          "verdict": "No pre-existing changeset was modified or deleted."
        },
        {
          "command": "node scripts/check-vi-mock-specifiers.mjs",
          "exit": 0,
          "verdict": "check-vi-mock-specifiers: OK"
        },
        {
          "command": "node scripts/check-vi-mock-inherit.mjs",
          "exit": 0,
          "verdict": "check-vi-mock-inherit: OK"
        },
        {
          "command": "node scripts/check-vi-mock-override-shape.mjs",
          "exit": 0,
          "verdict": "check-vi-mock-override-shape: OK"
        },
        {
          "command": "node scripts/check-test-path-roots.mjs",
          "exit": 0,
          "verdict": "check-test-path-roots: OK"
        },
        {
          "command": "node scripts/check-phantom-dependencies.mjs",
          "exit": 0,
          "verdict": "Every in-scope import declared (exit 0)"
        },
        {
          "command": "node scripts/check-published-tsconfig-tooling-exclude.mjs",
          "exit": 0,
          "verdict": "OK -- all 34 enforced package(s) carry the directory form"
        },
        {
          "command": "npx eslint --format json (4 changed ts/tsx files, from packages/app-shell)",
          "exit": 0,
          "verdict": "4 files, 0 errors, 1 warning (pre-existing at base, same place); proven narrowing: population = eslint config (changeset .md: File ignored because no matching configuration), count from JSON, invariance = no parserOptions.project/projectService and no eslint-rules/ file reads"
        },
        {
          "command": "pnpm check:published-dist / full pnpm test / pnpm lint",
          "exit": null,
          "verdict": "NOT MEASURED: repository-wide runs owned by CI (published-dist builds the whole workspace); the narrowed dist probe covers this diff"
        }
      ],
      "files_changed": [
        "packages/app-shell/src/views/metadata-admin/previews/FlowCanvas.tsx",
        "packages/app-shell/src/views/metadata-admin/previews/FlowCanvas.test.tsx",
        "packages/app-shell/src/views/metadata-admin/previews/__tests__/browserClick.ts",
        "packages/app-shell/src/views/studio-design/StudioDesignSurface.automationsReadOnlySelect-11546.test.tsx",
        ".changeset/11546-readonly-canvas-select.md"
      ],
      "deviations": [
        "The narrowed vitest run held the verify lock 18m28s and outlived the 10-minute tool cap; the harness moved it to the background. I waited for it in the foreground (tail --pid on the lock holder) and read the verdict from its log. Sibling devs queued meanwhile.",
        "Real-browser repro used an untracked scratch entry under apps/console plus a vite server on port 5291. Both were removed and the server was killed by its recorded PID tree; nothing of it is in the commit.",
        "Gates: objectui has no dispatch-gates.mjs. Families were derived by hand from objectui package.json and the lint, vi-mock-specifiers, control-bytes, line-citation-gate, changeset-presence, changeset-guard and published-dist-gate workflows for the changed paths. Repository-wide runs are declared to CI.",
        "Reported, not a deviation: the commit carries objectui AGENTS.md's model-free trailer pair (Claude-Session + Co-authored-by: Claude), per that file's precedence over the harness reminder's model-named Co-Authored-By. The PR body ends with the os-dev session-URL footer.",
        "Clause-②: no is confirmed. packages/app-shell/src/index.ts is not in the diff, so no export moved."
      ],
      "line_budget": "n/a (no skills/** touched)",
      "worktree": "removed after the PR opened (node_modules deleted first; git worktree remove succeeded without --force)"
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR objectui#11603 at head c47b70879 (dev report 5978351187); it lands through the merge queue when every check is green

    domain:ui seat 1 · session_01FjqrwXPfSMkSfkKYDSRkN2 · 2026-10-04T09:05Z. Reviewed against GitHub, not the report.

    • Shape: draft, base main. The first line is Fixes #11546, with no other closing keyword. Clause-②: no is at line start. 5 files, +349 / −2. check-governed-merges: NOT governed. The PR assignee is os-zhuang.
    • Clause-②: no re-checked: packages/app-shell/src/index.ts is not in the diff, and the new __tests__/browserClick.ts helper is test-only. The dev's dist probe found it absent from the built package. patch ✓.
    • The card's ruling, carried out (in FlowCanvas.tsx onNodePointerDown):
      • A left press on a node in design mode now stopPropagation()s on a read-only canvas too. It no longer reaches onBgPointerDown, which cleared the selection and took pointer capture, so the click was fired at the viewport.
      • Only the drag start stays gated on editable.
      • Outside design mode, a node press still pans, as before.
      • The Delete-key handler is untouched, so it is still editable-gated.
      • StudioDesignSurface.tsx needed no change, because the selection already opened the inspector with the pillar's readOnly.
    • Pins:
      • StudioDesignSurface.automationsReadOnlySelect-11546: a read-only click opens the inspector with every control disabled and no save. A writable control is beside it.
      • A new FlowCanvas.test.tsx block: a read-only click selects exactly the node; a read-only drag captures, writes and pans nothing; the editable click and drag work as before; a non-design press still pans.
      • objectui#11124's read-only-inputs pin is untouched and green.
      • The dev named why objectui#11124's pins missed this: fireEvent.click with no press, under happy-dom's lack of pointer-capture routing. The new browserClick helper routes pointerup and click to the capturing element, as a browser does.
    • Red first and ablation: a real-Chromium harness on base reproduced the card. With the base order restored, 3 cases go red (the host's read-only pin, and the canvas's read-only click and drag), and objectui#11124's pins stay green under the defect. Restored by blob hash. The narrowed union (472 files, 5,352 tests, selected by import and by source-text read) is green.
    • Edges: a different mechanism, which already stops propagation when selectable; a read-only edge click selected at base. No change, correctly.
    • Out-of-scope reading: a pre-existing exhaustive-deps warning on addNode. It is identical at base ⇒ Acceptance notes.
    • Serial: objectui#11591 (Studio copy) was queued behind this card on StudioDesignSurface.tsx. This PR does not touch that file, so objectui#11591 is free to claim now.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 4, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed and verified by content: closed completed by PR objectui#11603 · domain:ui seat 1 · session_01FjqrwXPfSMkSfkKYDSRkN2 · 2026-10-04T09:33Z.

    • The merge: PR objectui#11603 went through the merge queue to main as 278d244 at 2026-10-04T09:32Z (seat ACCEPT 5978362979).

    • Content check of packages/app-shell/src/views/metadata-admin/previews/FlowCanvas.tsx on main 278d244 against its first parent b61c116:

      main parent
      the old early return if (!editable || e.button !== 0) return; 0 1
      if (!editable && !designMode) return; (a read-only design canvas still claims the press) 1 0
      the dependency list [designMode, editable, positionOf] 1 0

      The pin StudioDesignSurface.automationsReadOnlySelect-11546.test.tsx, the __tests__/browserClick.ts helper and the changeset 11546-readonly-canvas-select.md are in the tree. The diff is exactly the reviewed 5 files, +349 / −2.

    • No other card closed in that window.

    • pm:dispatched is removed in the same act. domain:ui, area:studio, the type and the priority stay.


    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 portalbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions