Repository navigation
Releases: Miragon/pulse
Releases · Miragon/pulse
Release list
v0.21.0
0.21.0 (2026-10-16)
⚠ BREAKING CHANGES
- the npm packages are now @miragon/pulse-widget-shell, @miragon/pulse-camunda7-client, @miragon/pulse-camunda7-connector, @miragon/pulse-analytics-client and @miragon/pulse-analytics-connector (subpaths unchanged; the @miragon-ai packages are deprecated). The server image is ghcr.io/miragon/pulse-server on the GitHub Container Registry; the Docker Hub image miragon/miragon-ai-server stays frozen at 0.20.0. The repo is Miragon/pulse, the starter Miragon/pulse-starter, the playground https://pulse-playground.miragon.ai/mcp. The MCP server introduces itself as pulse (title "Pulse") and logs as [pulse]; the examples register it as pulse. See "Renamed from miragon-ai" in the README.
Code Refactoring
- rename the repo and everything it ships to Pulse (0bab7b9)
v0.20.0
0.20.0 (2026-10-13)
⚠ BREAKING CHANGES
- widget-shell:
inlineRowBudget,DEFAULT_INLINE_ROWSandInlineBudget.rowsare gone, replaced by the measured fit (InlineFitBox,useInlineRows).RowsBudgetedtakes the paged list'srows.PagedViewDatagainsfitandfooterLabels. - camunda7_show_user_profile, camunda7_user_profile_data and camunda7_save_user_profile are renamed to camunda7_show_settings, camunda7_settings_data and camunda7_save_settings; the widget id camunda7:user-profile is camunda7:settings; camunda7_save_settings no longer takes language (use shell_save_settings). AppShellProviders and ProfileGate take no profileTool. settingsLayout and filterLayoutToWidgets come from @miragon-ai/widget-shell/widgets, and camunda7's cockpitViews take no view context. A composition root passes { profileStore, allowSave } to createShellPlugin and spreads shellWidgets into its widget registry.
- camunda7: the view payloads replace
bpmnXmlwithdiagramDefinitionId(camunda7) or carry no diagram at all (analytics_show_bpmn_heatmap,analytics_bpmn_heatmap_data). The widgets read the XML from the new app-only feedscamunda7_bpmn_xml_dataandanalytics_bpmn_xml_data.BpmnDiagramtakesdefinitionId(+engineId) instead ofbpmnXml;BpmnCanvasdraws XML already in hand. - widget-shell:
buildDataFeedResultreturns{ content }only: the feed payload is JSON text, nostructuredContent. Read it with the toolkit'sparseToolResult. Thecamunda7:bpmnXmlkey ofcamunda7:load-process-instanceis gone. - widget-shell:
installToolCallLoggingis removed from@miragon-ai/widget-shell/server(mcp-use logs requests itself).MCP_DEBUG_LEVELis no longer a known variable; use mcp-use'sMCP_USE_LOG_LEVEL. A module named twice inMCP_ACTIVE_MODULESfails the boot. - analytics: the duration histograms are now
camunda_*_duration_millisecondsand record milliseconds; the incident counters gainprocess_definition_version;VersionCompareResult.notesis removed. Upgrade the engine plugin and the analytics client together; dashboards and alert rules of your own need the new names and the reading rules in metrics-contract.json. A clustered engine needs a uniqueservice.instance.idper node.
Features
- analytics: millisecond histograms, versioned incidents, honest first counts and committed-only metrics (#388) (28dfa26), closes #337
- camunda7: one action group per view, every action one button size (#405) (483d386)
- camunda7: warn at boot that passthrough auth is for trusted single-audience setups only (#390) (3c39be9), closes #330
- the shell owns the UI language and the settings page (#397) (8fa4fb3), closes #346
- widget-shell: an inline confirmation opens beside its opener (#400) (ce80c39), closes #344
- widget-shell: focus after navigation, fullscreen in a drill, no pip, an outlier floor (#399) (4657df5), closes #344
- widget-shell: inline lists fit the host's height by measuring their rows (#404) (6791363)
- widget-shell: inline views are cards that fit the host's height budget (#398) (1b563e2), closes #396
- widget-shell: views ask for a border, the bundle gets a budget (#401) (266ab71), closes #344
Bug Fixes
- camunda7: row actions have the one action size, level with their icon buttons (#408) (84fcb31)
- camunda7: the instances list finds an instance by its id, and pages in one order (#402) (5207a8e)
- docs and skills match the code, guarded; connectors declare the toolkit-ui peer (#395) (7fff7f4), closes #345
- widget-shell: the segmented toggle's selection follows its rounded corners (#406) (d0423e2)
Code Refactoring
- camunda7: views name the diagram they draw; the widgets read its XML by id (#394) (4169059), closes #342
- widget-shell: feeds answer once, diagrams are read once, summaries claim no UI (#393) (8bd2e51), closes #342
- widget-shell: one request log, one module per name, honest tool-call metrics (#392) (4665445), closes #346
v0.19.0
0.19.0 (2026-10-12)
⚠ BREAKING CHANGES
- analytics: In @miragon-ai/analytics-client, an EngineLandscapeEngine that reports no metrics carries null instead of 0 in every count. The landscape totals' runningInstances, openIncidents and failedJobs are null while no engine reports, and analytics_engine_landscape and its feed send these nulls too. AnalyticsDashboardData requires the new previous and activityCount fields, and dashboardData takes an optional minBucketSize. createBpmnXmlFetcher (camunda7-connector) rejects a failed read instead of resolving null, and resolves null only for a missing definition. FetchBpmnXml (analytics-connector) takes an optional engineId and carries the same contract, so a custom fetcher must reject a failure.
- camunda7: In @miragon-ai/camunda7-connector, camunda7_save_user_profile and Camunda7Settings drop preferredRole; the strict tool input refuses it, and a stored value stays inert. UserProfileView requires readOnlyReason ("toolset" | "noSignIn" | null); "noSignIn" is reported for any request without a profile key. The view models require new name and label fields, each null when unknown:
- Job: processDefinitionName and activityName;
- ProcessInstanceRow: processDefinitionName;
- IncidentInstance: businessKey;
- InstanceDetailData: processDefinitionName;
- HistoryTimelineData: incidentActivityIds;
- EngineHealthCluster: activityName and processDefinitionName;
- ClusterIncidentRow: processDefinitionName;
- ClusterDetailData: activityName;
- BpmnViewerData: businessKey and processDefinitionName.
- widget-shell: In @miragon-ai/widget-shell/widgets, ViewDataState and QueryFallback require onRetry. QueryFallback no longer takes errorHint: describeError words the failure, and errorTitle heads only a failure it cannot classify. ViewDataState's loadingText is now the optional sr-only status. useDetailView takes refreshErrorTitle instead of refreshErrorText. ListTable requires ariaLabel and renders its table inside a scroll region. TableEmptyState renders the toolkit's EmptyState, with its children as a non-heading title. BpmnHeatmap without a height sizes itself from the diagram's aspect ratio, and HeatmapLegend shows min and max when given. The shell:* widgets' default empty texts are the kit's localized words instead of the dataKey.
- @miragon-ai/widget-shell/widgets no longer exports cn, the tone model (ToneVariant, TONE_, MICRO_LABEL), KpiGrid/KpiGridSkeleton/KpiCell/KpiGridHeader, LivePill/StatusBadge/CountPill, FilterBar/FilterChip, WidgetHeader, PagedListFooter, SectionHeading, GroupCard, DrillButton, ListFooter, useDebouncedValue, parseToolResult/parseViewToolResult, useHostActions/buildShowWidgetIntent/HostActions, useViewToolQuery, useViewData or ViewDataResult. Import them from @miragon/mcp-toolkit-ui (or its /app and /hooks subpaths), and use useViewData with initialDataMode "seed" plus the new viewRefreshState. camunda7's CockpitListFooter and its listFooter. catalog keys are gone. The @miragon/mcp-toolkit-* peer range is ~2.8.0.
- The in-app theme switch is gone. The profile record, the camunda7 settings panel and camunda7_save_user_profile no longer carry a theme, and the save tool rejects the key. widget-shell no longer exports THEMES or ThemePref, and useApplyTheme() takes no argument; widgets follow the host's theme, then the OS's. @miragon-ai/widget-shell no longer ships ./theme.css. A consumer stylesheet imports tailwindcss, adds an @source for node_modules/@miragon/mcp-toolkit-ui/src, imports @miragon/mcp-toolkit-ui/theme.css and overrides role variables only; the template's brand.css shows how. The --m-* accents and the critical tone no longer exist. The @miragon/mcp-toolkit-* peer range is ~2.7.0, and a host bundle that dedupes lucide-react needs a 1.x version.
- camunda7: EngineHealthData drops
headline; the verdict isstatusplussummary, worded by its reader. IncidentsDashboardData, ProcessIncidentsData and IncidentDetailData requireengineVendor. The CIB seven provider's display name is "CIB seven". Several camunda7 catalog keys changed: the hand-off labels (handOff.*), the former…One/…Otherplural pairs and several messages. The show tools' view titles come from the profile language, or are absent. - widget-shell: The widget-shell tone vocabulary drops
critical(usedanger) andTONE_TEXT(useTONE_INK; numbers stay neutral, and a state is a dot, edge or icon).WidgetHeaderno longer takesicon/iconTone. The tone colours live in@miragon-ai/widget-shell/theme.css, and the--critical*and--*-foregroundtone tokens are gone from the app and template stylesheets; override--<tone>,--<tone>-softand--<tone>-inkinstead.formatDurationrenders German units in a German view. The kit peers onlucide-react(^0.562.0 || ^1.0.0), which a consumer installs and appends to its vitededupelist. - In @miragon-ai/widget-shell, PagedViewData.error now carries only the page-0 failure; load-more failures move to the new loadMoreError, and retry, refreshing and stale are added. firstPage keeps the previous result of the same list while a new page 0 is in flight or has failed. camunda7:process-definition-flow drops its initialMode prop. camunda7_open_cockpit lists only the caller's engines (allowedEngineIds) and refuses an
engineoutside them with ENGINE_NOT_AVAILABLE instead of opening the picker. - widget-shell: The profile language gains "system" (follow the host locale) and defaults to it, so ProfileRecord.language and the camunda7 UserProfile.language are now LanguagePref. View stylesheets import @miragon-ai/widget-shell/theme.css after tailwindcss, plus an @source for the toolkit's src, instead of @miragon/mcp-toolkit-ui/globals.css, and Geist is no longer shipped. ViewDisplayModeBridge is replaced by ViewHostBridge, and AppShellProviders no longer mounts mcp-use's ThemeProvider. ProfileGate holds the first paint until the profile answers: at most 1.5 s after the host connects, 5 s without a host. BpmnZoomControls sit top-right.
- AskAiButton's
promptaccepts only anAskAiPromptbuilt byaskAiPromptfrom@miragon-ai/widget-shell/widgets: a raw string no longer compiles, andnullrenders no button.@miragon-ai/camunda7-connectorno longer exportsCAMUNDA7_ENGINELESS_TOOLS.camunda7_format_incident_issueand thedraft_incident_ticketprompt drop theirrepositoryargument: drafts target only the configuredCAMUNDA_INCIDENT_ISSUE_REPO, and without one there is no prefilled URL. - analytics: analytics reads only the server's configured engines: camunda7's engine ids, else ANALYTICS_ENGINE_IDS, else every analytics tool refuses. It refuses any other
engineid. analytics_engine_health returnsunknown(a new status) for silent engines and only counts alerts scoped to them. @miragon-ai/analytics-client renames or removes result fields without aliases:- dashboard runningCount/failedCount/incidentCount/failureRatePct → runningNow/openIncidentsNow/incidentsCreated/incidentsResolved/incidentRatePct;
- failureDashboardData.processBreakdown totalInstances/failedCount/incidentCount/failureRatePct → runningNow/deadJobs/openIncidents/incidentRatePct;
- definitionBreakdown running/failed → runningNow/incidentsCreated;
- activityBreakdown rows drop activityName and gain processDefinitionKey;
- analyzePerformance/comparePeriods failed/failure_rate_pct → incident_count/incident_rate_pct, and analyzePerformance drops earliest/latest;
- compare failed_count/failure_rate_pct and the failure-rate delta are removed, instance_count_delta_pct → started_per_day_delta_pct, and element-scoped incidents move to element_incident_*;
- failure-dashboard and find-failed rows carry only incident type, process and counts;
- durations and rates are null when not measured;
- every engine-filterable result gains
engines, and findFailedInstances returns { engines, patterns }.
- camunda7: camunda7 view payloads change meaning and shape. The definition view, the cockpit landscape and the incidents dashboard count every version of a key. ProcessIncidentsData.version is now diagramVersion; DefinitionStat.version and IncidentsDashboardProcess.version are now latestVersion; IncidentsDashboardProcess.totalActivityCount is gone; per-activity incidentCount is now scannedIncidentCount. Health and cluster counts follow the ClusterCounts shape: incidentCount is nullable, with scannedIncidentCount and a nullable last24hCount. Numbers the server cannot vouch for are null instead of 0: affected activities, the 24h and first-seen facts of a partial scan, siblingsWithIncidents and BpmnViewerData.bpmnXml. InstanceDetailData gains exact incidentCount/openTaskCount. BpmnViewerData gains statsScope and, in instance mode, counts only the instance's own tokens and failed jobs. The process-instance list reports totals over the whole filtered set. Engine failures and unknown ids are tool errors instead of empty views. The pipeline steps throw on failure and stamp engineId. The incidents-dashboard step reads its scope from camunda7:incidentsProcessDefinitionKey instead of camunda7:processDefinitionKey.
- @miragon-ai/widget-shell/server no longer exports
mergeRawSlice(save a slice withsaveModuleSlice) ormergeProfile(usemergeStoredProfile(...).record).ComposableModule.supportsToolsetsis removed: a module without atoolsetsvocabulary is a module without toolsets, so its suffix is ignored with a warning and its config never carries atoolset.EffectiveToolset.sourceno longer has the"legacy"value. Profile records stored below schema v3 are no longer migrated: they are adopted at schema v3, their flat v1/v2 module fields stay inert, and those preferences read as their defaults. - camunda7_engine is gone: camunda7_list_engines (read-only) lists the engin...
v0.18.0
0.18.0 (2026-10-09)
⚠ BREAKING CHANGES
- server: requests whose Host (or, on non-GET requests, Origin) is not localhost-class, MCP_URL's or allow-listed via MCP_ALLOWED_HOSTS / MCP_ALLOWED_ORIGINS get 403 (
*disables a check), so a server reached under a public name must set MCP_URL or the allow-lists; request bodies over MCP_MAX_BODY_BYTES (default 4194304) get 413; MCP_OAUTH now requires MCP_URL; and camunda7_engine "list", UserProfileView.availableEngines and CockpitEngineInfo no longer carry the engine REST baseUrl. - analytics: @miragon-ai/analytics-client's VersionCompareKpi failed_count, failure_rate_pct, incident_count and incident_rate_pct (and the two rate deltas) are now
number | nulland always null, and VersionCompareResult gains a requirednotes: string[]. analytics_version_compare and analytics_show_version_compare report these KPIs as unavailable instead of 0; the previous zeros were never measured values. - toolsets fail closed. Without a suffix in MCP_ACTIVE_MODULES a module no longer gets every tool: unauthenticated boots (no MCP_OAUTH) run each module read-only; with MCP_OAUTH the defaults are camunda7:operations and the new analytics:standard; admin is reached only by naming it; an empty (camunda7:) or unknown suffix falls back to read-only, even under OAuth. camunda7_create_deployment additionally requires CAMUNDA_ALLOW_DEPLOYMENTS=true (deploying is code execution inside the engine JVM). camunda7_throw_signal and the external-task worker protocol (fetch_and_lock, complete_external_task, handle_external_task_failure) are admin-only; the new camunda7_list_external_tasks (read-only) and camunda7_set_external_task_retries (operations) cover reading and recovering external tasks. The dashboard builder and its tools need OAuth and no read-only module. A server behind an auth-terminating gateway looks unauthenticated and must name its toolsets. Restore the previous surface with MCP_ACTIVE_MODULES=camunda7:admin,analytics:standard (+ CAMUNDA_ALLOW_DEPLOYMENTS=true for deployments, MCP_OAUTH for dashboards). Package API: a direct createPlugin call without
toolset(camunda7 or analytics) now registers the read-only floor, so pass the toolset explicitly (camunda7 also needsallowDeployments: truefor deployments); createToolsetVocabulary().resolve(undefined) returns the floor instead of undefined, and ToolsetVocabulary gained module/fallback/authenticatedDefault/effective/allowsDurableWrites, so build vocabularies with createToolsetVocabulary; modules declaretoolsetsinstead of the deprecated supportsToolsets (which keeps a raw pass-through but blocks the dashboard builder); composed servers boot via composeModules().resolveBoot(env, { authenticated }) and logEffectiveToolsets.
Features
Bug Fixes
- analytics: version-compare incident KPIs unavailable instead of 0; label-checked metrics contract (#356) (144f410)
- camunda7,analytics: actionable engine errors, upstream timeouts and Prometheus auth (#357) (8d1045d)
- camunda7: send deployment resources as real multipart parts (#355) (dab051c)
- server: DNS-rebinding protection, pre-auth body cap, graceful drain and one createApp factory (#358) (e1fa024)