Repository navigation
refactor: what a double-click on a node opens is a contribution point - #140
Merged
Merged
Conversation
The double-click listener ("viewer listener") did two things: open a
node's definition, which every product uses, and, for a task with a
@viewer annotation, open its last tokens (open, diff, open with an editor,
run a command) or a path it declares, which only wfpy has.
`NodeOpener` (node-opener.ts, exported) is the contribution point: an
opener with an `id` answers a double-click on a node with the actions to
run, or leaves the node to the platform, which opens its definition as
before. The listener multi-injects them (one per id, the last binding
winning, asked in the order the ids were first bound; the first that
answers wins) and asks them before its own definition navigation.
The @viewer half moves verbatim into viewer-node-opener.ts
(ViewerNodeOpener, id `viewer`): git's moved-code detection marks 33 of
its 372 lines as new, the opener's guard and context lines and its
imports. The stock module binds it, so nothing changes; wfpy-ide binds
its own next, and then the stock module stops.
The three @viewer test files inject the opener the stock module binds
and pass unchanged; test/node-opener-seam.test.ts pins the contract and
the bindings, through a real container too. The parity baseline accepts
the one constant binding.
Claude-Session: https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv
…seam # Conflicts: # packages/diagram-client/README.md
- An empty answer is no answer (the contract named only undefined, but `[]` stopped the loop and blocked the definition), and an opener that throws is skipped with a warning instead of making the node open nothing at all. - The contract says an opener without an id is dropped, and that an opener's answer, unlike the platform's definition, does not stand back for a node whose first view the network navigation opens. - The two definition branches are one (a task, or an actor not marked external), with a test pinning the marked-external actor. - Comments: ABSOLUTE_URI's explanation moved with it into the opener, and the stock module's line for the listener says what it does for every product now. Claude-Session: https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P5e, the
@viewerstep: the next wfpy-only piece of the client, behind a fourth contribution point (after annotation editors, node sections and wizard templates). Nothing changes yet.Why
The double-click listener (
viewer-mouse-listener.ts) did two things:@viewerannotation, open its last tokens instead (open, diff, open with an editor, run a command), or a path the annotation declares.What
NodeOpener(src/node-opener.ts, exported). An opener has anid, and itsopen(node, { sourceUri })answers a double-click with the actions to run, orundefinedto leave the node to the platform. The listener multi-injects the openers and keeps one per id (the last binding wins, vialastPerKey). It asks them in the order their ids were first bound, before its own definition navigation, and the first that answers wins.@viewerhalf moves verbatim intosrc/viewer-node-opener.ts(ViewerNodeOpener, idviewer), with its helpers andwf:viewer*argument names. Git's moved-code detection marks 33 of its 372 lines as new: the opener's own guard, its context lines, and the imports. It emits the sameNavigateToExternalTargetActions, which Dialogram's host still turns into an editor, a diff or a command.Review (
/code-review medium), addressedThe review confirmed the moved code is equivalent: the same order of checks, the same nodes reaching
@viewer(it comes down to the type alone), the same messages and routes, and no change for actor or network nodes. Fixed:[]used to stop the loop and block the definition.ABSOLUTE_URI's explanation moved with it.Tests
@viewertest files (viewer-declared-target,declared-target-resources,double-click-opens-one-thing) inject what the stock module binds and pass unchanged.test/node-opener-seam.test.ts(9 tests):vieweropener, a product's after it, a product'sviewerreplacing it, and none when nothing is bound.NodeOpenerconstant binding.https://claude.ai/code/session_01EToj6RJRMSSHQiqGNMU9wv