Skip to content
KAMOUniverse

Changelog

What's new.

Every improvement to the platform, as it ships.

  1. · kamo-shared-library

    Repository queries for exact-match find, paged list, receipts

  2. · kamo-shared-library

    Add dateLastViewed to MediaSessionMember for receipt timestamps

  3. · kamo-shared-library

    Add isAccessRevoked flag for per-attachment access control

  4. · kamo-marketing

    Distinguish actively-translating vs queued messages

    The translation queue was already sequential, but every queued bubble rendered "Translating…". Now the single in-flight message shows "Translating…" with a pulsing dot and the rest show "Pending Translation…" with a static dot, so the visitor can see the queue progressing.

  5. · kamo-internal

    Distinguish actively-translating vs queued messages

    The streaming queue was already strictly sequential (one fetch at a time), but every queued message rendered "Translating…" because they all shared the same pendingTranslation flag. Split that into two states: the single message currently in flight shows "Translating…" with a pulsing dot, all the other queued messages show "Pending Translation…" with a static dot. Live (just-arrived) messages are translated alone and start in the active state.

  6. · kamo-marketing

    Show error icon when a message fails to translate

    When the per-message translate call returns translated:false, errors out, or times out, the chat bubble now renders an AlertTriangle icon in red with tooltip "Failed to translate message." instead of silently leaving the bubble in the original language.

  7. · kamo-internal

    Show error icon when a message fails to translate

    When the per-message translate call returns translated:false, errors out, or times out, the chat bubble now renders a small red ErrorOutline icon in place of the translate badge with tooltip "Failed to translate message." instead of silently leaving the bubble in the original language. The flag is reset whenever the user picks a new language so a re-attempt can succeed without the stale error sticking around.

  8. · kamo-marketing

    Stream translations newest-first for visitor history

    When the visitor lands on a non-English locale and the support chat has existing English messages, every bubble flagged needsTranslation by the backend now shows a "Translating…" placeholder while a streaming queue fills them in one at a time, starting from the newest message. A generation counter prevents stale queues from clobbering current state.

  9. · kamo-internal

    Stream message translations newest-first on language switch

    When the user picks a new language (or opens an existing chat in a language different from the messages' source), every bubble that needs translation immediately renders a "Translating…" placeholder and the translations stream in one at a time starting from the most recent message and working backwards. This includes the user's own past messages — anything authored in a different language than the viewer is now translated. A generation counter cancels in-flight queues if the user changes language again.

  10. · kamo-marketing

    Auto-translate visitor and agent messages

    Live agent replies arriving in a language other than the visitor's URL locale now show a "Translating…" bubble while the TranslateService call resolves, then swap to the translated text with a Languages badge whose tooltip shows the source language and the original message. Visitor messages are tagged with the URL locale on send so the agent's chat can translate them into the agent's profile language. Messages loaded into history are translated up front via the new ?lang=<locale> query param on /api/chat/support.

  11. · kamo-internal

    Translate chat messages into the viewer's language

    Adds a "My Language" flag picker in NavTop (left of the email tool, separated by a vertical rule). Selecting a language writes back to Member.language and syncs the locale cookie so the entire UI switches; it also broadcasts an event that any open ChatBox uses to re-fetch its history in the new language. ChatBox now fetches messages with ?lang=<locale>, renders translated bubbles with a small Translate badge whose tooltip shows the original text and source language, and shows a "Translating…" placeholder for live messages until the TranslateService call returns. The send path tags every outbound message with the author's locale so other viewers can translate it on demand.

  12. · APIService

    Proxy support-message translate endpoint

    Adds a passthrough route for the new MediaService endpoint that translates a single support-chat message into the visitor's URL locale. The marketing-side chat widget hits **************** which the gateway now forwards to MediaService with the standard public-chat auth and rate-limit checks.

  13. · MediaService

    On-demand translation for chat and support messages

    Captures the source language for every chat / support message and adds an optional ?lang=XX param on the message-fetch endpoints plus a per-message POST /translate endpoint. MediaService now talks to TranslateService via TranslationServiceClient, and MessageTranslationService caches results in MediaObjMsgTranslation so the same translation is never paid for twice. Wires the same flow into the public-chat (visitor) path: visitors send their URL locale as sourceLanguage, and the agent / visitor sides each pull translations into their own preferred language. Adds the translate-service secret to the MediaService deployment so the new client can authenticate.

  14. · kamo-shared-library

    Translation cache for chat messages

    Adds the MediaObjMsgTranslation entity (one row per (message, language) pair) and an optional sourceLanguageId column on MediaObjMsg so chat messages can be translated on demand and re-served instantly to other viewers in the same language. ChatMessageDto carries sourceLanguageId so live recipients know whether they need to translate. MediaService.createMessage gains an overload that takes the authoring language, falling back to Member.language for legacy callers.

  15. · kamo-internal

    Add Personal + Chat/Docs/Notes/KB/HRS sections

    The /settings index showed no sections to non-admins because every existing section was gated on an admin right (CONFIGURE_SYSTEM, MANAGE_*_SETTINGS, MANAGE_ACCESS_RULES). A regular team member with only support rights saw exactly 3 cards (Topics, Analytics, Scheduled Support) and nothing else. Add an always-visible Personal section (My Profile, Audio & Video, Account Activity, and Plans & Billing on child orgs) that links to the viewer's own /settings/member/<myId> tabs — so settings is never empty, regardless of org-level rights. Also surface the previously-missing Chat / Docs / Notes / Knowledge Base / HRS sections — each gated on the corresponding org feature flag plus the appropriate MANAGE_*_SETTINGS right — to match the dedicated /settings/features/<app> pages that already exist for those apps.

  16. · kamo-internal

    Rotate goal opening based on viewport aspect ratio

    The goal frame now tilts by atan2(viewportH, viewportW) so its open right side aims toward the viewport diagonal — for 16:9 monitors the opening points ~29° south of east; for portrait it points closer to south. Reads the way users naturally throw heads from the bulk of the screen back toward the upper-left corner. Physics: goal collision now runs in goal-LOCAL coords. Each thrown head's center+velocity rotate into the local frame, the existing AABB collision against axis-aligned walls runs unchanged, then any push-out and velocity reflection rotates back to world space. The score zone check is also done in local coords so a head genuinely entering the (rotated) opening still scores. Visual: the SVG frame + entry-side glow live inside a rotation container; celebration overlays (GOAL!/MISS!) and the REMOVE caption sit outside the rotation so text stays readable. Miss-shake now oscillates around the base angle instead of zero. Goal angle is recomputed on viewport resize via a state setter, with a parallel ref so the throw RAF reads the latest value each frame without re-creating the callback.

  17. · kamo-internal

    Throw-to-remove goal with score/miss celebrations

    A 132×132 goal frame appears in the upper-left whenever a head is in solo-drag or active-throw, offset 56px from the corner so heads can miss past or behind it. Three solid walls (top, left, bottom) act as elastic bounce surfaces (0.65 restitution); the right side is the open entry. A bold red X in the back panel makes the "remove" intent unmistakable, and a pulsing entry indicator marks the open side. When a thrown head's center crosses into the score zone, it's removed from the throw map, the underlying tool window is closed via tool:close, and the head is removed via removeHead. A green radial flash, 18-particle gold/orange burst, and a bouncing GOAL! overlay fire on score. When a thrown head merely bounces off any goal wall (debounced by 350ms so a single fail doesn't spam events), the goal shakes red and a MISS! overlay punches in. Stability: goal collision lives entirely inside the throw RAF loop (no spring-system contention), and HexHeadGoalZone owns all celebration state internally — the engine only fires events. Pure additive feature; non-throw drag/drop paths are unchanged.

  18. · kamo-internal

    Throw physics with pool-table collisions and comet trail

    Flicking a head past the throw threshold launches it across the viewport under explicit physics (friction, edge bounce, head-vs-head elastic collisions). Slow drops still land exactly where released. While the head is in motion an arcade-style fire trail follows it. Throw is gated by both release velocity (>= 650 px/s averaged over the last ~110 ms) and total drag distance (>= 30 px) so a quick precise re-position never accidentally triggers a throw. Magnitude is capped at 3200 px/s to keep edge-of-detection flicks tame. The throw RAF loop drives motion-value writes directly via .set() — bypassing framer-motion springs while in flight — and self-stops when all heads drop below the stop-speed threshold. placeHomeCluster and softPushCluster skip any anchor currently in the throw map so the spring system never fights the physics integrator. Struck heads detach from any cluster, promote to a solo cluster, and join the throw simulation with the impulse imparted by the collision. Trail rendering: SVG layer with radial-gradient embers along recent positions, mix-blend-mode: screen for additive glow, single CSS blur filter for softness — arcade aesthetic, near-zero CPU cost.

  19. · kamo-internal

    Use server-minted OTK to switch into new org

    Prefer the otk returned by POST /api/security/org over the follow-up /api/security/enter-as round-trip. The server now mints a fresh owner session as part of org creation, so the post-create redirect to the new org's /validate is deterministic — no race with domain creation, no silent enter-as failure leaving the creator on the parent-org session.

  20. · SecurityService

    Mint owner ***+OTK on org create

    After createOrganizationOwner, mint a fresh *** bound to the new owner TeamMember and return its OTK alongside id/members. Without this the creator stays on the parent-org session — limited rights and isOrganizationOwner=false — so the new child org's settings page appears gated and Plans & Billing is hidden until they manually re-enter.

  21. · kamo-shared-library

    Self-heal unprovisioned COMP orders on startup

    On @PostConstruct, scan all APPROVED COMP orders and provision any that lack an AccountSubscription. Idempotent — find-or-create means safe to run repeatedly.

  22. · kamo-internal

    Move availability status dropdown to left side before My Businesses

    Relocates the status pill from the right action bar to the left welcome section, placing it between the greeting separator and My Businesses with a divider. Removes the now-orphaned vertical rule that previously separated the status from the icon buttons.

  23. · kamo-internal

    Add targetOrganizationId to SubscriptionOrder types and createSubscriptionOrder

  24. · SecurityService

    Add provision-comp endpoint to activate COMP subscription from approved order

    POST **************** calls **************** then invalidates entitlements for the target org via EntitlementService.

  25. · kamo-shared-library

    COMP order approval auto-provisions AccountSubscription and assigns license

    - SubscriptionOrder: add targetOrganization (nullable FK to orgs) - **************** add targetOrganizationId string - AccountRepository: add findByPrimaryMember_Id for account lookup by holder member - SubscriptionService: inject billing repos; provisionCompSubscription creates/upserts **************** SubscriptionMember, and ACTIVE AccountLicense for the target-org member; approveOrder calls it for COMP payment method; new activateCompOrder for retroactive provisioning of existing APPROVED COMP orders

  26. · kamo-internal

    Replace click-to-open with action popover + size controls

    Clicking a hex head now opens a polished glass-morphism popover with contextual actions instead of immediately opening its tool window. Member chat heads expose: Open Chat, View Account, Email, Invite to Meeting, Call (when both sides have a registered VOIP extension); tool heads expose Open <toolName>. A Size sub-menu lets the user pick small/medium/ large for that specific head (persisted per member via the new MemberUiPreference store) plus a global scale slider that affects every hex head on this machine (persisted in localStorage). Tool windows now clamp width/height to the viewport so they never open partially off- screen even with shrunken windows.

  27. · InitializerService

    Add MEMBER_UI_PREFERENCES table (order 60)

    Idempotent CREATE for the generic per-member UI-preference store backing the hex-head popover size selector and future per-member UI settings. Schema mirrors the EmbRecordState convention (is_active, date_created, date_updated) used elsewhere in the data model.

  28. · SecurityService

    Add MemberUiPreferenceController for per-member UI settings

    Backs the new hex-head popover size selector and any future small per- member UI preference. Endpoints under /api/security/members/me/ui- preferences resolve the member from the OTK session and read/write JSON values keyed by an opaque prefKey string.

  29. · kamo-shared-library

    Add MemberUiPreference entity for per-member UI prefs

    Generic per-member UI preference store (memberId, prefKey, JSONB value) for small persisted UI settings. First consumer is the hex-head popover size selector.

  30. · kamo-internal

    Wire FeaturesManager to platform subscription for child-org gating

    FeaturesManager was calling legacy **************** which throws (ungated fallback) instead of reading the real platform subscription. Now calls **************** which queries the root org's commerce subscription orders for the caller's cross-org membership. When the caller has an APPROVED COMP order on the root org, all feature gates open as expected for comped child-org admins.

Your universe is waiting.

Start free in minutes. Add products whenever you are ready — no migration, no new logins.

Free forever — no credit card required