Report form becomes a tool window; filter and status changes
REPORT FORM -> POPUP TOOL WINDOW. A modal was the wrong shape for the job. Reporting a defect means describing something you were just looking at, and a modal i...
Suggest logo, colours and backgrounds from the member's site
The Basics step already asks for a website. This reads it and offers what it finds on the three branding steps that follow, as suggestions the member can take, ...
Enter as System Member no longer needs your own membership
The button was disabled by canEnterOrg, which asks whether the VIEWER holds a usable membership — so it was greyed out for exactly the orgs it exists to reach, ...
File a bug or an enhancement
The type leads the form, because it changes what the rest of it is asking: 'What happened?' for a defect, 'What would you like to see?' for a request. Two cards...
Design the website brand scan
Where the /network/create Website field turns into logo, colour and background suggestions on the three branding steps. Records two things that are easy to get...
Remind the dispatched session to push its work
Matches the server copy in SystemBugAiDispatchService, which is what the dialog actually shows once the preflight lands — this one covers the moment before it. ...
Tell people a web alias is taken while they are typing it
The create wizard is eleven steps long and the alias was only validated for FORMAT locally — whether anyone already held it was discovered when the form was sub...
Correct what the KamoDesktop SSO token's lifetime actually is
The comment called the link "short-lived, single-use" and "5-minute", which is what caused the token expiry to be set as if it were a URL redemption window. It ...
Add the System Bugs tab
Members report defects in the platform with screenshots and the sites they the dev machine. A tenant sees only its own organization's bugs and the platform org...
Show a member's photo on the scoreboard, not their initials
The face now comes from the same directory index every other member list on the platform reads (useMemberProfiles), so a person's picture on the scoreboard is i...
Show Google's OAuth callback URL on its registration card
An operator filling in the Google Workspace registration had nothing telling them what to put in the Google Cloud console's Authorized redirect URIs, and the Re...
Plan the System Bugs build across six repos
Screenshots turn out to need no table: an Img row already carries an assoc type plus an assoc object id, and imgs has no CHECK constraint on assoc_id, so append...
Manage a custom domain from Company settings
A domain used to be the doorway into an organization: DNS had to be configured before anyone could sign in at all, which is why /setup/dns was reached from the ...
Design the System Bugs tab and its AI dispatch path
vscode:// URI handler opens a conversation in the window sage already has open, and coderProcessWrapper carries model and effort, which the URI cannot. Also rec...
Record SP1 as complete, and the six things the plan got wrong
Keeps the reasoning rather than just ticking boxes — the top-level-org skip and the PLANNING-stage regression are both the kind of mistake that would be made ag...
Render the app tree, and confirm what a parent switch-off takes
Children now sit under their parent in the Apps & Features list, each with its own switch. Nesting is expressed by ORDER plus an indent rather than a nested con...
The Affiliate Sales Scoreboard widget
One grid column wide and two rows tall: the ten people in the organisation bringing in the most through their tracking links, over today, this month, this year ...
Restore CRLF on the two theme files
Both files are uniformly CRLF and my previous commit rewrote them through Python in text mode, which reflowed every line: Theme.tsx showed 237 changed lines and...
Paint the branding of the org in the tab, not the host
getThemePath() derived the theme base from window.location.hostname. That answered the right question while every organization had a hostname of its own — and f...
Clear the cloned session in the enter-as tab
Entering an org opens a tab with window.open('', '_blank') and points it at /validate. That was cross-origin until now, so nothing was shared. It is same-origin...
Regenerate the ServiceType mirrors after the stage correction
The five pre-existing commerce verticals are COMPLETED, EHR is PLANNING.
Read the session from the tab, not the shared cookie jar
46 client modules read the *** id out of document.cookie and sent it as X-***-Token. sessionStorage is per-TAB; a cookie is per-ORIGIN. While every organization...
The scheduled-support presenter picker offered nobody
The Presenters tab dropdown was empty for every organization, and always had been. GET **************** answers with { teamMembers, total }; the tab read data.m...
Mirror the six commerce child apps, and stop the mirrors drifting
Both TS mirrors are now GENERATED from ServiceType.java rather than hand-maintained. They had drifted badly from Java and from each other: stale "RAG integratio...
Task 7 needed no new migration, and top-level orgs must be included
The app-tree backfill turned out to already exist as **************** restricted to isGated() verticals. Dropping that restriction is the whole change. Records...
One scrollbar, three times as wide, down every conversation
The bar beside the messages was 8px in the member chat and SMS, 6px in support tickets and social, and in the AI chat it was nothing at all: that list declared ...
Give /api/org/current the domain the client requires
internal.kamocrm.com failed to render with "Invalid organization data: missing 'id' or 'domain'". Organization.fromJSON refuses a record without a domain, and t...
Move jump-to-newest in with the toolbar's other actions
Search now owns the whole left track of the toolbar, because the empty part of that track is exactly the room the field opens into. The scroll-to-bottom control...
Refresh the favicon and drop the unused blueleven logos
public/favicon.ico now carries 48x48 and 32x32 layers instead of 32x32/16x16. The five logo-blu*/logo-blueleven* PNGs are referenced from nowhere in the app, so...
The toolbar's search is a glyph that opens into a field
The member chat carried a permanent search box across the top of the window — the width of the whole toolbar, spent on a control that is empty almost all of the...
A sent message animates in once, not twice
The message list keyed each row on the message id, and a sent message's id changes exactly once — the optimistic row is appended under a local id, and the STOMP...
Name rooms after the org id, not the hostname
getOrgToken() took the first label of the current host, and its own comment said why: "so identically-named rooms cannot collide across orgs". On the shared hos...
Land inside a newly created org instead of at DNS setup
Creating an org routed the creator to /setup/dns, and the reason was real: entering meant an OTK redirect to internal.<new-domain>, and a brand-new org has no D...
Implementation plan for SP1, the app catalog parent/child tree
12 tasks across kamo-shared-library, KamoInitializerService, SecurityService, MediaService, VOIPService, kamo-internal and the translation dictionary. Ordering...
Design the EHR/EMR vertical and the parent/child app catalog
Two specs from the pre-build analysis of ~30 repos and the 2026 ambulatory EHR market. The program design records the six decisions that bind every sub-project...
Make an org without a domain enterable
Entering an org meant navigating to **************** With no domain that URL rendered as the literal **************** so Enter was disabled and owners were rout...
Write a scheduled-support description as rich text
The description on **************** was a three-row textarea. It is the /kb/new writing surface now, minus pictures and the media library — those upload into KB...
Take the chat-core that stops a sent message showing twice
@kamo/chat-core 0.1.6. The conversation reducer now adopts the pending optimistic row when the member's own message comes back over STOMP, instead of appending ...
A file may be dropped anywhere on a chat window, not only on the input strip
The drop target was the composer surface alone — a few dozen pixels at the bottom of a window that is otherwise all messages. A screenshot let go over the conve...
Stop offering Business the add-ons it already includes
Choosing Business still presented video conferencing, the AI assistant, the HR system and e-signatures as things to buy, even though the plan bundles all four. ...
Let the SSL check lower the flag, not only raise it
checkDns only ever latched sslConfirmed to true. A domain whose stored flag was set under the old any-one-host rule therefore kept a green SSL card and an unloc...
Open the swatch's own colour window, not the first on the page
The swatch reached its hidden <input type="color"> through document.getElementById on an id built from the picker's translated label. A label is only unique ins...
Stop the colour group fighting the colour you are choosing
ModernColorGroup was controlled and uncontrolled at the same time. It kept local state for every slot, mirrored the `value` prop into that state in one effect, ...
Read the new org's id when it arrives quoted
The last step of the wizard appeared to do nothing, and clicking Create a second time answered that the organization already exists — because the first click ha...
Show per-host certificate progress, not a single spinner
Certificates are issued one per subdomain, and they do not all land at once, so the SSL step now reports how many of the org's hosts are live and names the ones...
Lift the wallpaper and widget shortcuts above the media pod
The profile header band laid "My Wallpapers", "My Widgets" and the media chrome out as one wrapping row, so the two shortcuts read as a fourth switch sitting al...
Point frame media at an endpoint that actually serves it
Every photo and video in a picture frame rendered as a broken image. The URL pointed at **************** I took that for a general imaging proxy — it speaks HT...
Drop the greeting block and put the masthead on one row
The launchpad's masthead carried a kicker, a "good afternoon" heading and a status line of apps/title/trial/date beside the logo, and the member's own controls ...
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...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.