KamoCRM

Live Change Log

Every feature, fix and improvement, posted as it ships. Nothing is held back for a launch.

17,393
Total Changes
5,908
Features
5,260
Fixes
30
Projects
Filter by project
All Projects17,393AIService242APIService174BillingService157ConversionService110DaemonService137DocsService223ESigService91EmailService568InitializerService329KBService151KlusterServices738MCPGatewayService235MediaService592RAGService79SecurityService1,829TranslateService62VOIPService248VectorService11kamo-apps26kamo-asterisk-support27kamo-capcha17kamo-capcha-widget4kamo-internal8,327kamo-login335kamo-marketing641kamo-nowww20kamo-register213kamo-shared-library1,637kamo-signer-monorepo56kamolos114
Filter by type
All TypesBuild16CI523Chore773Docs3,252Feature5,908Fix5,260Other993Performance165Refactor278Revert23Style42Test159Upgrade1
April 27, 2026
FixAPIService

Carve /api/voip/recordings/** out of the wildcard VOIP forwarder

The /api/voip/** catch-all in APIGatewayController was shadowing the dedicated VoipRecordingUploadController POST /api/voip/recordings/upload mapping when Sprin...

Kamo·6mo ago
Fixkamo-asterisk-support

Write managed config files 0644 so the asterisk daemon can read them

The kamo-asterisk-support pod runs as root and writes to host-mounted **************** Asterisk inside the FreePBX pod runs as user "asterisk" and could not rea...

Kamo·6mo ago
Fixkamo-asterisk-support

Use envsubst-compatible \${VAR} syntax in config template + re-render on stale placeholders

Pods were CrashLoopBackOff with "config errors: API_KEY is missing or too short" because the config template used literal __API_KEY__ markers that envsubst sile...

Kamo·6mo ago
Fixkamo-asterisk-support

Drop unused watcher import

uploader.go only uses CallBatch (declared in grouper.go in the same package), not anything from internal/watcher directly. Go rejects unused imports.

Kamo·6mo ago
FixDaemonService

Enable JPA repos for commerce + email + dao.repositories packages

DaemonService crashed on startup with: Parameter 0 of constructor in **************** required a bean of type **************** that could not be found. A r...

Kamo·6mo ago
FixVOIPService

Capture newExtNumber as final for lambda capture in MemberVoipConfigController

newExtNumber is conditionally reassigned inside the if (isVoipEnabled && ...) block, which makes it not effectively final. The TeamMember sync block reads it fr...

Kamo·6mo ago
Fixkamo-internal

Cast voiceActivityDetection to bypass missing TS DOM type

voiceActivityDetection is a valid WebRTC MediaTrackConstraints property but is absent from TypeScript's DOM lib, causing a type error at build time.

kamo·6mo ago
April 26, 2026
FixKlusterServices

Configure STUN so browser ICE can complete bidirectionally

Two-party browser-to-browser calls connected at the SIP layer but had no audio either direction. Voicemail (one-way Asterisk → browser) worked because Asterisk'...

Kamo·6mo ago
Fixkamo-internal

Live audio that survives load-interrupts, centered spinner, outbound ringback

Three coordinated fixes for the in-call audio path: 1. AbortError on remoteAudio.play() (visible in production console as "The play() request was interrupte...

kamo·6mo ago
Fixkamo-internal

Hangup tears down ALL live sessions, not just the primary

Self-call edge case left a session leaked: dialing your own extension creates an outbound session, then Asterisk loops the call back as a second inbound session...

kamo·6mo ago
Fixkamo-internal

Instant connecting feedback on outbound dial

Same problem the inbound Answer button had: clicking Call kicked off the SIP INVITE round-trip (1-3 seconds) but the button kept its idle "Call" appearance the ...

kamo·6mo ago
Fixkamo-internal

Connecting animation + audio that actually plays + ringtone unlock

Three coordinated fixes for the inbound-call path: 1. Visual feedback while accepting. Clicking Answer left both buttons responsive-looking but unresponsive...

kamo·6mo ago
Fixkamo-internal

Mount SoftphoneProvider above ToolDock so tool windows can read it

Opening the Softphone popup crashed the page with "This page couldn't load" because tool windows mount inside ToolDock, which lives in ToolProviders — a SIBLING...

kamo·6mo ago
Fixkamo-internal

Use Grid size prop so AV panels fill the row

MUI v7's Grid is flexbox-based, so the gridColumn sx I'd been using was a no-op — items rendered at their natural width and left empty space on the right. Switc...

kamo·6mo ago
Fixkamo-internal

Migrate stale ringtone IDs to default on load

If a user's saved AV preferences reference a ringtone that no longer exists in the catalogue (e.g. 'classic' from before the catalogue was trimmed), the Rington...

kamo·6mo ago
Fixkamo-internal

Dialpad digits now register on touch devices

The dialpad buttons called e.preventDefault() in both onTouchStart and onTouchEnd. That stops the browser from firing the synthetic click event that follows a t...

kamo·6mo ago
FixKlusterServices

Host browser SIP WSS on internal.kamocrm.com (real cert)

Browsers refused the WebSocket connection to **************** with close code 1006 because Traefik was serving its self-signed default cert for that hostname (n...

Kamo·6mo ago
Fixkamo-internal

Separate globe presence for marketing live chat vs members

Public Chat widget tickets keep org placeholder as requestorId; use only media session presence for those rows. Internal and other tickets use member presence (...

kamo·6mo ago
Fixkamo-marketing

Periodic STOMP presence heartbeat for public support

Refresh Redis TTL for public session presence so agents see accurate online state.

Kamo·6mo ago
Fixkamo-internal

Globe uses media session presence for marketing visitors

Request public-chat session GUIDs in presence snapshot; treat online if either session or requestor member is connected. Handle snapshot envelope and sessionGui...

kamo·6mo ago
FixMediaService

Track public support chat by session GUID in Redis

Marketing visitors use /ws/public-chat-native without memberId; tickets still reference the org placeholder member as requestor. Increment PRESENCE_PUBLIC keys ...

Kamo·6mo ago
FixVOIPService

Don't wipe member assignment on sync from providers that lack metadata

**************** unconditionally overwrote PhoneExtension.assignedMemberId with whatever the provider returned. FreePBX (and any provider that doesn't track whi...

Kamo·6mo ago
Fixkamo-internal

Show provider name in view mode + own extension in edit dropdown

Two bugs on **************** 1. View mode dumped the raw UUID — "Instance 32f520b0-347a-…" — because the instance list was only loaded inside handleVoipEdit...

kamo·6mo ago
Fixkamo-shared-library

Serialize ExtensionDto.assignedMemberId as a string

overflows JS's safe-integer range (e.g. 1168485658174423046 round-trips as 1168485658174423000 once a JSON number hits the browser). The frontend already typed ...

Kamo·6mo ago
FixKlusterServices

Make WebRTC config survive pod restart

The previous approach (http_custom.conf with [general] override) didn't actually take effect because Asterisk's INI parser doesn't honor multiple [general] sect...

Kamo·6mo ago
FixKlusterServices

Enable Asterisk built-in HTTP server on :8089 for WebRTC /ws

A chan_pjsip `protocol=ws` transport rides on top of res_http_websocket, which in turn requires Asterisk's built-in HTTP server to be running. The default FreeP...

Kamo·6mo ago
FixSecurityService

Prioritize real first/last name over usernameAlias for display

usernameAlias is functionally a login handle (often equal to username), not a display name. Real human-readable names live on User.name (EmbNameFull). Apply to ...

Kamo·6mo ago
Fixkamo-internal

Scope Add Lead scroll and footer to its content area

The form was using minHeight: 100vh inside a parent that's already calc(100vh - 56px), forcing an outer scrollbar even when content fit. The action bar also use...

kamo·6mo ago
Fixkamo-internal

Smart multi-column layout for Add Lead form

Restructure the page into a top-level grid so sections compose horizontally instead of stretching individual fields: - Market & Assignment uses a 3-col interio...

kamo·6mo ago
Fixkamo-internal

Use /api/security/members/names for assigned-member name resolution

The by-department endpoint filters to active TeamMembers only, missing assignments to base Members or inactive members. Switch to /names which returns all membe...

kamo·6mo ago
Fixkamo-internal

Full-width Add Lead form and clearance for sticky footer

Drop the 1200px max-width on /leads/new so the form spans the page area, and bump bottom padding so the sticky action bar no longer overlaps the last form secti...

kamo·6mo ago
FixSecurityService

Resolve display name with correct priority in by-department endpoint

Priority: member.usernameAlias → user.name.formatFull() → user.alias → user.username

Kamo·6mo ago
Fixkamo-internal

Probe master model endpoint and fix appliedModel org ID

- Replace appliedModel.source-based gate with a direct probe of /api/security/master-model on mount; r.ok=false (409) means the org is governed by a branch ...

kamo·6mo ago
Fixkamo-internal

Gate censorship tab options by applied model constraints

- Hide EDIT MASTER MODEL button when org is governed by a branch type (use appliedModel.source instead of unreliable org context branchTypeID) - Hide ATF fiel...

kamo·6mo ago
Fixkamo-internal

Mark-as-read and message fetch for shared/member mailboxes

Classic mode now loads shared mailbox messages via the correct /messages/{folder} endpoint (was calling the non-existent /conversations endpoint). Fetching a fu...

kamo·6mo ago
FixEmailService

Mark-as-read for shared and member mailboxes

EmailController.setFlags now accepts an optional mailboxId query param and routes through resolveProviderWithMailbox so member-mailbox flags are set against the...

Kamo·6mo ago
FixVOIPService

Use extensionId as external ID, not Relay node id

FreePBX returns the same Relay id (ZXh0ZW5zaW9uOg== = "extension:") for every extension because the id field is not populated. Using it caused all extensions to...

Kamo·6mo ago
FixEmailService

Handle IMAPInputStream in getMessage to prevent ClassCastException

JavaMail can return an IMAPInputStream instead of a decoded String from part.getContent() when message content has not been pre-fetched. The direct (String) cas...

Kamo·6mo ago
FixVOIPService

Rewrite all GQL queries/mutations against live schema introspection

Verified every field name and type against the actual FreePBX 17 schema. Full set of corrections: Queries: - fetchAllExtensions: remove non-existent 'voicemail...

Kamo·6mo ago
Fixkamo-internal

Pass selectedFolder to ThreadDetailView so email:folder-changed fires with a valid folder

conversation.folder is always undefined because the Java ConversationEntity has folderIds (text[]) not a folder string field. This caused loadThread to call mar...

kamo·6mo ago
FixVOIPService

Correct GraphQL field name to fetchAsteriskDetails

FreePBX API returns "Did you mean fetchAsteriskDetails?" — rename the health check query and its data path accessor accordingly.

Kamo·6mo ago
FixVOIPService

Add XHR/Accept headers and String response parsing to GraphQL client

Same pattern as FreePBXTokenCache: add X-Requested-With + Accept: application/json to suppress FreePBX's HTML redirect responses, and switch all three call site...

Kamo·6mo ago

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing