Move Binders and Uploads to the right of the strip
The strip now separates what a document manager IS from where it takes you. Left: Originals, Modified, Common — three views of the same documents. Right: the fo...
Make the Spirit Animal visible, and stop the palette vanishing
Two reports, two different mistakes of mine. THE PATTERN WAS INVISIBLE. It painted behind the pane, and every pane surface — FeatureCard, LauncherParentCard, W...
Rebuild 533bbeb4 now the Expression strings are in the dictionary
The image build clones kamo-translation-dictionary and copies it over messages/, then fails if a component names a key those messages do not define. 533bbeb4 wa...
Set the headline in quotation marks
Quotes around the banner line, as asked — but rendered from CSS (`open-quote`/`close-quote` against `quotes: auto`) rather than typed into the string, for two r...
Expression — colour, Spirit Animal and logo as one decision
Two corner controls become one. That split was an accident of the order the features shipped rather than a distinction anybody holds: a colour, a pattern and th...
Count on the Binders tab, and land on Selected Docs
The tab reads "Binders (n)" so the count the Selected Docs binder holds is visible from the strip — including (0), which is the case worth seeing, since it says...
The picture frame IS the pane, not something inside one
Every other widget is content in the launchpad's frosted glass card, with a header, a title and a corner control. A picture frame is not: rendered that way it i...
Drop the frozen ordinal CHECKs that were failing every new enum value
imgs_assoc_id_check allowed assoc_id 0..13. ImageAssocType.PICTURE_FRAME is ordinal 14, so EVERY Picture Frame upload violated it. Hibernate writes CHECK (col ...
Show which layers of a modified document were worked on
A document has one modified record, so the Modified tab has one row per document. The column names the layers touched rather than which of two kinds a row was: ...
Rebuild e67f59b against the dictionary commit it needs
e67f59b renamed previewBanner.nowLive -> previewBanner.headline and was pushed before the matching kamo-translation-dictionary commit (f4627d31). The build step...
Open the one modified record, whichever layer asked
getOrCreateClassic and getOrCreateFormFillable collapse into getOrCreateModified: "open this for editing" means the same thing whichever editor asked, and the a...
Trade the NOW LIVE badge for the headline it was hiding
The top banner led with a six-character pill — bordered, uppercase, pulsing — and put the actual message after it. The pill now carries the message itself: "Run...
Merge the two modified records into one with two layers
Where a document has both kinds, the CLASSIC row survives — it is the one that may hold edited bytes — the design is repointed onto it, and the FORM_FILLABLE ro...
One modified record with two layers, not two records
A document had up to two derived rows — CLASSIC for edited bytes, FORM_FILLABLE for fields — and something had to decide which was based on the other, repointin...
Picture Frame — a member's own photos and videos, in a frame they build
The first INSTANCED widget. A member hangs as many frames as they like, each with its own contents, its own moulding and its own place in the grid, all from one...
Frame and media endpoints, and seed the new rights
Self only, and enforced in the QUERY. Every read and write resolves the member from the session and every repository call takes that id, including the single-fr...
Create the picture_frames table
One row per Picture Frame widget a member has arranged on their launchpad. A table rather than a preference blob because the photos and videos in a frame are i...
The schema, rights and storage domain behind frame widgets
A Picture Frame is a member's own photos and videos on their own launchpad, and a member may hang several. This is everything the platform needs to hold one. P...
Stamp last_login so "Last Login" stops reading Never
Nothing in SecurityService has ever written users.last_login. The write lived in the retired AuthenticationService and was not carried over when authentication ...
Put the four member shortcuts on one row
are one class of control, so they now share one row: the launchpad's top-right corner reads as a single strip rather than a two-line stack. styling; it uses th...
Stop /validate and /logout from mounting the signed-in shell
A load of / showed a burst of 401/403 before the session settled — user-info, ui-preferences, by-department, chat/unread, timezone/effective and tickets/pending...
Restore the status endpoint the frontend has been polling
kamo-internal polls GET /api/security/session/god-mode once on mount and every 60s thereafter. That endpoint was removed in 9c70cb7 along with the rest of the t...
Stop the drag preview from driving itself into a render loop
Dragging a pane sometimes threw React #185 and left the page scrolling to the bottom forever, undoing every attempt to scroll back up. One cause, two symptoms....
Bucket the history by the member's day, not the browser's
groupByDay built its day key from getFullYear/getMonth/getDate, which read the machine's calendar rather than the member's. With createdAt now parsed as the UTC...
Restore the timezone fix, and take chat-core 0.1.5 / net 0.1.1
5d1cc23e was committed through a stale private index and reverted ec881208 wholesale — serverTime.ts, the member-timezone provider, the guard and all 216 call-s...
Take @kamo/chat-core 0.1.5, net 0.1.1, email-core 0.1.1
The chat half of the timezone fix lives in chat-core: message timestamps and read receipts are parsed there, so the bubble stayed seven hours out until this lan...
Render every timestamp in the member's zone, read every one as UTC
A direct message sent at 3:33 AM Pacific displayed "10:33 AM" — the raw UTC clock, printed as though it were local. Two independent defects, present together on...
Position and colour for a pane's logo, and always let a member open the editor
THE EDITOR WAS UNREACHABLE FOR ANYONE THE ROLL HAD NOT DECIDED FOR. `brandOf` answered null until a mark existed and the control was gated on the answer, so a m...
Stop the master-note ring sweeping a gradient across the launchpad
LIVE ON PRODUCTION since b9b1fe08. The org master note's ring was a conic gradient in a pseudo-element sized 150% by 150%, centred and rotating once every six s...
Paint the master notes in the organisation's colours
"Our Master Note" is the organisation's PRIMARY and "My Master Note" its SECONDARY, each as a pastel — an 18% tint on white. The pair reads as a set at a glance...
Stop seeding a palette colour on the org master note
Both master notes are painted from the ORGANISATION's brand now — primary for "Our Master Note", secondary for "My Master Note", each as a pastel — so a stored ...
Rebuild against kamo-shared-library 48cde37
Picks up MANAGE_ORG_MASTER_NOTE, the right that guards "Our Master Note". SecurityService is what enumerates RoleRightType for the role, job-title and departme...
Put the two master notes on every launchpad
"My Master Note" and "Our Master Note" are panes in the same sortable grid as everything else — dragged, resized and ordered like any other pane — and neither c...
Serve, provision and protect the two master notes
GET /api/notes/master answers both and provisions whichever is missing. PUT /api/notes/master/org writes "Our Master Note", addressed by organisation rather tha...
Add the master-scope columns to notes
MASTER_SCOPE ('MEMBER' / 'ORG' / NULL) and ORGANIZATION_ID, plus the two indexes the entity declares and a partial unique index per scope so one live master not...
Model the master notes and the right that guards the org's
A master note is the one note a member — or an organisation — always has. "My Master Note" is provisioned per membership; "Our Master Note" is one per organisat...
Hand the editor what it needs instead of re-asking
DocumentEditor fired POST /api/docs/form-fillable/{id} on every mount purely to read classicEditable — a write used as a query, re-deriving a row the call that ...
Make the pane logo visible, and stop the two seeding passes racing
Two bugs, either of which alone would have shown no logos. IT WAS PAINTED BEHIND FROSTED GLASS. The mark went in at z-index 0, under the pane's content — where...
Make the Modify rules testable, and drop a dead field
Both rules the Modify menu encodes have shipped wrong once — form fillable was disabled on the rows whose fields are meant to stay editable, and it was offered ...
Drop hasDesignVersion and its per-row template lookup
Every document list ran an esign_templates lookup for EACH row — 100 per page — to answer "is this an original that happens to carry a design". That was how the...
Brand a third of a member's panes with the org logo, and let them tune it
A third of a member's panes wear the same faint org mark /leads and /calendar carry, at pane scale. Which panes, and how, is rolled once and kept. WHAT THE ROL...
Do not offer form fields on files that cannot carry them
Replacing the two buttons dropped the isConverted gate the old "Edit PDF" had, so Modify offered form-fillable editing on audio and video — where there is no re...
A form fillable row can still be opened in the editor
I had disabled "Edit In Form Fillable Mode" on a form-fillable row, which contradicts the rule: its fields stay editable in every tool the editor has — what a f...
Edit in Classic Mode, and redraw when it saves
The form-fillable editor can now branch out to LibreOffice. The server derives the classic version on the way if the document has not got one, which is the poin...
Give the Linux options a Tux who hops
The icon beside "Linux Desktop" and "Dev Machine" was an 18.6 KB static penguin. It is now a 1.4 KB vector one who bounces, built from flat ellipse geometry so ...
Give the audit test the new constructor argument
Missed in the previous commit, which I pushed off a grep's exit code instead of maven's — so a red suite went out as green. The controller gained a ClassicSaveP...
Announce a classic save to the member who made it
A WOPI save on a CLASSIC version now publishes docs.classic-saved.{memberId} so the Kamo PDF editor, if it is open on the form-fillable version, can redraw the ...
Relay "the classic version was just saved" to the editor
DocsService publishes docs.classic-saved.{memberId} after a WOPI save lands on a CLASSIC version; this puts it on /topic/docs/saves/{memberId} over the STOMP co...
Do not bill an org twice for a version that owns no bytes
The org storage total is SUM(fileSize) over Img rows, and a derived version points at its original's ImgDat while copying its fileSize — so every modified versi...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.