Skip to content

Changelog

What's new in kendo, in reverse chronological order.

Hand-to-Claude, AI attachments, and live updates everywhere

New

  • Hand to Claude. Admins can now hand an eligible issue to Claude for autonomous execution. Claude scores the issue against an eligibility rubric first; only passing issues proceed. Rolling out tenant-by-tenant.
  • AI story generation reads attachments. When generating a story from a report, the AI now pulls in attached images and text files (screenshots, plain text, CSV, JSON, Markdown) and uses them as prompt context. A per-attachment status panel shows which files were read and which were skipped, with the reason.
  • Live Reports overview. The reports list now updates in real time when teammates create, dismiss, promote, delete, or reorder reports — no refresh.
  • Quick self-assign on board cards. Click the user icon on an unassigned board card to assign yourself. A confirmation toast appears with an Undo action that reverts the assignment.
  • Sprint estimate totals on the planning view. Sprint rows on the backlog now show total estimated hours and an unestimated-issue count. A yellow chip warns when items lack an estimate; a green chip confirms when the sprint is fully sized.
  • Browser tab title reflects the page. The tab title updates to the current issue, project, or page context as you navigate, instead of always reading "kendo".
  • remaining_minutes on the Issue API. Every issue resource now includes remaining_minutes (estimated minutes minus logged minutes, or null if no estimate). Returned by the index, show, create, update, and project-scoped search endpoints.
  • --limit on kendo issue search. The CLI now accepts --limit N (default 25, max 500) on kendo issue search. A latent envelope-parsing bug that silently dropped results was also fixed on kendo issue search and kendo epic issues.

Improved

  • Faster project, board, sidebar, and team loads. Project, lane, sprint, and team responses no longer hydrate every related issue or member just to compute counts and IDs. Visible on tenants with thousands of issues — board page loads, sidebar navigation, and team settings no longer fan out a full table read per item.
  • Slimmer user responses. The unused issue_ids array was removed from user and profile resources, so /api/users no longer hydrates every listed user's full Issue rows.
  • Longer descriptions on issues, reports, and teams. Team descriptions now accept up to 5,000 characters (previously capped at 255 by the database column). Issue and report descriptions now store up to 65,535 characters regardless of emoji content.

Fixed

  • No duplicate issues from double-clicking Save. The Create, Edit, and Promote-Report forms disable the submit button while a save is in flight, so a fast double-click no longer creates duplicate issues or breaks back-navigation.
  • Issue detail page stays in sync. Issue fields, branch links, and watch status now update live across every open tab — the detail page used to require a manual refresh to see changes from another tab or tool.
  • Spurious "discard unsaved changes?" prompt on Create Issue. Opening the new-issue page and leaving without typing no longer triggers the unsaved-changes confirmation.
  • Tenant deletion now succeeds for billed tenants. Deleting a tenant in the central admin now correctly removes related subscription and GitHub install records before the tenant row. Previously the deletion failed with a database constraint error for tenants with an active Stripe subscription.
  • Issue update API no longer claims to accept attachment_ids. PUT /api/projects/{id}/issues/{slug} has dropped the attachment_ids field — it was silently ignored on update. Use the dedicated attachment endpoints to link or unlink attachments on an existing issue.

Unsaved-changes guard, password modal fix, and MCP project-context tool

New

  • prepare-project-context MCP tool. A new gather-phase tool returns the project, board lanes, active sprint, members, member count, and current user in one call. The companion prepare-issue-context tool is now slimmer — issue plus epic only — so flows that need both gather them in parallel instead of fanning out across separate kendo:// resources.

Improved

  • Pagination bar fits inside narrow columns. On the Reports overview and other narrow lists, the page navigator no longer overflows past the column edge. At narrow widths the first/last shortcuts collapse so the bar stays on a single row; at very narrow viewports the row wraps as a final fallback.

Fixed

  • Leaving an unsaved issue edit prompts before discarding. Editing any field on an issue and then navigating away — by clicking another link, hitting the back button, or closing the tab — now asks before discarding the changes. Saving clears the dirty state, so successful submits don't get a false-positive prompt.
  • Password confirm modal surfaces wrong-password errors. Entering a wrong password in the password confirmation modal now shows the inline error instead of silently closing. Cancel is also disabled while a submit is in flight, matching Confirm.

Per-issue watching and redesigned notification settings

New

  • Per-issue Watch toggle. Every issue page shows a bell next to the title — filled when you're watching, outline when you're not. Watching subscribes you to comments and status changes on that issue, even when you're not the creator or assignee.
  • Auto-watch rules. Three toggles under Settings → Notifications: auto-watch issues you create, are assigned to, or comment on. All three are on by default — turn off any you don't want.

Improved

  • Notification settings redesigned. Settings → Notifications now has two sections: Auto-watch rules and Email notifications. The email section bundles five toggles — @mentions, Issue assignment, Project membership changes, Team membership changes, and Activity on issues I follow (comments, status changes) — one row per event. The previous lane-based allowlist is gone; to stop getting activity notifications on a specific issue, click the bell on that issue to unwatch it.
  • Notification rows show read state by font weight. Bold = unread, regular = read, with a red dot still marking unread. Team-membership rows display a tooltip ("You were added to team X") and are non-clickable.
  • "Mark all as read" actually marks them all. The button now collects every unread notification when nothing is individually selected, instead of doing nothing.
  • AI Generate uses your latest report selection. Adding more reports to the AI panel after it opens now feeds those new reports into Generate. The panel previously captured only what was selected when it mounted.
  • AI Generate accepts longer merged-report prompts. Combining several sizeable reports into a single Generate request is less likely to hit a length cap — the per-request limit was widened to fit merged payloads.
  • Logged-in user pinned in assignee and creator filters. Your own name floats to the top of the assignee and creator dropdowns on Board, Backlog, Overview, and My Issues — just under Unassigned in the assignee list, and first in the creator list.

Fixed

  • Newly created report auto-selects in the detail pane. Submitting "+ Report" leaves the right pane on the new entry, so verify-and-edit is one continuous flow.
  • Promote acts on the report you can see. Checking report A, dismissing it, then clicking B and pressing Promote no longer sends A's id to the server. Dismissed reports are automatically deselected.
  • Dismissed reports leave the Selected pane immediately. No hard refresh required.
  • AI Generate works on the first click again. A wire-format mismatch caused every Generate click on Reports and Issues to surface a "source description field is required" toast; resolved.
  • Login "Remember me" persists sessions across browser restarts.
  • Billing seat count and the upcoming invoice match. The Pro billing page reads seat count from the same source as Stripe, so the displayed number always matches what's invoiced.
  • Lane reorder chevrons redraw the page on click. The up/down arrows in Project Settings → Lanes again move the lane visibly — the new order was being saved but the view wasn't refreshing.

Self-serve signup, inline images, and admin-invite tenants

New

  • Self-serve workspace signup. Anyone can sign up at central.kendo.dev/signup, click a verification email to activate the workspace, and sign in. Pricing CTAs now point straight at signup, brand-new workspaces land on an onboarding hero, and signing in before verifying surfaces a resend button with a cooldown.
  • Inline image paste in descriptions and comments. Paste screenshots straight into issue descriptions and comments — including while editing existing comments. Hovering an inline image reveals a toolbar to maximise to a lightbox, download, copy to clipboard, or open in a new tab.
  • Admin invite when central admin provisions a tenant. The tenant-create form now collects the first admin's email, first name, and last name. When the workspace is provisioned, the admin reliably receives a tailored "Your Kendo workspace is ready" welcome email with a one-click claim link.

Improved

  • File thumbnails are easier to click. The whole tile previews on click, with download and delete sitting in the footer next to a tooltip-truncated filename. Tiles and icons are also slightly larger.
  • Sidebar collapses on touch devices. Landscape phones and tablets no longer get a desktop-width sidebar squashed into the viewport — touch is detected by pointer/hover capability, not viewport width. Board cards also truncate cleanly at narrow column widths.
  • Project color dots in the sidebar match the Teams overview. The sidebar now reads from the same color source as the Teams page, so a project's accent looks identical wherever it appears.
  • Modal close button is keyboard- and screen-reader-accessible. Keyboard navigation tools and screen readers can now reach and announce the close action.
  • Loading… in English everywhere. A Dutch "Laden…" fallback that survived the April language cutover now reads "Loading…" across every async-mounted modal.

Fixed

  • First-time GitHub App install handshake is reliable. Install state is now stored server-side, so the central callback can reliably find it regardless of which tenant context is active.
  • GitHub App install flow is hardened. Stricter callback-state validation, per-user rate limiting on install endpoints, and tighter origin checks on the install popup's postMessage channel.
  • Issue activity enforces the same per-user access as the issue itself. Reaching an issue's activity timeline now requires the same permission as opening the issue.
  • AI story generation no longer leaks validation errors. Short or vague AI input is handled by the pipeline instead of dumping a raw validation error into the issue form.
  • Long project descriptions save reliably. Saving a project description longer than 255 characters used to fail with a server error; descriptions up to 5,000 characters now save as expected.
  • No duplicate "added to project" notification. Linking a team that already shared members with a project no longer fires a second "added you to project X" notification at those existing members.
  • Reports without an author show the creator's name. Reports created from the in-app form previously rendered "Unknown"; they now fall back to the creator's full name.
  • Deleting an issue unlinks promoted reports. Issues created from a promoted report can now be deleted — the linked report returns to Pending so it can be triaged again. Bulk delete handles this too.
  • Epic badge no longer overflows parent containers. Long epic names truncate cleanly within their row.
  • Comment delete confirmation stays a fixed size. The modal no longer renders the comment body inside the dialog, so the cancel/submit buttons remain reachable for long comments at high zoom.

Team-scoped user visibility and steadier real-time updates

New

  • Team-scoped user visibility. Members now only see colleagues who share a project or team with them. Workspace admins, and roles granted the new "Access all users" toggle in the role form, retain full visibility.

Improved

  • Profile pictures on the activity timeline. Each row's avatar now shows the actor's uploaded picture, falling back to initials when there isn't one.
  • Backlog, Board, and Overview search matches title and key. Description text no longer counts toward results — the placeholder reads "Search by title or key…" to match.

Fixed

  • Live updates from queued events. All real-time updates — board drags, issue edits, comments, branch links, AI progress, and more — now reliably reach other open tabs.
  • Real-time updates on long issues. Issue broadcasts now carry a slimmed-down payload, so an issue with a lengthy description no longer fails to deliver live updates to other open tabs.

Self-serve GitHub App, MCP issue intents, and a raw-markdown editor

New

  • Self-serve GitHub App connection. Settings → GitHub App now has an "Install GitHub App" button that opens a popup, walks through the install on github.com, and lands you back in kendo with the installation linked to your workspace. Once installed, the page shows the connected account name and type plus a Disconnect button — no manual configuration step.
  • assign-issues-to-sprint MCP tool. Move up to 100 issues into, between, or out of a sprint in a single call. Replaces the per-issue update-issue loop agents were running for sprint planning.
  • start-work-on-issue MCP tool. One call assigns the issue, moves it into a lane, optionally sets its sprint, and links a branch — the multi-step pickup workflow agents were running by hand collapsed into a single intent.
  • prepare-issue-context MCP tool. One call returns the issue, its epic, the project's active sprint, all lanes, and the calling user — replacing four separate kendo:// resource reads.
  • Raw markdown toggle in the rich text editor. A new </> toolbar button swaps the editor for a plain textarea showing the markdown source. Format buttons grey out while in raw mode.
  • H1 / H2 / H3 buttons in the rich text editor. Three new heading buttons in the toolbar, separated from the inline-format buttons by a thin divider. Heading sizes inside the editor now match the rendered description.
  • Backlog tab before Board. Project navigation lists Backlog → Board, matching the issue lifecycle order. The default landing for /projects/:id is unchanged.

Improved

  • My Issues badge and page update live. The sidebar count and the issue list both reflect newly-assigned, dragged-to-Done, and self-assigned issues without a refresh, including changes made via MCP.
  • Sprint dropdown hides completed sprints. When picking a sprint on an issue, the dropdown only offers active and planned sprints. If the issue is already linked to a completed sprint, that sprint stays visible so saving doesn't silently unlink it.
  • Issue Show page card matches the detail-page pattern. Card padding and corner rounding line up with the rest of the app, and badges no longer stretch to full width inside column layouts. The doubled border under the user profile settings list is gone too.
  • Delete confirms name the action. Confirmation dialogs show "Delete sprint" or "Delete epic" instead of a generic "Confirm".
  • Issue tab labels match section header sizing. Small typographic polish on the issue detail page.

Fixed

  • Clearing a title or description no longer drops the save. Form fields cleared by the user now send null instead of an empty string, so the server correctly distinguishes "no value" from "value too short" and the change goes through. Regression from the validator pass two weeks ago.
  • Assignee avatars on the Activity tab. Assignment changes in the activity timeline now render the user's avatar instead of a broken-image placeholder.

Central admin dashboard, issue activity, and a live inbox

New

  • Central admin dashboard. A new Overview page on the central admin app with stat cards for tenants, domains, users, and waitlist, a GitHub card showing how many tenants are connected, and drill-down tables for the 5 most recent tenants, tenants without GitHub, and unclaimed installations. Stat cards click through to their detail pages.
  • Issue Activity tab. A read-only timeline on every issue detail page, showing who changed what and when — status pills, priority and type icons, assignee avatars, sprint and epic pills, and expandable word-level diffs for title and description. Newest-first, grouped by day.
  • Live inbox. The notification badge in the navbar and the inbox list now update live across every open tab. No more reloading to see a new notification, and "mark all as read" reflects everywhere instantly.
  • Live sprints, epics, and lanes. Boards, backlogs, and epic overviews now stay in sync across tabs in real time when someone else creates, renames, or deletes a sprint, epic, or lane — no refresh needed.
  • Live branch links. The git branch sidebar on an issue updates live when teammates link, edit, or unlink a branch.
  • Bulk-assign issues to an epic. From the backlog, select multiple issues, switch the action bar to "Epic" mode, and pick an epic (or "No epic" to clear). All selected issues update in one go.
  • Auto-fill start time on the time entry form. Tick the new "Auto-fill start time" box and the start time is computed from the duration as you type. Existing entries are left alone until you edit the duration. Your preference is remembered across sessions.
  • Edit which projects a tenant AI key applies to. Tenant AI key cards now show "Allowed on N projects" or "Allowed on all projects" with an Edit button, so you can change the scope of an existing key without recreating it.
  • Pagination on the Reports overview. Page-size selector (10, 25, 50, 100) below the reports list. The page resets when you change the status filter or search.

Improved

  • You float to the top of assignee and creator filters. On the issue list pages, the active user is now pinned at the top of the multi-select dropdowns — no scrolling to filter by yourself.
  • Dropdowns cap at 500px on wide screens. Select dropdowns no longer stretch across the page on big monitors. Inside modals and on mobile they still fill the available width.
  • Consistent text-area sizing. Multi-line text fields are now the same height and padding everywhere; the same field used to look noticeably taller inside modals than on plain pages.
  • Restyled rich text editor toolbar. A compact pill of icons inside the editor instead of a full-width header strip, with subtler buttons and a red focus glow that matches the rest of the form.

Fixed

  • Selected values in dropdowns no longer look empty. Picked Epic, Sprint, and Assignee values now render in solid text instead of the muted placeholder color, so a filled field doesn't look unset.
  • Multi-line text fields read more easily. Bumped line spacing so paragraphs in textareas no longer feel cramped, including the Log Time modal where text was rendering noticeably small.
  • Removed the redundant "issue updated" toast. The "Alert: updated by " pop-up was duplicating live updates that the board, backlog, and issue overview already show. It's gone.
  • Board no longer goes blank if a saved filter is in a bad state. Old or hand-edited filter values in browser storage used to crash the page; they now fall back to defaults.
  • Activity tab badge is correct on first paint. The activity count on the tab used to read 0 until you opened it. It now reflects reality immediately.
  • Activity tab error state. When fetching activity fails, the tab now shows a dedicated error message instead of looking like an empty timeline.
  • AI generation no longer fails the whole request when realtime is down. AI progress toasts may lag, but the underlying request completes instead of erroring out.

VS Code extension, Kendo Today MCP widget, and live comments

New

  • VS Code extension. A VSC-Kendo sidebar showing the active sprint's issues, browseable by lane via tabs and split within each lane into Assigned to Me, Unassigned, and Assigned to Others. Per-issue actions let you move issues between lanes, create or open a GitHub branch for an issue, and assign or unassign yourself. Sign in with a personal access token stored in VS Code's secret storage.
  • Kendo Today MCP widget. A sandboxed iframe mini-app that renders inline in Claude Desktop. Initial data arrives via the kendo-today-tool result on spawn; users can log time via per-issue quick-log chips and open issue deep-links in the default browser.
  • Live comment updates. Comment create, update, and delete mutations broadcast on the comments channel, so other open tabs see them live without a refresh — the same pattern already powering live issue events.

Improved

  • Tighter Stripe outbound timeouts. Billing API calls use explicit 10s total / 5s connect timeouts instead of the SDK's 80s / 30s defaults, so misbehaving upstreams fail fast instead of hanging interactive flows.

My Issues, live boards, timetracking measurements, and MCP polish

New

  • My Issues page. Every open issue assigned to you, across every project — with search, six multi-select filters (project, lane, epic, creator, priority, type), and sortable columns.
  • Timetracking measurement switcher. Choose Hours, 7h, 7.5h, or 8h workdays and every duration on the page (summary, totals, per-entry, modal inputs) re-renders in that unit. The choice is saved in your browser and applies across the summary card, time-entry table, and entry form.
  • Live create and delete. Cards appear and disappear across every open tab as they happen.
  • Public changelog at kendo.dev/changelog. A single-page feed of dated entries, newest first.
  • "What's new" sidebar link. New entry in the tenant sidebar opens the changelog in a new tab, with a "new" pill (or a red dot when collapsed) for 4 days after the latest entry ships.
  • Board moves now appear in the audit log. Reorders are recorded alongside other issue changes.
  • Search truncation banner. Board, Backlog, Overview, and My Issues show "Showing first 500 matches. Refine your search to see more." when the server-side cap is hit.
  • fetch_attachment returns image attachments. Image content now comes back inline in the MCP response — the image path was previously broken.

Improved

  • Batched board reorders. Multi-card drags fire one UPDATE instead of one per card.
  • Live updates apply instantly. Issue changes from other users now show up in the board, backlog, and overview without a follow-up round-trip — the listening client used to refetch each updated issue.
  • MCP tools no longer show a phantom error on claude.ai web. Successful tool calls were displaying a generic "Error occurred during tool execution" because the response shape didn't match what the spec requires; 28 tools were migrated and now render correctly.
  • MCP search tools surface truncation. search_issues and get_my_issues now return truncated and limit in their response so MCP callers know when the 500-result cap was reached.
  • search_issues is faster and reliable. The tool was throwing on every call on staging and silently making three extra database lookups per result on production; both paths are fixed.
  • Time entries default to newest-first by start date. The All Entries table now sorts by when work happened, not when the entry was recorded. Entries without a start time fall back to creation date.
  • Inline measurement pills on the time summary. The measurement selector on the All Entries page moved from a dropdown with a help icon to a segmented pill control tucked inside the Total card.
  • Admin UI is permission-gated. Teams overview, User Management, and the Roles link are hidden from regular members — they only see admin surfaces their role permissions explicitly grant.
  • Single git-checkout box on issue pages. The "git checkout -b" suggestion box is now hidden whenever a branch is already linked or another branch form is open, so it no longer stacks visually on top of the per-branch checkout boxes.

Fixed

  • Hardened Stripe webhook verification. Misconfigured deployments now fail at boot instead of accepting traffic.
  • fetch_attachment error handling. Unexpected errors now return a clean message instead of an internal exception.
  • send_feedback error responses. Returns a clean message when the feedback service is unavailable.
  • OAuth consent screen. MCP connections via Claude Code now go through the standard authorization consent flow on first connection. (Claude Desktop is not yet supported.)
  • VITE_REVERB_HOST example. Corrected the value in .env.example for local dev.

Bigger search results and a status filter for reports

New

  • Status filter on list-reports. The MCP tool accepts an optional status integer — 0 (Pending), 1 (Promoted), or 2 (Dismissed) — and the kendo report list CLI accepts --status pending|promoted|dismissed.

Improved

  • No more dropped cards on large boards. Board, Backlog, and Issue Overview were silently using the /search endpoint's 25-item default because no limit was passed, dropping cards on bigger projects. The pages now pass limit=500 explicitly, and the endpoint's hard cap was raised from 100 to 500 to match. The 25-item default is kept for CLI and MCP callers.

MCP attachments, deep-linked reports, and a backend proxy for images

New

  • fetch_attachment MCP tool. Agents can read image and text attachment content inline via MCP — images up to 5 MB, text up to 500 KB. Binary formats like PDF and video fall back to the existing download URL.
  • send_feedback MCP tool and kendo feedback send CLI. Submit feedback (title + description) straight from an AI assistant or the terminal.
  • Synthesised title in feedback submissions. Feedback sent from the in-app widget is automatically attributed to the authenticated user — no title field to fill in.
  • Deep-linkable reports. Every report now has a hover-revealed copy-link button for sharing, plus a new GetReport MCP tool and kendo://reports/{id} resource so agents can fetch a specific report directly.
  • Backend proxy for images and attachments. Profile pictures and attachments now serve through stable backend routes instead of expiring signed S3 URLs, fixing intermittent broken-image errors.
  • create_task agent intent handled. The frontend now correctly handles the create_task classification from the AI assistant — previously it fell through to a generic handler.

Improved

  • Scoped /search on Board, Backlog, and Issue Overview. Listings now fetch a scoped page instead of a full project dump. New filters (sprint_id, include_backlog, sprint_status, since) let each page ask for exactly the slice it renders.
  • Slim update-board response. Board moves return only the changed positions; the frontend merges them in place, skipping a post-drag refetch.
  • Board and Backlog query params. Board was sending sprintStatus[]=ACTIVE and returning every recently-updated issue in the project because the tenant http middleware only snake-cases request bodies, not query params. Board now filters by sprint_id; Backlog switched to include_backlog=1 + snake_case keys.

Fixed

  • Password reset clears pending invites. Using the forgot-password flow to reset a password now also wipes any pending invite token, so the "resend invite" button no longer stays visible after the invite is consumed.
  • Notifications are cleaned up on project or team delete. Deleting a project or team now removes associated notifications, keeping the inbox stable.
  • Password-reset link error handling. Expired or invalid password-reset links now return a proper error response instead of a server error.

Stripe billing, tighter AI errors, and an AI-bot cleanup

New

  • Stripe billing, end to end. Subscriptions, signature-verified Stripe webhooks, tenant billing pages (status / checkout / portal, gated behind manage-billing for admins), and a central-side admin surface (grant admin-granted Pro, revoke it, or cancel a Stripe subscription). Currency: EUR.
  • Free-tier limits enforced. Inviting a fourth seat, creating a second project, or restoring a soft-deleted user past the 3-seat cap now returns 402 Payment Required. After a downgrade, issue creation in "excess" projects (everything past the single free project, oldest kept) is blocked with 403 Forbidden.
  • User-facing AI error messages. AI provider errors now return the right HTTP status instead of a generic 500: rate-limited → 429, provider overloaded → 503, request too large → 422, generic provider error → 502.

Improved

  • Unified select component across forms. Delete-role, pagination, epic, and AI-key forms now use the design-system single-select, replacing the old native-<select> wrapper.
  • My Issues badge refreshes on self-assign. Assigning yourself from an issue detail page immediately updates the sidebar badge — previously it waited until you navigated to My Issues.
  • Profile issue counter matches My Issues. The profile sidebar now excludes Done-lane issues, so the count stays consistent with the My Issues overview.
  • AI agent/bot assignment removed. The entire surface is gone — no more bot-assignable user, AI-run tables, or is_bot flag.
  • Audit log integrity. Audit-log writes enforce hash-chain consistency under concurrent load.

Fixed

  • OAuth invite with an already-linked provider. Completing an invite with a provider already linked to another account now returns a provider_already_linked error cleanly, for both invite and link flows.