Pin KamoCRM's own sales details, and that no org can change them
The address and number are constants a single edit away from becoming a tenant lookup, which would route a customer asking about a KamoCRM plan back to their ow...
A plan card says what it adds to the one below it
The picker gave a price, a seat ceiling and one sentence. Choosing between $46 and $80 a seat on that is a decision with one obvious answer, and for most teams ...
Attachments authenticate like chat's, instead of showing broken
Every attachment on a bug report rendered as a broken tile. In production: seven content requests, seven 401s, zero successes — while the report's own JSON load...
One way to reach sales, and a seat control that knows the plan's limit
ContactSalesDialog holds KamoCRM Inc.'s own details — Sales@KamoCRM.com and (949) 298-9960 x1 — as constants, deliberately. Every other address on this platform...
A Numbers screen, so calls and texts can come from different companies
An organization buys its numbers from one company and answers the calls with another. That is ordinary, and Kamo could not describe it: texting was a property o...
Anchor it to the first cell, and stop the scrollbar collapsing it
Three things, and two of them are the same mistake: asking a question about a portalled element as though it were a child. THE SCROLLBAR COLLAPSED THE PANE. Sc...
The shelf replaces the per-app cards, and four fixes to its rows
The launchpad was a wall of one card per app. The App Shelf lists every one of those apps in a single pane, with what each does and everything inside it, so the...
Quote the real price, and stop the Free plan looking like the best one
Two things on this page were wrong in a way that reaches customers. The price. bestRate() took the cheapest rate across all three terms and printed it as "per ...
The templates button called an endpoint that could not answer
Found by reading the controller rather than the code calling it, and it was broken twice over in a way that LOOKED fine: - The list asked for `status=ACTIVE`...
The report's thread in the drawer, shelving, and Issue Persists
`SystemBugThread` renders everything anybody has said about a report and every status it has passed through, under the current-status callout: the callout answe...
Two rows tall, and it opens by widening rather than by a second pane
The pane was 861px tall, not the 496 its two rows ask for. The launchpad grid is gridAutoRows: minmax(106px, auto), and an auto maximum sizes a track to its ite...
No explanation that lasts one frame, and a failure you can act on
A refused member was shown an info alert and redirected home in the same breath, so the message appeared for one frame and was replaced by the launchpad. That i...
A document outline, and a skeleton in the page's own shape
Only the hero was a real heading. Everything else — the ledger's nine categories, the account panels, the covenant, each upgrade option — was a styled div, so a...
One module owns the link from the plan page to the billing tab
Every action on /myplan is a link into Plans & billing, and it has to land on the right sub-tab or "Payment and invoices" opens on Subscriptions and looks broke...
The upgrade section said the opposite of the truth during a trial
A trialling organization's plan row really is FREE — the subscription points at it — while the trial has the whole catalogue switched on. The difference this se...
Draw the god rules the server now holds
The Users tab locked every god row for everybody, and both halves were wrong. Too loose, because the lock lived only in this component — the endpoints behind it...
Type the nav-option fixture the shelf tests hand the launcher
The helper took { id: string }[], so every fixture with a kind, an href or a toolKey on it was a type error the test run never saw and tsc did.
Staff can write the sentence the customer reads
The customer-visible note had a column, a DTO field and a plan page ready to render it, and no way for anyone to set it — so Harmony's was the only one that wou...
Bridge SMS unread across the boundary the tool dock sits above
ToolDock is mounted in ToolProviders ABOVE AuthedChrome, deliberately, so it never unmounts across a navigation -- the single fact that keeps a member's typing ...
Clear the shelf's edge, cap the pane's height, and read apps from one source
Three things a real browser found that the tests could not: - The pane anchored to the shelf's inner content column, so it opened a dozen pixels INSIDE the w...
The softphone gets an inbox, and an SMS window is one thread
The SMS tool window opened on a twelve-key dialpad and then became a three-tab window -- Chat / Templates / CRM -- titled "Conversation #a3f1c8de-...". None of ...
A Free Plan pill, and a page at /myplan behind both pills
The trial pill lived twice — the nav rail and the launchpad — with the countdown, the member-type gate and the styling copied between them. Both gated on a live...
The shelf, its slide-out pane, and its place on the first row
Every app the member may open, with a pin, a search, and a pane that slides out of whichever side has room for it. Locked to the launchpad's first row by lib/ho...
Design for the App Shelf launchpad widget
A system widget with no rights, locked to the first row of the launchpad by arithmetic rather than a band of its own, with a portalled flyout carrying each app'...
One scrollbar on a data grid, not two
Every grid in the app drew two vertical bars — ours and the library's, side by side. Measured on /leads: ours at x∈[868,900], ag-Grid's at x∈[900,915]. ag-Grid...
Fix Verified, a reason on every denial, and a Requires Verification filter
The status menu on /support?tab=system-bugs leads with "Requires Verification" and a rule, then the individual statuses. It stands for NEW, IN_PROGRESS and FIXE...
Lock the platform rights an operator may not grant
SecurityService now refuses to grant a right the caller does not hold themselves — an administrator may create a peer or a lesser, never a superior. The Manage ...
Make the left seam move the LEFT edge, and put one on every window
Two things were wrong with the width gesture. **It moved the far edge.** `store.resize` writes a window's width and touches nothing else — not `dockX`, not the...
Stop a horizontal scrollbar flashing under every tab switch
Every tab and sub-tab change in the Interaction Center slides the incoming pane in from x: 12 (the panel's tabs) or x: 10 (the Terminals workbench's). A transfo...
Show how much coder allowance is left, live, in the Linux Desktop menu
windows is left, which window resets when, and whether what is on screen is current. It is the fact that decides whether starting a session is worth doing, so i...
A tab per open window above the maximized pane
A maximized tool window with a navigator down its left side now gets a row of tabs across the top of the column beside it — one per OPEN window of the type the ...
Keep the dock clear of every scrollbar, and let members size it
Three things about the row of docked tool windows. **It stops covering scrollbars.** The dock reserves the viewport's right edge so it does not park a window o...
Preview each logo from the org being edited, and stop hiding the software simple logo
Two defects on Behavior & Labeling, both of which make a logo that IS uploaded read as though it is not. **Every preview URL now comes from the org this pane f...
Context menus for tool window title bars and hex heads
A member with a dozen windows open could only put them away one at a time, and the only bulk gesture that existed — throwing each hex head at the goal — is a ge...
Make the logo-preview checker mid-grey, so a white logo shows
The checker shipped in 5e0fb7b2 at #e0e0e0/#fff, matching the image-to-svg tools. Rendered against real logo geometry that is wrong for this screen: a pure-whit...
Checkerboard behind the logo previews on Behavior & Labeling
The nine logo slots painted their artwork straight onto the card's own white, which hid the two things an admin is looking at: whether the file is actually tran...
Ribbon wording and a tab icon column on Behavior & Labeling
Two additions to the same page, each in the pane it belongs to. **Custom Labels** grows a Ribbon Messages box: five rows, one per public pane screen, in the or...
Give the member Careers tab the route its own gate asks for
The tab was invisible to every team member in every organization, including one looking at an open posting. Not a rights problem, though it was shaped exactly l...
Stop the header eating the priority badge in a narrow window
The ticket number and both badges sit in one nowrap row, and none of the three can give way. The number is a 19-digit int64 that must not be abbreviated. The ba...
Stop a hover control giving the message list a scrollbar
The support chat window drew a horizontal scrollbar under a conversation that had nothing to scroll sideways to. Each message's reply button is absolutely posi...
Show the member Careers tab on team membership and an open role
Two conditions, and no right among them: the viewer is a team member, and the organization has at least one posting open and taking applications. The second ch...
Make /settings/member/me the real address three callers already assume
RestrictedMembershipGuard builds it when the session's member id has not settled, the sign page's back link builds it, and kamo-login now lands a candidate on i...
Give the right-click menu the copy and paste it never had
Suppressing the browser's context menu (734f68cb) took the only copy/paste the terminal window actually had. That is not what it looked like — there are Copy an...
One refused request no longer ends the call and the session
The last way a member could lose a live call and everything in their tool windows without doing anything wrong. `authenticatedFetch` answered EVERY 401 with `w...
Choose the support topic a website's chats are filed under
The add/edit dialogs had no way to say which support queue a website's chats belong in, because the setting didn't exist — the widget sent a hardcoded "General ...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.