Skip to content

feat: update website about acp clients#14

Merged
sirily11 merged 1 commit into
mainfrom
acp-website
May 15, 2026
Merged

feat: update website about acp clients#14
sirily11 merged 1 commit into
mainfrom
acp-website

Conversation

@sirily11

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings May 15, 2026 10:19
@vercel

vercel Bot commented May 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rxcode Ready Ready Preview, Comment May 15, 2026 10:20am

Request Review

@sirily11 sirily11 enabled auto-merge (squash) May 15, 2026 10:19
@autopilot-project-manager autopilot-project-manager Bot added the enhancement New feature or request label May 15, 2026
@sirily11 sirily11 merged commit 1a1e2e3 into main May 15, 2026
8 checks passed
@sirily11 sirily11 deleted the acp-website branch May 15, 2026 10:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the marketing website and app UI to better reflect ACP (Agent Client Protocol) client support, adds a dedicated Release Notes page to the website, and introduces per-project model/provider defaults in the macOS app.

Changes:

  • Website: add /release page and supporting release-notes fetching/rendering + styling.
  • Website: update homepage/OG copy and feature cards to highlight ACP clients + registry install flow.
  • App: add per-project model/provider persistence and update ACP settings UI navigation.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
website/app/release/page.tsx New Release Notes page UI rendering fetched release notes.
website/app/page.tsx Marketing updates for ACP clients + feature layout changes; links now point to /release.
website/app/lib/release.ts Adds GitHub releases list fetching + lightweight markdown-to-HTML conversion; introduces Sparkle parsing helpers.
website/app/lib/og-image.tsx Updates OG description text to mention ACP clients.
website/app/globals.css Adds .release-notes typographic styles for rendered release notes HTML.
RxCode/Views/Settings/ACPClientSettingsTab.swift Adds segmented Installed/Registry navigation and lazy registry refresh.
RxCode/Views/MainView.swift Uses AppState.effectiveModelSelection(in:) for model/provider display.
RxCode/App/AppState.swift Adds per-project model/provider default selection logic and persistence.
README.md Documentation updates to include ACP clients + registry installer.
Packages/Sources/RxCodeCore/Models/Project.swift Persists per-project lastAgentProvider and lastModel.
Comments suppressed due to low confidence (1)

RxCode/Views/MainView.swift:792

  • Same as above: effectiveModelSelection(in:) is computed twice for effectiveModel/effectiveProvider, which repeats selection work on every render of this sheet. Compute once and reuse to keep SwiftUI updates cheaper.
    private var effectiveModel: String { appState.effectiveModelSelection(in: windowState).model }
    private var effectiveProvider: AgentProvider { appState.effectiveModelSelection(in: windowState).provider }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 30 to 37
type GitHubRelease = {
tag_name: string;
name: string;
html_url: string;
published_at: string;
body: string | null;
prerelease: boolean;
assets: GitHubAsset[];
Comment on lines +210 to +264
function inlineMarkdownToHtml(value: string): string {
return escapeHtml(value)
.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>")
.replace(/`([^`]+)`/g, "<code>$1</code>");
}

function releaseMarkdownToHtml(markdown: string): string {
const lines = markdown.split(/\r?\n/);
const html: string[] = [];
let inList = false;

const closeList = () => {
if (inList) {
html.push("</ul>");
inList = false;
}
};

for (const line of lines) {
const trimmed = line.trim();
if (!trimmed) {
closeList();
continue;
}

if (trimmed.startsWith("### ")) {
closeList();
html.push(`<h3>${inlineMarkdownToHtml(trimmed.slice(4))}</h3>`);
continue;
}

if (trimmed.startsWith("## ")) {
closeList();
html.push(`<h2>${inlineMarkdownToHtml(trimmed.slice(3))}</h2>`);
continue;
}

if (trimmed.startsWith("# ")) {
closeList();
html.push(`<h2>${inlineMarkdownToHtml(trimmed.slice(2))}</h2>`);
continue;
}

if (trimmed.startsWith("- ")) {
if (!inList) {
html.push("<ul>");
inList = true;
}
html.push(`<li>${inlineMarkdownToHtml(trimmed.slice(2))}</li>`);
continue;
}

closeList();
html.push(`<p>${inlineMarkdownToHtml(trimmed)}</p>`);
}
Comment on lines +452 to +453
private var effectiveModel: String { appState.effectiveModelSelection(in: windowState).model }
private var effectiveProvider: AgentProvider { appState.effectiveModelSelection(in: windowState).provider }
Comment on lines +145 to +151
function extractHtmlBody(html: string): string {
const bodyMatch = html.match(/<body\b[^>]*>([\s\S]*?)<\/body>/i);
const inner = bodyMatch ? bodyMatch[1] : html;
return inner
.replace(/<script\b[\s\S]*?<\/script>/gi, "")
.replace(/<style\b[\s\S]*?<\/style>/gi, "")
.trim();
Comment thread RxCode/App/AppState.swift
Comment on lines +664 to +717
private func isModelAvailable(_ model: String, provider: AgentProvider) -> Bool {
availableAgentModelSections()
.flatMap(\.models)
.contains { $0.provider == provider && $0.id == model }
}

private func projectDefaultModelSelection(for project: Project?) -> (provider: AgentProvider, model: String)? {
guard let project,
let provider = project.lastAgentProvider,
let model = project.lastModel,
isModelAvailable(model, provider: provider)
else {
return nil
}
return (provider, model)
}

func defaultModelSelection(for project: Project?) -> (provider: AgentProvider, model: String) {
projectDefaultModelSelection(for: project) ?? (selectedAgentProvider, selectedModel)
}

func effectiveModelSelection(in window: WindowState) -> (provider: AgentProvider, model: String) {
if let provider = window.sessionAgentProvider, let model = window.sessionModel {
return (provider, model)
}
if let model = window.sessionModel {
return (window.sessionAgentProvider ?? selectedAgentProvider, model)
}
return defaultModelSelection(for: window.selectedProject)
}

private func rememberProjectModelSelection(_ model: String, provider: AgentProvider, in window: WindowState) {
guard let project = window.selectedProject,
let index = projects.firstIndex(where: { $0.id == project.id })
else {
return
}

guard projects[index].lastAgentProvider != provider || projects[index].lastModel != model else {
return
}

projects[index].lastAgentProvider = provider
projects[index].lastModel = model
window.selectedProject = projects[index]

Task {
do {
try await persistence.saveProjects(projects)
} catch {
logger.error("Failed to save project model selection: \(error.localizedDescription)")
}
}
}
@sirily11

Copy link
Copy Markdown
Contributor Author

🎉 This PR is included in version 1.3.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants