Skip to content

Commit b8cf200

Browse files
authored
Merge pull request #5 from spring-ai-community/0.2.0-M4
Release 0.2.0-M4
2 parents e70f6c8 + ae7c092 commit b8cf200

92 files changed

Lines changed: 5504 additions & 1771 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/desktop-release.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ jobs:
6262
- name: Checkout
6363
uses: actions/checkout@v5
6464

65+
- name: Resolve installer version from ref
66+
id: ver
67+
shell: bash
68+
run: |
69+
REF="${{ github.ref_name }}"
70+
if [[ "$REF" =~ ^v?([0-9]+\.[0-9]+\.[0-9]+([.-][A-Za-z0-9]+)*)$ ]]; then
71+
VERSION="${BASH_REMATCH[1]}"
72+
elif [[ "$REF" =~ ^([0-9]+\.[0-9]+\.[0-9]+([.-][A-Za-z0-9]+)*) ]]; then
73+
VERSION="${BASH_REMATCH[1]}"
74+
else
75+
VERSION="${REF}"
76+
fi
77+
# Normalize milestone marker case (e.g., -m4 -> -M4)
78+
VERSION=$(echo "$VERSION" | sed -E 's/-m([0-9]+)/-M\1/')
79+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
80+
echo "Resolved installer version: $VERSION"
81+
6582
- name: Set up GraalVM JDK 21
6683
uses: graalvm/setup-graalvm@v1
6784
with:
@@ -97,6 +114,11 @@ jobs:
97114
working-directory: electron
98115
run: npm ci
99116

117+
- name: Set installer version on electron/package.json
118+
working-directory: electron
119+
shell: bash
120+
run: npm version "${{ steps.ver.outputs.version }}" --no-git-tag-version --allow-same-version
121+
100122
- name: Install frontend dependencies
101123
if: hashFiles('package.json') != ''
102124
run: npm install --no-audit --no-fund
@@ -124,6 +146,8 @@ jobs:
124146
runs-on: ubuntu-latest
125147
permissions:
126148
contents: write
149+
id-token: write # required for Sigstore OIDC token used by build provenance
150+
attestations: write # required to write the attestation back to the repo
127151

128152
steps:
129153
- name: Download installer artifacts
@@ -132,6 +156,24 @@ jobs:
132156
path: release-assets
133157
merge-multiple: true
134158

159+
- name: Generate SHA-256 checksums
160+
working-directory: release-assets
161+
run: |
162+
shopt -s nullglob
163+
for f in *.dmg *.exe *.deb *.rpm; do
164+
sha256sum "$f" > "$f.sha256"
165+
done
166+
ls -la
167+
168+
- name: Attest build provenance
169+
uses: actions/attest-build-provenance@v2
170+
with:
171+
subject-path: |
172+
release-assets/*.dmg
173+
release-assets/*.exe
174+
release-assets/*.deb
175+
release-assets/*.rpm
176+
135177
- name: Upload assets to GitHub Release
136178
uses: softprops/action-gh-release@v2.5.0
137179
with:
@@ -143,4 +185,5 @@ jobs:
143185
release-assets/*.exe
144186
release-assets/*.deb
145187
release-assets/*.rpm
188+
release-assets/*.sha256
146189
generate_release_notes: true

.github/workflows/docs-site.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ jobs:
3939
with:
4040
python-version: "3.12"
4141

42+
- name: Install system libraries for social card rendering
43+
run: |
44+
sudo apt-get update
45+
sudo apt-get install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev pkg-config
46+
4247
- name: Install docs dependencies
4348
run: pip install -r docs/requirements.txt
4449

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,40 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

77
## [Unreleased]
88

9+
## [0.2.0-M4] - 2026-04-27
10+
11+
### Added
12+
13+
- New adaptive Home dashboard with workspace status, provider health pill, recent activity, and a Getting Started checklist that mirrors the first-run flow.
14+
- Agentic Chat surfaces RAG search options (query, filter, top-K, similarity threshold) and emits a structured retrieval-completion event so the UI can show retrieved doc count and titles.
15+
- Agentic Chat anchors the new prompt at the top of the viewport on submit, labels each step with timing/counts (`RAG · {time} · {N docs} · {titles}`, `THINK · {time}`, `MCP TOOLS · {time} · {N calls} · {names}`), preserves the partial assistant response when the user clicks Stop, and shows a Stopped/Error stream-status badge that persists across reload.
16+
- Common workspace shell shared by Chat, MCP, Tool Studio, and Vector Database surfaces (sidebar + content header + settings drawer) for consistent layout.
17+
- Telemetry opt-out (`SPRING_AI_PLAYGROUND_TELEMETRY_ENABLED=false`) now applies uniformly across the web app and every desktop launcher window (splash, server-splash, config editor, Ollama manager).
18+
- Release assets ship with SHA-256 checksums (`.sha256`) and Sigstore build provenance attestations, verifiable via `gh attestation verify --owner spring-ai-community`.
19+
- Documentation site generates per-page Open Graph / Twitter social cards (1200×630) and embeds `SoftwareApplication` JSON-LD schema for richer search results.
20+
- Getting Started page now hosts a platform-aware download confirm popup that resolves the latest release through the GitHub API, shows filename, size, and the typical OS download path; README and the docs home redirect platform badges to the same popup.
21+
22+
### Changed
23+
24+
- Persistence rewritten to save on mutation through an async executor with atomic writes; `SimpleVectorStore` dumps are debounced to coalesce bursts into a single write, keeping disk-write threads non-daemon so in-flight writes finish on shutdown.
25+
- Generic `RuntimeException` wrapping replaced with targeted error handling; MCP startup uses sequential per-server iteration with try/catch in place of `parallelStream` to isolate failures.
26+
- Standardized desktop installer filenames to `spring-ai-playground-<version>-<platform>-<arch>.<ext>` (no spaces, version included). Bumped to `0.2.0-M4`. CI now resolves the installer version from the branch/tag ref and injects it into `electron/package.json` at build time.
27+
- Linux `.deb` / `.rpm` package metadata renamed from `spring-ai-playground-desktop` to `spring-ai-playground` for consistency with the bundle ID, binary, and user-visible app name.
28+
- Architecture documentation split into a dedicated page; README and mkdocs nav aligned with the new Home dashboard.
29+
30+
### Fixed
31+
32+
- `APP_HOME` now defaults to `<user.home>/<app-name>` when the JVM `user.home` property is unset, preventing log/config write failures in containerized environments.
33+
- Loopback MCP client and embedded MCP server are closed before Tomcat graceful shutdown so the JVM exits cleanly.
34+
- Saved persistence files are deleted immediately on removal instead of being deferred to JVM exit, eliminating stale files after a crash.
35+
- MCP client map keys scoped per-server, stale clients closed on update, and self-update flows allowed without orphaning the previous client.
36+
- Chat history reload restores `tool_calls` and matching tool responses correctly.
37+
- Renamed `lancher-*` documentation assets to `launcher-*` (typo fix).
38+
39+
### Security
40+
41+
- Persisted file names are sanitized to prevent path traversal when writing under the application home directory.
42+
943
## [0.2.0-M3] - 2026-04-18
1044

1145
### Added

README.md

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Spring AI Playground is a cross-platform desktop app for building, testing, vali
66

77
> **No pass, no run.**
88
9+
Every tool you build earns a **Local Pass** — a local test-run with your sample arguments. Only passing tools are added live to the built-in MCP server and become callable from Agentic Chat. A tool that has not passed is never exposed to an agent.
10+
911
In Tool Studio, new or updated built-in tools are test-run before they are published to the built-in MCP server. You do not need to know Java, Spring, or JVM internals to use it. If you can install a desktop app and write a small JavaScript function, you can build tools here and connect them to hosts and clients such as Claude Desktop, Claude Code, Cursor, IDEs, and other MCP-compatible environments.
1012

1113
## The Problem
@@ -36,13 +38,13 @@ Spring AI Playground is a standalone desktop app, so you can install it and star
3638

3739
Choose the installer for your platform from the latest release:
3840

39-
[![Windows](https://img.shields.io/badge/Windows-NSIS%20Installer-0078D6?logo=windows&logoColor=white)](https://github.com/spring-ai-community/spring-ai-playground/releases/latest/download/Spring.AI.Playground.exe)
40-
[![macOS Apple Silicon](https://img.shields.io/badge/macOS-Apple%20Silicon%20arm64-000000?logo=apple&logoColor=white)](https://github.com/spring-ai-community/spring-ai-playground/releases/latest/download/Spring.AI.Playground-arm64.dmg)
41-
[![macOS Intel](https://img.shields.io/badge/macOS-Intel%20x64-555555?logo=apple&logoColor=white)](https://github.com/spring-ai-community/spring-ai-playground/releases/latest/download/Spring.AI.Playground-x64.dmg)
42-
[![Linux DEB](https://img.shields.io/badge/Linux-DEB-A81D33?logo=debian&logoColor=white)](https://github.com/spring-ai-community/spring-ai-playground/releases/latest/download/Spring.AI.Playground.deb)
43-
[![Linux RPM](https://img.shields.io/badge/Linux-RPM-EE0000?logo=redhat&logoColor=white)](https://github.com/spring-ai-community/spring-ai-playground/releases/latest/download/Spring.AI.Playground.rpm)
41+
[![Windows](https://img.shields.io/badge/Windows-NSIS%20Installer-0078D6?logo=windows&logoColor=white)](https://spring-ai-community.github.io/spring-ai-playground/getting-started/#win-x64)
42+
[![macOS Apple Silicon](https://img.shields.io/badge/macOS-Apple%20Silicon%20arm64-000000?logo=apple&logoColor=white)](https://spring-ai-community.github.io/spring-ai-playground/getting-started/#mac-arm64)
43+
[![macOS Intel](https://img.shields.io/badge/macOS-Intel%20x64-555555?logo=apple&logoColor=white)](https://spring-ai-community.github.io/spring-ai-playground/getting-started/#mac-x64)
44+
[![Linux DEB](https://img.shields.io/badge/Linux-DEB-A81D33?logo=debian&logoColor=white)](https://spring-ai-community.github.io/spring-ai-playground/getting-started/#linux-deb)
45+
[![Linux RPM](https://img.shields.io/badge/Linux-RPM-EE0000?logo=redhat&logoColor=white)](https://spring-ai-community.github.io/spring-ai-playground/getting-started/#linux-rpm)
4446

45-
Or browse all available assets on the [Releases page](https://github.com/spring-ai-community/spring-ai-playground/releases).
47+
The Getting Started page resolves to the latest published release automatically. The downloaded file keeps the version in its name (e.g. `spring-ai-playground-0.2.0-M4-mac-arm64.dmg`). Or browse all available assets on the [Releases page](https://github.com/spring-ai-community/spring-ai-playground/releases).
4648

4749
### 2. Install and Launch
4850

@@ -80,6 +82,30 @@ If you install the app, you can run Spring AI Playground immediately without set
8082
>
8183
> For more detailed platform guidance, see the [Getting Started guide](https://spring-ai-community.github.io/spring-ai-playground/getting-started/).
8284
85+
### Verify Your Download
86+
87+
Each release ships with two integrity guarantees. You do not have to verify, but it is recommended for production use.
88+
89+
**1. SHA-256 checksum** — every installer has a matching `.sha256` file in the release assets.
90+
91+
```bash
92+
# macOS / Linux
93+
shasum -a 256 -c spring-ai-playground-0.2.0-M4-mac-arm64.dmg.sha256
94+
95+
# Windows (PowerShell)
96+
Get-FileHash spring-ai-playground-0.2.0-M4-win-x64.exe -Algorithm SHA256
97+
# compare the value with the one inside the .sha256 file
98+
```
99+
100+
**2. Sigstore build provenance (SLSA)** — every installer is signed by the official GitHub Actions release workflow using a short-lived Sigstore key, and the attestation is recorded in the public transparency log.
101+
102+
```bash
103+
gh attestation verify spring-ai-playground-0.2.0-M4-mac-arm64.dmg \
104+
--owner spring-ai-community
105+
```
106+
107+
A successful verification proves the file came from this repo's release workflow and was not tampered with after build.
108+
83109
<p align="center">
84110
<b>First-Launch Configuration Screen</b><br/>
85111
Desktop launcher overview with the built-in config editor
@@ -97,8 +123,8 @@ If you install the app, you can run Spring AI Playground immediately without set
97123
</p>
98124

99125
<p align="center">
100-
<a href="docs/assets/images/lancher-ollama-config.png">
101-
<img src="docs/assets/images/lancher-ollama-config.png" width="760" alt="Spring AI Playground Ollama model manager"/>
126+
<a href="docs/assets/images/launcher-ollama-config.png">
127+
<img src="docs/assets/images/launcher-ollama-config.png" width="760" alt="Spring AI Playground Ollama model manager"/>
102128
</a>
103129
</p>
104130

@@ -205,6 +231,23 @@ We triage issues regularly, and issues outside the current scope may be closed w
205231

206232
If you believe you have a contribution that fits the current scope, submit a PR or a targeted issue.
207233

234+
## Anonymous Usage Telemetry
235+
236+
The official build sends anonymous usage data (page views, app surface, device/browser
237+
info) to the maintainer's Google Tag Manager / Google Analytics account so the most-used
238+
features can be prioritized. IPs are anonymized by Google. The same opt-out switch applies
239+
to both the web app and every desktop launcher window (splash, server-splash, config
240+
editor, Ollama manager):
241+
242+
- **Server / Docker / `mvn`**: `SPRING_AI_PLAYGROUND_TELEMETRY_ENABLED=false`
243+
- **Desktop launcher**: set `SPRING_AI_PLAYGROUND_TELEMETRY_ENABLED=false` before launching
244+
the app (the launcher forwards this env var to every window and to the bundled Spring
245+
process)
246+
- **From source / IDE**: pass `-Dspring.ai.playground.telemetry.enabled=false` as a JVM arg
247+
248+
If you self-host this project for EU users, adding cookie consent on top is the
249+
operator's responsibility under GDPR.
250+
208251
## Upcoming Improvements
209252

210253
These are the near-term areas we plan to improve while keeping the project focused on practical, reusable tool execution.

docs-overrides/main.html

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,25 @@
22

33
{% block extrahead %}
44
{{ super() }}
5+
<script>
6+
// Material renders mermaid diagrams inside closed shadow DOM, which blocks
7+
// our pan/zoom hook and any label-wrapping CSS. Force open mode only for
8+
// .mermaid hosts so we can reach into the shadow root from our own JS/CSS.
9+
(function () {
10+
var orig = Element.prototype.attachShadow;
11+
Element.prototype.attachShadow = function (init) {
12+
if (this.classList && this.classList.contains('mermaid')) {
13+
return orig.call(this, Object.assign({}, init || {}, { mode: 'open' }));
14+
}
15+
return orig.call(this, init);
16+
};
17+
})();
18+
</script>
519
{% set ga_measurement_id = "G-52TGT1G9B3" %}
620
{% set page_title = page.title ~ " - " ~ config.site_name if page and page.title else config.site_name %}
21+
{% set ga_page_title = "Doc - " ~ page.title if page and page.title else "Doc - " ~ config.site_name %}
722
{% set page_description = page.meta.description if page and page.meta and page.meta.description else config.site_description %}
823
{% set page_url = config.site_url ~ page.url if page and page.url else config.site_url %}
9-
{% set social_image = config.site_url ~ "assets/images/icon.png" %}
1024
<script async src="https://www.googletagmanager.com/gtag/js?id={{ ga_measurement_id }}"></script>
1125
<script>
1226
window.dataLayer = window.dataLayer || [];
@@ -17,18 +31,37 @@
1731
});
1832
gtag('config', '{{ ga_measurement_id }}', {
1933
app_name: 'spring-ai-playground-docs',
20-
app_surface: 'docs'
34+
app_surface: 'docs',
35+
page_title: '{{ ga_page_title | e }}'
2136
});
2237
</script>
23-
<link rel="canonical" href="{{ page_url | e }}">
38+
{# Open Graph and Twitter Card meta — kept here as a fallback when the
39+
mkdocs-material `social` plugin is not active (e.g. local dev without
40+
the imaging extras). When the plugin runs, it injects its own og:image
41+
and twitter:image with a generated 1200x630 card; browsers honor the
42+
first occurrence, so we keep these tags AFTER plugin injection points.
43+
The canonical link is already produced by mkdocs-material's base
44+
template from `site_url`, so we do not duplicate it here. #}
2445
<meta property="og:site_name" content="{{ config.site_name | e }}">
2546
<meta property="og:type" content="website">
2647
<meta property="og:title" content="{{ page_title | e }}">
2748
<meta property="og:description" content="{{ page_description | e }}">
2849
<meta property="og:url" content="{{ page_url | e }}">
29-
<meta property="og:image" content="{{ social_image | e }}">
3050
<meta name="twitter:card" content="summary_large_image">
3151
<meta name="twitter:title" content="{{ page_title | e }}">
3252
<meta name="twitter:description" content="{{ page_description | e }}">
33-
<meta name="twitter:image" content="{{ social_image | e }}">
53+
<script type="application/ld+json">
54+
{
55+
"@context": "https://schema.org",
56+
"@type": "SoftwareApplication",
57+
"name": "{{ config.site_name | e }}",
58+
"applicationCategory": "DeveloperApplication",
59+
"operatingSystem": "macOS, Windows, Linux",
60+
"url": "{{ config.site_url | e }}",
61+
"downloadUrl": "https://github.com/spring-ai-community/spring-ai-playground/releases/latest",
62+
"license": "https://www.apache.org/licenses/LICENSE-2.0",
63+
"description": "{{ config.site_description | e }}",
64+
"offers": {"@type": "Offer", "price": "0", "priceCurrency": "USD"}
65+
}
66+
</script>
3467
{% endblock %}

0 commit comments

Comments
 (0)