Skip to content

Feature: projects with live sync, selections of several, groups - #48

Draft
StackEnjoyer wants to merge 51 commits into
mainfrom
feature/projects-prototype
Draft

StackEnjoyer wants to merge 51 commits into
mainfrom
feature/projects-prototype

Conversation

@StackEnjoyer

@StackEnjoyer StackEnjoyer commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Features

  • save_project, open_project: a view as a BeamletOpticsProjects folder, opened by its .bmo file
  • Live sync: every action is saved, changes by agents and others merge into the open window
  • Several participants: others and agents shown at their selection, also on a shared drive
  • Ctrl+S saves a version (git via libgit2, no git install), Ctrl+R reloads the files
  • Selection of several objects: Ctrl+click, Ctrl+drag rectangle, object tree; move, remove, card
  • Ctrl+G / Ctrl+Shift+G: groups made in the window, nested, @group lines of a project
using BeamletOptics, BeamletOpticsGUI, GLMakie
gui = open_project("Bench/Bench.bmo")   # autosaves, merges what an agent writes to system.jl

Bugfixes

  • Camera moved or reset while Ctrl/Cmd was held, e.g. at Ctrl+S
  • Rotations could turn into NaN after many rotations or an undo (axis of a rounding error)
  • Axes of the controls no longer perpendicular after a tilt
  • Labels of new card widgets drawn too large or too small
  • Inspector: the button "‹" of a part covered its actions

Doc changes

  • Live view: selections of several objects and groups made in the window
  • Agent skill: SKILL.md, API.md, WIDGETS.md updated

Internal changes

  • New dependencies BeamletOpticsProjects (from GitHub, unregistered), NativeFileDialog, TOML
  • Needs BeamletOptics master with push!/delete! of ObjectGroup (#183)
  • Precompile sessions cover projects, selections of several and groups

Closes #49

uitt_hu and others added 11 commits October 27, 2026 00:32
save_project(gui, dir), open_project(dir), Ctrl+S / Ctrl+O and the tools
Save / Open with native folder dialogs; system.jl via BeamletOpticsProjects,
view.toml for camera, views, clip planes, table and beam looks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ctrl+S saves to the project or asks like Save as; Ctrl+Shift+S and the tool
Save as ask for a place and a name and create the folder; Ctrl+O picks a
.bmo file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A watcher reloads the project when its files change and the setup in the
window did not; otherwise, and on Ctrl+S after an outside change, a card
offers Load from disk, Overwrite and Save as. Ctrl+R reloads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Objects have a readable id, a label and a machine id. The watcher merges the
files into the open window per object: moved objects glide, new ones appear,
changed ones are rebuilt, removed ones go; only objects changed on both sides
are a conflict, shown on a card. Ctrl+R loads the files in place. Save keeps
the line order; save as copies src/ and sets the window title.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ctrl+S, Ctrl+O and Ctrl+R moved the camera back, out or up by the frames that S, O or R was held.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Autosave: the window writes every finished action to system.jl (after 0.5 s, not during a
  drag, a glide or a conflict); files that do not load get .bmo/window-backup.jl; closing a
  watched window saves the last change
- .bmo/session.md: the selection, open conflicts, load errors and the recent changes of the
  person, for the agent (shown with every prompt by the hook of the project)
- Ctrl+S saves a version (a git commit via BeamletOpticsProjects) on a card with the summary of
  what changed
- Merge: a conflict stays until the person decides; an agent that writes from an older read over
  a change of the person is a conflict (written states of the window); same-size writes are found
  by the stamp of the contents
- Precompile step of a project session

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d drive

- Participants, people and agents alike: each window writes .bmo/presence-<person>.toml (name,
  kind, beat, ttl, selection, stamp of its last save) and its own .bmo/session-<person>.md; the
  window shows the others with a box and their name at the object they work on; the status line
  names who wrote merged files ("Anna: moved L1"), else the one active agent
- The view of each person in .bmo/view-<person>.toml, view.toml stays the default
- The watcher ignores dotfiles of src/ (._X.jl of macOS on shared drives)
- A save as removes the session and presence files of the old folder
- Precompile step: another participant works on an object and leaves

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Presence and session files through the participant protocol of BeamletOpticsProjects; the
  window keeps the drawing and the journal; the writer of merged files is named by the stamp it
  published, for people and agents alike, also when its presence comes after the merge
- _sync! on merge_plan: members of a system that both the window and the files changed are merged
  as sets; removed objects stay out; a renamed member no longer resets the members
- A new project saved by the window also gets the agent skill of the GUI (not versioned)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a shared drive every access to a file waits for the network. The watcher read the times,
the contents, Project.toml and the presence files five times a second on the thread of the
window, which then ran at a few frames per second. A look now reads them in a task of the
background (_files_look, _take_look!) and also writes the own presence file there; the stamp
of the contents is read at most every 2 s. A look that waits behind a solve is replaced by one
on the thread of the window at most once a second, a failed look is thrown once, a look from
before a save is dropped, and a merge reads the times of the own code itself.

benchmark/watch_io.jl and benchmark/save_io.jl measure a look and an autosave over SMB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings grouping, the selection of several and the axis-angle conversion without NaN
(_rotation_axis_angle), which fixes the NaN rotations that a window wrote to system.jl after
many rotations and merges. Both branches add an include and a connect at the same place; both are
kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
uitt_hu and others added 17 commits October 28, 2026 18:29
A group made in the window (Ctrl+G, nested, pasted) is saved as `@group G1 = [L1, M1] pos = ...
rot = ...` of BeamletOpticsProjects: the members keep their own lines and poses, the systems list
the outermost group; opening a project makes its groups window groups again (Ctrl+Shift+G). When
another window or an agent changes groups in the files, the open window follows: a group whose
members change is made anew from the window objects (also groups not saved yet), one that only
moved or was renamed is changed in place, members taken out of a group leave the systems that do
not list them. Undo of ungrouping a group of one member (from a file) makes it again; export_changes
does not write a group of the project as a new grouping. Session step and skill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No change of behavior: the watcher (looks, merge after the files settled, start and stop) moves
to LiveProjectWatch.jl, the glides to LiveProjectGlide.jl (_adopt! calls _glide_all!), and
_ProjectSync gets the fields of the next steps (first_change_at, adopting, monitor, claim).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While a conflict is open, the window saves everything else; the objects of the conflict keep the
state of the files until the person decides (BeamletOpticsProjects.compose), per object on the
card ("theirs" / "mine") or for all. The card comes for new conflicts only, not after every
action. Saves pass the participant to save_project, which refuses lines claimed by others. The
backup while the files do not load is per person.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dly glides as one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, the lock at the object

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… file notifications

- _check_files! merges when the files are quiet for _SETTLE or at the latest _MERGE_EVERY (2 s)
  after they began to change (first_change_at)
- _adopting/_begin_adopt!/_end_adopt!: during a merge and its glides, _on_change! only marks the
  beams outdated; one solve of the union of the systems at the end (_finish_adopt!, from
  _on_idle! while objects glide)
- FolderMonitor of the project folder, src/ and .bmo/ wakes the watcher at once; polling stays
  (_POLL_WITH_MONITOR, kept at 0.2 s until benchmark/watch_notify.jl was run on the shared drive)
- FileWatching (stdlib) added to the dependencies
- test/TestLiveProjectLoad.jl

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he table

The table fits the setup after a drag (drag_end of the controller), a removal and a merge; every
merge outside the watcher is one solve too (_adopting); session steps for a refused gesture on a
claimed object and for a conflict decided on its card; skill text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…re gestures, redo of an edit asks the claims, a drag holds its claims, a gesture lands glides first, claim! leaves the presence file to the window

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d only their lines

- The lines that another participant claims keep the state of the files in what is saved, like
  those of an open conflict (`_composed`); a save refused by a claim reads the claims again and
  saves without that line (F1, F9)
- A ProjectChanged of a busy write lock is tried again after `_AUTOSAVE_DELAY`, not an error (F15, F22)
- Systems and groups made during a conflict keep their ids (F16); the ids of the files at held
  lines stay reserved (F19)
- A window closed with an open conflict writes the person's version to the backup, and the
  session file stays and names it (F17)
- A change of the person is saved within `_AUTOSAVE_WAIT` while the files keep changing; a merge
  does not restart its delay (F20)
- save_project(gui, dir) lands the glides first (F25)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ge, wait_solve waits for a merge

F21: _land_all! removes an object from gliding only after its landing change, so a tick during
the wait of that change for a cancelled solve does not end the merge and start its solve while
the object still moves; a glide frame does not move an object that landed meanwhile.
F27: the tokens of _glide_all! are the entries that its merge put into gliding, taken from the
glides and not when the task first runs; objects that a newer merge took over neither glide nor
land there.
F23: wait_solve waits while a merge of the project files is applied (adopting, glides) and for a
job whose result another task shows in _run!.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…held, wait_solve and merges

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f a pivot is a gesture that asks the claims; the view lock test expects the keys without Ctrl

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… files, an object removed here under the same id gives way; agents ask whether to keep a report on the tools

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the files and writes it with the next one; the presence files of the others are read only when changed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Oct 29, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 94.18303% with 157 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/LiveProjectSync.jl 92.72% 49 Missing ⚠️
src/LiveProject.jl 92.59% 44 Missing ⚠️
src/LiveProjectSession.jl 89.82% 17 Missing ⚠️
src/LiveProjectWatch.jl 92.68% 15 Missing ⚠️
src/LiveProjectClaims.jl 96.00% 11 Missing ⚠️
src/LiveProjectVersions.jl 91.83% 8 Missing ⚠️
src/LiveProjectPresence.jl 97.32% 5 Missing ⚠️
src/LiveProjectGlide.jl 97.91% 3 Missing ⚠️
src/LiveTable.jl 91.30% 2 Missing ⚠️
src/LiveTrace.jl 96.22% 2 Missing ⚠️
... and 1 more

📢 Thoughts on this report? Let us know!

uitt_hu and others added 5 commits October 29, 2026 14:26
… the file system refuses is busy and tried again, without a log entry per try

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… list every object and the windows box each; session files date their actions and say how to tell a window that was not closed; skill: docstrings with REPL

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gents run a project in .envs/<person>@<machine>; AGENTS.md: Pkg reads [sources] of path-tracked dependencies

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…; the lenses of the project tests and of the session take ConstantRefractiveIndex, as BMO master requires

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the project file when it opens it (a card for older or missing packages, a notice for a newer major version), Ctrl+N and the tool "New project" make an empty project, the presence file carries the versions of each participant; the packages of a project and their notice are gone

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@StackEnjoyer StackEnjoyer added this to the v0.3.1 milestone Nov 6, 2026
@StackEnjoyer StackEnjoyer added the enhancement New feature or request label Nov 6, 2026
uitt_hu and others added 18 commits November 6, 2026 13:35
…y after "Apply" on the page "Edit", release 0.3.0; the docstring of _replace! names both the pinned cards and the claims

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…chine (a shown window sees a change of the files within 5 s instead of 0.5 s, the first look within 60 s), and the write that the file system refuses makes the folder read-only too where a rename depends on the folder only (Linux)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…jl: the [sources] entries, README, AGENTS.md and docs; the Michelson tutorial on the new docs site

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ocs; its pull requests run CI (DOCUMENTER_KEY)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the others, versions, Ctrl+R, groups, conflicts, presence, claims, session file, keys and tools), open_project and save_project on the API page, a short section in the live view page that points to it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lder, each window driven by simulated mouse and key events (presence, drags seen by the other, claims refused and expiring, edits at the same moment, a race that ends on the conflict card, an agent's edit, a group, versions of both, leaving); the sides wait for each other through files of the folder and log each step

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… accesses of a project in a folder, save_io.jl the parts of an autosave also in a folder of a drive; two_machines.jl reads a signal file again while the other side replaces it, and compares the windows after edits at the same moment only once the other side's change arrived

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…save prepares the save on the window's thread and writes it on a thread of the background, its result taken at a later step (merge after files changed, claims read again, busy, failed, as before); the session file is written by one writer in the background that keeps the latest text; a slow look is no longer read again on the window's thread unless a solve holds the background. Closing, Ctrl+S, Ctrl+R and save_project wait for a running write. On a shared drive 89 ms away an autosave had stopped the window for 4-16 s and every click for about 1 s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… = true) takes the rest of the width of the card (a given width wins), CardRow(...; aligned = true) gives the first texts of its rows one width, so that their widgets start in one column; WIDGETS.md shows both

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…types of episodes and of the activity of a window, the interfaces of the model, the cues and the timeline, stubs to be filled in by their workstreams

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k of a pick ("+", "−") that started before another participant claimed the system, and "×" of a row of its members, are refused and the status line names the holder; otherwise they claim the system

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… colour per participant (lighter on a dark theme), episodes of their changes and messages, cues paced one after the other and summarised when more than 3 s behind, the poses at a time for the scrub of the timeline, following a participant with the camera

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s gives back the pose of the files, not the one halfway: the step notes the pose after its gesture, which lands the glide

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-cues.md, W2): a frame in the colour of the participant, a dashed ghost at the old place and a soft arc drawn out to the new one (a move), an arc around the object (a rotation), a settling frame (added), a ghost with a cross (removed), a chip with the name and what changed, bubbles of messages, ghosts of the scrub; overlays only, faded in and out, the chips and bubbles hidden in the spectator mode

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…3): a strip at the bottom of the 3D view in both layouts, hidden until an other was there; collapsed one line with each participant's last change and its age, expanded a lane per participant with the marks of its changes, pills of bursts and messages; hover shows the change, a click replays it, a double click frames it, a drag scrubs the time, the eye follows a participant, the wheel zooms the time span

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…indow includes src/gui.jl of a project into its module (again when src/ changes, its error in the status line); an input on a card that changes the constructor code of an object (BeamletOpticsProjects.constructor_code) draws it again (rerender!) and writes the new code to its line, with undo; a type without it says once that changes of its shape are not saved; card_widget(gui, obj, name) finds a widget of a card. Compat BeamletOptics 0.14.1; BeamletOpticsProjects from its branch feature/own-types until its pull requests are merged

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d, integration): a merge of the files of another participant is an episode (who, which objects, poses before and after, "moved M2 by 12 mm"), named once its writer publishes the stamp; a new `doing` of an agent is a message; every frame draws the cues at their pace, the timeline, a replay of the mark under the mouse, the ghosts of the scrub and the camera that follows a participant; presence boxes, names and locks in the colour of the participant; the toast of the compact layout stands above the timeline; a step of the precompile session; docs and skill

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd counts the refusals; two_machines.jl records a failed writer as a check instead of halting

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: a view is saved as a project that agents edit live

2 participants