NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #3041 most downloaded on pub.dev
A Flutter package for beautiful LLM text streaming with markdown support. Perfect for ChatGPT-like interfaces with typing animations, RTL support, and customizable effects.
Last release 6 days ago
02 Oct 2026
Release timing varies
gaps range from 8 days to 5 months
Nearly every release is documented
notes for 22 of 23 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
23 releases · first in 2025
All deprecations point to their replacement and are scheduled for removal in 2.0.0; nothing is removed in this release.
A ground-up correctness and architecture pass. No public API was removed
or renamed, so this is a zero-breaking-change release; see
doc/MIGRATION.md for upgrade notes.
Summary of the release (details in the sections below):
RevealEngine core with a catch-up pacer and asmoothFade reveal mode; a built-in syntax-highlighted CodeBlockViewCodeBlockTheme as the default code renderer (both exported from theStreamingTextController accessorsisStreaming, markdown, copyToClipboard); accessibility supportgpt_markdown 1.3; redesigned the markdown fademend()dart analyze --fatal-infos isEvery W-numbered bug from the audit is fixed:
codeBuilder receives indented code verbatim.onComplete); a tap mid-animation reliablycompleted.Brightness change after completion now updates thetypingSpeed/chunkSize/wordByWord/markdownEnabled) mid-stream, or a plain rebuild with no change at all,StateError: Stream has already been listened to — including when the caller reads stream: controller.stream directly inside build() instead of caching theStream in a field. (StreamController.stream returns a new,==-equal-but-not-identical wrapper object on every access, so thelatexEnabled: true no longer throws away markdown rendering:$...$/$$...$$ math is now handled.$VARS inside fenced or inline code are no longercodeBuilder verbatim. latexEnabled$...$/$$...$$ to gpt_markdown's native \(...\)/\[...\]useDollarSignsForLatex to gpt_markdown (whose own rewrite runs before$ is only ever treated as LaTeX when it looks$5, Cost $10 - $20, and $ alone are left as plain text, on both a closed source and mid-stream$5 whilepause/resume/stop/restart all work correctlypause was ignored for streams, andstop/restart were ignored in every mode).error state (via themarkError) and renders through the new errorBuilder, or a themedRow) no longer throws; width is only forced when the incomingcontroller instance now correctly unbinds theanimationsEnabled: false no longer fires onComplete oncontroller.onCompleted fires exactly once perupdateProgress(1.0),markCompleted(), or skipToEnd() triggered it (previously it could.instant(stream:) and animationsEnabled: false with aTextAlign.right; a user's textAlign is_effectiveTheme now reacts to widget.theme changes instead ofRegExp compilation for Arabic detection, and no moreStringBuffer.toString() buffer copies per stream tick.LaTeXProcessor/TextSegment regexgpt_markdown 1.3 (its native\(...\)/\[...\] syntax — see W11 for how $...$/$$...$$ reach it)flutter_math_fork for the default renderer._cursorController, _markdownCache,_completeMarkdownCache, _isAnimationActive,_resumeWordByWordTypingFromOldText, _safeSetState, the unbounded_rtlGroupCache, and the five-plus duplicated Timer.periodic bodiesRevealScheduler with exactly one Timer.periodic).MarkdownRenderOptions bundles every gpt_markdown 1.3 pass-through
that doesn't have its own top-level parameter (style sheet, block/inline
builders, autolink config, useDollarSignsForLatex, and more) — the
single place new gpt_markdown forwards land going forward.
errorBuilder (Widget Function(BuildContext, Object error)?) on
every constructor, called when stream emits an error (see W16 above).
StreamingTextController gains additive accessors for chat-style UIs:
isStreaming (true while a stream: input is still open or a reveal
is in progress or paused, false once completed or idle), markdown
(the bound widget's full accumulated source text, e.g. behind a "copy"
button), copyToClipboard() (copies markdown to the system
clipboard), and the public updateSource() method the bound widget
calls to publish its current source snapshot and open/closed state so
markdown and isStreaming stay truthful.
Accessibility: reduced-motion support (reveals instantly with a
static caret and no fade), single-announcement semantics with mid-stream
text excluded from the tree, semanticsLabel, and selectable (wraps
output in a SelectionArea).
showCursor (bool?, null resolves to stream != null) and
cursorColor — an 8px pulsing dot caret shown while revealing, hidden on
completion.
StreamingShimmer and MarkdownRenderOptions are now exported from the
barrel file, along with a curated re-export of the gpt_markdown types
used in MarkdownRenderOptions's public signatures (MarkdownComponent,
GptMarkdownStyleSheet, the *Builder typedefs, InlinePattern,
InlineDirective, ...), so consumers no longer need a direct
gpt_markdown dependency just to use it.
doc/BENCHMARKS.md — published frame-budget numbers for streaming
markdown vs. bare GptMarkdown (see Performance below).
doc/MIGRATION.md and a weekly CI job (pub upgrade + test,
pub downgrade + analyze, and pana --exit-code-threshold 0).
tool/check_coverage.dart — parses coverage/lcov.info and enforces a
minimum coverage threshold.
RevealMode ({smoothFade, wordFade, typewriter, instant}, exported)
and a revealMode parameter on StreamingText and every
StreamingTextMarkdown constructor. smoothFade (word-unit reveal, a
180ms opacity-only fade on Cubic(0.2, 0, 0, 1)) is the new default on
StreamingText, the default StreamingTextMarkdown constructor,
.chatGPT() and .claude(); .typewriter()/.instant() default to
their own matching mode. Pass revealMode: null explicitly to opt out
entirely and keep the pre-2.0 behaviour driven by the legacy
wordByWord/fadeInEnabled/fadeInDuration/fadeInCurve/chunkSize/
typingSpeed parameters — see doc/MIGRATION.md.
StreamPacing (StreamPacing.catchUp(...) / StreamPacing.fixed(...))
and a pacing parameter alongside revealMode. Stream<String> input
now defaults to catch-up pacing (a bursty-token-smoothing pacer: reveals
a backlog-proportional share every ~50ms, floors at 30 chars/s, and
drains fully within 400ms of the stream closing) instead of one fixed
unit per typingSpeed tick; static text input keeps the fixed,
typingSpeed-driven pacer. An explicit pacing: always overrides the
default, on either input kind.
StreamingRenderScope — an internal InheritedWidget seam (carrying
isStreaming/isComplete/the caret builder) wrapped around the markdown
view, for a future block-level renderer to read instead of having those
threaded through by hand. Not part of the public API surface yet.
components / inlineComponents on all 6 constructors — usemarkdownOptions.blockComponents / markdownOptions.inlinePatterns.gpt_markdown's incrementalmarkdownOptions doesn't have that cost.initialText — never displayed; has no effect.latexFadeInEnabled (widget-level and StreamingTextTheme-level) — agpt_markdown, which has nolatexBuilder instead.StreamingTextTheme.blockLatexStyle and .latexScale — no-ops at thelatexBuilder and the widget-level latexScale.StreamingTextTheme.markdownStyle — use markdownStyleSheet.StreamProvider / DefaultStreamProvider (and the types around them) —Stream<String> directly toStreamingTextMarkdown.stream instead. Will be removed in 2.0.0.All deprecations point to their replacement and are scheduled for removal
in 2.0.0; nothing is removed in this release.
sdk: '>=3.7.0 <4.0.0', flutter: '>=3.32.0' (raised from >=3.0.0 />=3.10.0) — required by the gpt_markdown ^1.3.0 upgrade.These are visible behavior changes, listed explicitly since they can
affect existing consumers (notably flutter_gen_ai_chat_ui):
showCursor defaults tonull, which resolves to stream != null — a live stream now shows ashowCursor: false.MarkdownFadeMask, see the smoothFade bullet below) andtypingSpeed, chunkSize,wordByWord no longer restarts the reveal from the beginning — itonComplete/onCompleted fire exactly once per revealing→completesetSource/appendRevealMode.smoothFade on StreamingText,StreamingTextMarkdown constructor, .chatGPT() and.claude() (see Added above): word-unit reveal with a 180ms fade,MarkdownFadeMask applies a cheap paint-onlysmoothFade/wordFade modes, without rebuilding theGptMarkdown span tree (disabled under reduced motion or whenanimationsEnabled is false). Pass revealMode: null to keep theCodeBlockViewCodeBlockTheme, with a language-label header and a copy affordance thatcodeBuilder opts out and keeps your own rendering,Stream<String> input reveals faster by default (catch-up pacing —typingSpeed-per-unit rate. Passpacing: StreamPacing.fixed(typingSpeed) to keep the old rate.A plain fade over 5k characters now uses at most 2 transient tickers
(previously one AnimationController per character — 500+ concurrent
tickers at 5k chars in the old implementation).
A 20k-character markdown stream now runs within ~1.0x-1.3x of bare
GptMarkdown 1.3 (budget: 1.8x), down from roughly 2.1x against
gpt_markdown 1.2.1 in the pre-rewrite implementation — see
doc/BENCHMARKS.md for the full methodology and numbers:
| Run | ours median | bare median | ratio |
|---|---|---|---|
| 1 | 3697us | 3698us | 1.000x |
| 2 | 4438us | 4337us | 1.023x |
| 3 | 4146us | 4176us | 0.993x |
No more per-tick RegExp compilation and no more O(n) buffer copies per
stream tick (both from the audit's _containsArabic/StringBuffer
findings).
A gpt_markdown "hybrid" reveal (letting GptMarkdown fade-paint the
head our engine reveals) was prototyped and rejected: it measured ~1.4x
bare in isolation, but ~2.3x time and ~12.9x element-rebuilds once wired
into the real default (caret + engine + catch-up pacer together), over
both budgets. The shipped default instead fades markdown in
smoothFade/wordFade via MarkdownFadeMask: a paint-only, per-word
mask over the rendered paragraphs that repaints without rebuilding
GptMarkdown's span tree, keeping the real default at ~1.2x-1.5x bare
across both perf suites. See doc/BENCHMARKS.md's "B1-S5 correction".
One column per month.
Fixes all 6 findings from the 2026-09-03 visual QA pass on the live web demo: LaTeX now renders real typeset math instead of Unicode-substitution text
Fixes all 6 findings from the 2026-09-03 visual QA pass on the live web
demo: LaTeX now renders real typeset math instead of Unicode-substitution
text, copy-to-clipboard no longer throws on web, resume-after-pause no
longer duplicates a word, a completed character can no longer render
below full opacity (em-dash drop), the Customization Preview toggle
labels are no longer clipped, and the demo's version badge is generated
from pubspec.yaml instead of hand-typed.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
latexEnabled: true) now renders real typeset math instead of
a Unicode-substitution approximation — fractions, superscripts, and
radicals are laid out properly via flutter_math_fork (already pulled in
transitively through gpt_markdown, now a direct dependency), with a
plain-text fallback on any parse error.Clipboard.setData call is now awaited and its
failures caught instead of left as an unhandled Future rejection.StreamingTextController: resuming a word-by-word animation after
pause() no longer re-types the last word for one frame. Resume now
reads the typing timer's own tracked position instead of reconstructing
it from the displayed text's length, which could drift from the actual
buffer-writing rules (header newlines, conditional spacing).bouncy preset) invisible.wordByWord, fadeIn, etc. were losing their first
1-3 characters behind the switch thumb).pubspec.yaml at build time instead of a hand-typed literal, so it can't
go stale on a future release again..chatGPT()/.claude()/.typewriter()/.instant() accept optional fadeInDuration/fadeInCurve/typingSpeed overrides (closes #17 )
.chatGPT(), .claude(), .typewriter(), and .instant() now accept
optional fadeInDuration, fadeInCurve, and typingSpeed overrides
(closes #17) — pass any of the three to tweak just that part of the
preset's animation while keeping everything else the preset tunes.
Omitting them keeps the exact preset defaults as before, so this is fully
backward compatible.stream: payload each complete within a
bounded pump budget, proving the per-character fade-in suppression under
stream != null holds at real LLM-transcript scale.--wasm on every push/PR, so
WASM compatibility can't silently regress.gpt_markdown's deprecated highlightBuilder to
inlineCodeBuilder (the package's own highlightBuilder parameter on
StreamingTextMarkdown/StreamingText is unchanged and still works). This
was the sole cause of a lost pana static-analysis point — score is back to
160/160.gpt_markdown dependency lower bound from ^1.1.7 to ^1.2.0
— the version that introduced inlineCodeBuilder, which the fix above
requires even at the constraint's lower bound.public_member_api_docs is now enabled permanently to prevent regressions.Stream-mode engine rewrite — chunks now animate instead of rendering instantly
Stream-mode engine rewrite — chunks now animate instead of rendering instantly
The stream: parameter (added in 1.9.0) had several rough edges once real
LLM traffic hit it. This release rewrites the streaming engine and tightens
the surrounding lifecycle:
typingSpeed/chunkSize/wordByWord instead of
being dumped onto the screen the instant they arrive. wordByWord now
correctly holds back a trailing partial word at a chunk boundary until the
next whitespace or stream close, so words no longer visibly split mid-token.onComplete/controller.markCompleted() now fire exactly once — only
once the stream itself has closed and the displayed text has caught up
to everything received. Previously these could double-fire or fire before
the last chunk had finished animating in.controller.progress now updates correctly during streaming. It was
previously stuck at 0 for the entire stream and only jumped to 1.0 on
completion.controller.skipToEnd() are now stream-safe. In
stream mode, both now instantly catch the displayed text up to whatever has
been received so far — they never erase already-streamed content. They only
trigger full completion if the underlying stream has already closed;
previously tapping mid-stream wiped all streamed text and could double-fire
onComplete.didUpdateWidget now detects a stream instance swap (e.g. a chat UI
moving on to the next message). Previously swapping in a new Stream<String>
was silently ignored and its content never appeared. The old subscription is
now properly torn down and the new one subscribed — including the
stream → null and null → stream transitions.autoScroll (on StreamingTextMarkdown) now pins to the bottom as content
grows during animation/streaming, not only once at the very end. Backed by
a new optional onTextChanged callback on StreamingText.AnimationController ticker that
ran continuously with nothing ever rendering it — a source of needless
battery drain and a cause of pumpAndSettle hangs in tests.Code-fence render stability while typing. While a ``` code fence was still being typed, its raw backtick markers rendered as literal text; the instant the closing fence completed, gpt_markdown reformatted the block as a styled code widget, stripping those markers — the visible text shrank by a few characters at that exact moment, reading as a stutter/flicker on top of the typing animation. The markdown render now withholds a trailing unclosed fence until it balances, so code blocks only ever appear in their final styled form. Typing position, progress, and completion timing are unchanged — this affects display only.
v1.9.0: Stream support + completeAnimationOnTap (PR #15 )
v1.9.0: Stream support + completeAnimationOnTap (PR #15)
StreamingTextMarkdown now accepts a Stream<String> directly
The headline widget finally lives up to its name. You can pass a stream: parameter to StreamingTextMarkdown (and every preset constructor) instead of dropping down to the lower-level StreamingText. Each chunk emitted by the stream is appended to the rendered text and animated using the active typing settings.
StreamingTextMarkdown(
stream: openAiChat(prompt), // Stream<String> from your LLM client
markdownEnabled: true,
trailingFadeEnabled: true, // recommended for streams
onComplete: () => setState(() => _isStreaming = false),
)
stream — Stream<String>?. When non-null, takes over from text and content arrives via the stream.text is now optional (defaults to ''). Existing code passing text: keeps working unchanged.fadeInEnabled is automatically suppressed when stream is set (one AnimationController per glyph on an unbounded stream would exhaust memory). Use trailingFadeEnabled for a smooth gradient reveal..chatGPT(), .claude(), .typewriter(), .instant(), .fromPreset(). Non-breaking.README has new copy-pasteable bridges for OpenAI Chat Completions and Anthropic Messages SSE → Stream<String>.
Opt out of tap-to-complete (PR #15, thanks @AdamBurnett-Tonal)
completeAnimationOnTap flag (bool, defaults to true). By default, tapping the widget while it animates jumps straight to the finished text — set this to false to let the animation play through uninterrupted regardless of taps.StreamingTextMarkdown, every preset constructor, and the lower-level StreamingText. Non-breaking — existing behavior is the default.Custom markdown components (closes #13 )
Custom markdown components (closes #13)
You can now override how gpt_markdown renders any markdown element — headers, lists, bold, italic, tables, strikethrough, etc. — by passing your own MarkdownComponent lists.
StreamingTextMarkdown(
text: '# Custom heading\n**bold** *italic*',
markdownEnabled: true,
components: [
MyCustomHeader(),
MyCustomList(),
// ...
],
inlineComponents: [
MyCustomBold(),
MyCustomItalic(),
],
)Both params are List<MarkdownComponent>? and forward as-is to GptMarkdown. Defaults to null → uses gpt_markdown's built-in component list.
Available on every constructor: default, .chatGPT(), .claude(), .typewriter(), .instant(), .fromPreset().
Non-breaking. No user code changes required.
https://pub.dev/packages/flutter_streaming_text_markdown/versions/1.8.0
Custom markdown components (closes #13)
Expose gpt_markdown's component lists so you can override how block- and inline-level markdown elements are rendered — headers, lists, bold, italic, tables, etc. Both parameters are forwarded as-is to the underlying GptMarkdown widget; passing null (the default) keeps gpt_markdown's built-in component list.
components — List<MarkdownComponent>?, block-level overrides (headers, lists, code blocks, tables, …)inlineComponents — List<MarkdownComponent>?, inline-level overrides (bold, italic, strikethrough, links, …)Available on every constructor — default, .chatGPT(), .claude(), .typewriter(), .instant(), .fromPreset(). Non-breaking.
Fix pub.dev static analysis failure causing 90/160 score. gpt_markdown 1.1.7 changed the ImageBuilder typedef from 2 args to 4 args (added optional wi
gpt_markdown 1.1.7 changed the ImageBuilder typedef from 2 args to 4 args (added optional width/height parsed from image alt text). Our constraint ^1.1.6 permitted 1.1.7, so pana resolved to it and the imageBuilder argument at streaming_text.dart:1708 failed type-checking — which cascaded into platform-support detection also reporting 0/20. Bumped the dependency to ^1.1.7 and added a thin internal adapter so the public imageBuilder(BuildContext, String) signature stays unchanged. No user code changes required. Restores full 160/160 pub.dev score.v1.7.2 — fix trailing fade dismiss on completion (closes #12 )
v1.7.2 — fix trailing fade dismiss on completion (closes #12)
_triggerTrailingFade() was called during streaming via _updateProgress, but every completion path set _isComplete = true without re-triggering the dismiss animation. Centralized completion through a new _handleCompletion() helper that fires onComplete and triggers the fade-out together. Affected all 11 completion sites (typing finish, stream onDone, skip-to-end, tap-to-skip, append-completion, etc.).fadeInEnabled and stream now have explicit dartdoc on the interaction; README has a "Choosing a fade for streaming content" table.text prop + Stream<String>) with trailingFadeEnabled: true.Fix lint info (curly braces) for full 160/160 pub.dev score
Custom markdown builders (closes #10)
Custom markdown builders (closes #10)
Expose gpt_markdown's builder callbacks so you can customize how images, links, code blocks, and more are rendered inside streaming text.
imageBuilder — custom widget for markdown imagesonLinkTap — callback when a link is tappedcodeBuilder — custom widget for code blockslatexBuilder — custom widget for LaTeX expressionssourceTagBuilder — custom widget for source tagshighlightBuilder — custom widget for highlighted textlinkBuilder — custom widget for linksAll parameters are optional and available on every constructor including .chatGPT(), .claude(), .typewriter(), .instant(), and .fromPreset().
StreamingTextMarkdown.chatGPT(
text: response,
markdownEnabled: true,
imageBuilder: (context, url) => CachedNetworkImage(imageUrl: url),
onLinkTap: (url, title) => launchUrl(Uri.parse(url)),
codeBuilder: (context, name, code, closed) => MyCodeBlock(code: code),
);
Trailing fade effect — new trailingFadeEnabled parameter
Optional trailing gradient fade at the bottom edge while text is streaming. The fade holds steady during streaming and smoothly animates away when complete. Opt-in via trailingFadeEnabled: true — disabled by default.
_displayedText.length returned UTF-16 code units but was used as an index into grapheme cluster lists, causing characters after emoji to be dropped. Now uses _displayedText.characters.length.StreamingTextController callbacks in the example's ControllerSection could fire during the build phase. Deferred with addPostFrameCallback.✨ Shimmer loading state ( isLoading )
isLoading)No more blank screen while waiting for the first LLM token. Set isLoading: true to show an animated skeleton placeholder that seamlessly transitions to streaming text.
StreamingTextMarkdown.chatGPT(
text: _accumulatedText,
isLoading: _waitingForFirstToken,
)isLoading: false (default) — zero behavior change for existing codeshimmerLineCount: 3 — configurable number of skeleton linesgpt_markdown bumped to ^1.1.6 — table column alignment, ordered list fixes, Flutter 3.35 compat, heading style customizationFull changelog: https://github.com/hooshyar/flutter_streaming_text_markdown/blob/main/CHANGELOG.md
Shimmer loading state — isLoading parameter
Show an animated skeleton placeholder while waiting for the first LLM token (TTFT). No more blank screen between sending a request and the first character appearing.
isLoading: false — New parameter on all constructors and named variants. When true, displays an animated shimmer skeleton instead of the text widget. Defaults to false — all existing code is completely unaffected.shimmerLineCount: 3 — Controls how many skeleton lines are shown. Defaults to 3.AnimationController + LinearGradient sweep. Adapts to light/dark theme automatically.// Usage example
StreamingTextMarkdown.chatGPT(
text: _accumulatedText,
isLoading: _waitingForFirstToken, // true until first token, then false
)
gpt_markdown dependency to ^1.1.6 — picks up table column alignment fix, ordered list bug fix, Flutter 3.35 compatibility, and heading style customization fixesTrailing-edge fade animation for all content types
fadeInEnabled: true now works with markdownEnabled: trueComplete rebuild showcasing all 17 package features — live at https://hooshyar.github.io/flutter_streaming_text_markdown/
See CHANGELOG.md
Trailing-edge fade animation for markdown and RTL content
Previously, fadeInEnabled: true only worked with plain text (markdownEnabled: false). This release brings smooth streaming animations to all content types.
fadeInEnabled: true and markdownEnabled: true, a trailing-edge gradient fade animates at the bottom of the content as new text streams in, using the configured fadeInCurve and fadeInDuration$$...$$ block, uses a gentle opacity pulse instead of gradient mask to avoid visually cutting through equationsLLMAnimationPresets with live mini-previewsStreamingTextController API with progress bar, state display, speed multiplierFully backward compatible — existing code unchanged. Fade-in for markdown only activates when both fadeInEnabled: true AND markdownEnabled: true are set.
StreamingTextTheme.markdownStyle still works (deprecated with migration path)
This release adds a dedicated markdownStyleSheet property (typed as TextStyle) while maintaining 100% backward compatibility. Includes all v1.3.3 stability fixes.
StreamingTextTheme.markdownStyleSheet property accepts TextStyleStreamingTextMarkdown.styleSheet now properly typed as TextStyle?gpt_markdown package for proper markdown renderingStreamingTextTheme(
markdownStyleSheet: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.black87,
),
)
StreamingTextTheme.markdownStyle still works (deprecated with migration path)markdownStyle: TextStyle() continues to work perfectlymarkdownStyleSheet for a clearer APITextStyle usageNo migration required! Old code continues to work:
// Old way (still works, deprecated)
StreamingTextTheme(
markdownStyle: TextStyle(fontSize: 16),
)
// New way (recommended)
StreamingTextTheme(
markdownStyleSheet: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.black87,
),
)
Recommended upgrade - Get both new features AND stability improvements:
dependencies:
flutter_streaming_text_markdown: ^1.4.0
No code changes required, but you now have access to powerful markdown styling options!
Animation Disable Option - Added animationsEnabled parameter to all constructors allowing complete animation disabling
animationsEnabled parameter to all constructors allowing complete animation disabling
animationsEnabled: false for instant text displaytrue)Fixed Issue #3: Markdown Animation Conflict - Resolved critical issue where animations would freeze when markdown was enabled
Mathematical Expressions - Added comprehensive LaTeX support for inline ($x^2$) and block ($$E=mc^2$$) mathematical expressions
Removed deprecated textScaleFactor - Removed deprecated parameter to fix static analysis warnings
Updated deprecated API usage (withOpacity → withValues)
StreamingTextMarkdown.chatGPT(), .claude(), .typewriter(), .instant() constructorsStreamingTextConfig class for reusable animation configurationschatGPT, claude, typewriter, gentle, bouncy, chunks, rtlOptimized, professionalslow, medium, fast, ultraFastwithOpacity → withValues)docs/ → doc/, added .pubignore)Added professional theme system with StreamingTextTheme
docs: update changelog for version 1.0.2
docs: update changelog for version 1.0.2
prepare for release v1.0.1
prepare for release v1.0.1
✨ Markdown rendering with support for headers, bold, italic, and lists
Initial stable release 🎉
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →