Skip to content

feat: a view can be of the instance, asked of the root by the path of instances - #175

Merged
endrix merged 2 commits into
mainfrom
feat/view-of-instance
Nov 12, 2026
Merged

endrix merged 2 commits into
mainfrom
feat/view-of-instance

Conversation

@endrix

@endrix endrix commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Found while installing the CalPy sidecar for a first live test of the actor view: in the MPEG-4 example only 10 of 42 actors opened the view on a double-click. The rest are made by factories (make_X(...)), and for those the platform could not ask for the right thing.

The problem

A view of a node's unit is asked by name: the file the node references, and the name of its definition. For a unit made per instance (a factory called with the instance's parameters) the file holds, under that name, another object: its own default one, or none. So the sidecar either answered for the wrong class or could not answer, and the CalPy sidecar therefore offered no view on such actors.

A drill-down into a nested unit already has the answer to this: when the file cannot answer by name, the toolkit asks the editor's root by the path of instances the trail records (rootNetwork + instancePath).

What changes

  • Document. A view entry may say what it is of: meta.views: [{ id, label, of: 'instance' }].
  • Client. The double-click (openLeaf) and the context-menu item pass the mark in the openView action; requestView puts it on the view's crumb (viewOf), and the trail keeps it through serialising and parsing, so a click on the crumb asks for the same thing.
  • Toolkit (SidecarModelSource.getGraph). When the request's view is the last crumb's and that crumb is marked, the root is asked first, by the instance path, with the view. Only if it has no answer is the file asked by name; the root is then not asked a second time. The resolved options go on with the document, as they do for the existing fallback, so the layout is the instance's.
  • A view without the mark is asked exactly as before: other products are untouched.

Checked

  • sidecar-toolkit/test/view-of-instance.test.ts: the order of the questions for a marked view (root first; file by name when the root has none; never three), for an unmarked one (file first, root as fallback, as today), and for a mark that does not apply (another view, no instance, an unknown word).
  • diagram-server/test/open-view.test.ts: the view entry, the menu item's action, the crumb, viewIsOfInstance.
  • diagram-client/test/view-of-instance-trail.test.ts and leaf-double-click-opens-source.test.ts: the action, the crumb on the request, the crumb coming back, the handler.
  • Typecheck, the neutrality gate and the whole suite pass.

After review

An independent review traced the request end to end with the real client and server code and a spawned sidecar: a marked view opens correctly for an actor of the root network and for one in a nested network reached by drill-down (same file, another file in its own editor, in-place products), and an unmarked view sends byte-for-byte the requests it sent before, also when the by-name load fails. Its findings, fixed in 503eacb:

  • A refresh dropped the view (pre-existing, every view of every product). The host's refresh repeats the file, the name and the trail, and names no view, so a keystroke or a save in any source file replaced the view by the unit's structure, under a breadcrumb that still said the view. The storage now takes the view from the trail's last crumb when the request names none and is for that crumb's unit (withTrailView). Tested through the storage with a refresh-shaped request.
  • A trail with a hole (a crumb shown by name, with no instance) made the path skip a step, and the root's answer for the shorter path was shown. The root is asked first only when every crumb under the root was reached through an instance.
  • The root's reason was lost. When the root has no answer and the file answers by name, the document now carries a warning (view_of_definition) saying that what is shown is the definition's, with the root's reason; when neither answers, the error names both.
  • Tests now pin what the sidecar is sent on the wire ({rootNetwork, instancePath, view} on the root's file, no network), a trail of two, of three, and with a hole, and the mark from the document to the node's arguments.

Stated rather than changed: the mark is said of a node's views (a view offered on the canvas is reached through no node), and it is acted on by the model source that asks a sidecar; a product whose graph comes from a CLI plan asks by name as before.

Not checked

  • A running VS Code. The sidecar side that uses this is streamblocks/streamblocks-mlir (a PR stacked on #450); it is tested against the sidecar directly with the request this change sends.

https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv

… instances

A producer marks a view it offers on a node with of: 'instance'. By name,
a file answers for the definition it holds under that name; for a unit
made per instance (by a factory, with the instance's parameters) that is
another one, and the view shown was not the node's.

A view so marked is asked of the editor's root, by the path of instances
that leads to the node, as a drill-down into a nested unit already falls
back to. Its file is asked by name only when the root has no answer, and
the same question is not asked twice. The mark stays on the view's crumb,
so the trail leads back to the same view. A view without it is asked as
before.

Claude-Session: https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv
…en it is not

From the review of #175, which traced the request end to end with a
spawned sidecar.

- A refresh by the host (a keystroke or a save in any source file, a run)
  repeats the file, the name and the trail, and named no view: the view
  was replaced by the unit's structure under a breadcrumb that still said
  the view. This predates the mark and hit every view; with it, the actor
  view of the file being edited was lost at the first keystroke. The
  storage now takes the view from the trail's last crumb when the request
  names none and is for that crumb's unit.
- The root is asked first only for a whole trail: a crumb shown by name,
  with no instance, made the path skip a step, and the root's answer for
  the shorter path was shown.
- When the root has no answer and the file answers by name, the document
  carries a warning with the root's reason: what is shown is the
  definition's. When neither answers, the error names both.
- The host's own trail parser keeps a view crumb's fields.
- Tests: what the sidecar is sent on the wire, a trail of two, of three,
  with a hole; the refresh through the storage; the mark from the
  document to the node's arguments.

Claude-Session: https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv
@endrix
endrix merged commit bf34e2e into main Nov 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant