Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ RxCode/GoogleService-Info.plist
RxCodeMobile/GoogleService-Info.plist
RxCodeAndroid/app/google-services.json
.env
*.log
8 changes: 7 additions & 1 deletion Packages/Sources/RxCodeMarkdown/MarkdownView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,14 @@ private struct MarkdownDocumentView: View {
}

private func opacity(for range: Range<Int>) -> Double {
// A block-level element fades in only when it first appears. We key the
// fade off the segment containing the block's start offset rather than
// any overlapping segment. Otherwise, appending content to an existing
// block during streaming (e.g. new table rows or code lines) keeps
// overlapping the newest fade segment and re-fades the whole block on
// every chunk — which shows up as the block blinking repeatedly.
fadeSegments
.filter { $0.range.overlaps(range) }
.filter { $0.range.contains(range.lowerBound) }
.map(\.opacity)
.min() ?? 1
}
Expand Down
17 changes: 17 additions & 0 deletions RxCode.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
DFA0CCD22FB4CC01005991E1 /* PlanCardViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFA0CCC12FB4CC01005991E1 /* PlanCardViewTests.swift */; };
DFA0CCD42FB4CC01005991E1 /* RxCodeChatKit in Frameworks */ = {isa = PBXBuildFile; productRef = DFA0CCC32FB4CC01005991E1 /* RxCodeChatKit */; };
DFA0CCE12FB4CC02005991E1 /* HistoryListArchiveFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFA0CCD52FB4CC02005991E1 /* HistoryListArchiveFilterTests.swift */; };
DFA8E3B42FD1A27F00F33E7F /* SDWebImageSVGCoder in Frameworks */ = {isa = PBXBuildFile; productRef = DFA8E3B32FD1A27F00F33E7F /* SDWebImageSVGCoder */; };
DFAA00012FCD34B3002D9562 /* JSONSchema in Frameworks */ = {isa = PBXBuildFile; productRef = DFAA00022FCD34B3002D9562 /* JSONSchema */; };
DFAA01102FCD34B3002D9562 /* JSONSchema in Frameworks */ = {isa = PBXBuildFile; productRef = DFAA01112FCD34B3002D9562 /* JSONSchema */; };
E62000012FCB000100000001 /* MemoryIntentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E62000002FCB000100000001 /* MemoryIntentTests.swift */; };
Expand Down Expand Up @@ -264,6 +265,7 @@
DF230BA32FBC73BA008929A6 /* RxCodeSync in Frameworks */,
DF230BA12FBC73BA008929A6 /* RxCodeCore in Frameworks */,
DF230B9F2FBC73BA008929A6 /* RxCodeChatKit in Frameworks */,
DFA8E3B42FD1A27F00F33E7F /* SDWebImageSVGCoder in Frameworks */,
FB0000070000000000000001 /* FirebaseAnalytics in Frameworks */,
FB0000080000000000000001 /* FirebaseCrashlytics in Frameworks */,
DF46683C2FCDB56B002D9562 /* JSONSchemaValidator in Frameworks */,
Expand Down Expand Up @@ -510,6 +512,7 @@
DF4668392FCDB56B002D9562 /* JSONSchemaForm */,
DF46683B2FCDB56B002D9562 /* JSONSchemaValidator */,
DFAA01112FCD34B3002D9562 /* JSONSchema */,
DFA8E3B32FD1A27F00F33E7F /* SDWebImageSVGCoder */,
);
productName = RxCodeMobile;
productReference = DF230B4F2FBC7367008929A6 /* RxCodeMobile.app */;
Expand Down Expand Up @@ -685,6 +688,7 @@
DF462DC72FC73FA8002D9562 /* XCRemoteSwiftPackageReference "RxAuthSwift" */,
DF4652662FCD34B3002D9562 /* XCRemoteSwiftPackageReference "swift-jsonschema-form" */,
DFAA00032FCD34B3002D9562 /* XCRemoteSwiftPackageReference "swift-json-schema" */,
DFA8E3B22FD1A27F00F33E7F /* XCRemoteSwiftPackageReference "SDWebImageSVGCoder" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = E67335392F7356F600FD26C7 /* Products */;
Expand Down Expand Up @@ -1546,6 +1550,14 @@
kind = branch;
};
};
DFA8E3B22FD1A27F00F33E7F /* XCRemoteSwiftPackageReference "SDWebImageSVGCoder" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SDWebImage/SDWebImageSVGCoder";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.8.0;
};
};
DFAA00032FCD34B3002D9562 /* XCRemoteSwiftPackageReference "swift-json-schema" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/sirily11/swift-json-schema";
Expand Down Expand Up @@ -1680,6 +1692,11 @@
isa = XCSwiftPackageProductDependency;
productName = RxCodeChatKit;
};
DFA8E3B32FD1A27F00F33E7F /* SDWebImageSVGCoder */ = {
isa = XCSwiftPackageProductDependency;
package = DFA8E3B22FD1A27F00F33E7F /* XCRemoteSwiftPackageReference "SDWebImageSVGCoder" */;
productName = SDWebImageSVGCoder;
};
DFAA00022FCD34B3002D9562 /* JSONSchema */ = {
isa = XCSwiftPackageProductDependency;
package = DFAA00032FCD34B3002D9562 /* XCRemoteSwiftPackageReference "swift-json-schema" */;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions RxCode/App/AppState+MobileRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@
}

func handleMobileSkillCatalogRequest(_ request: SkillCatalogRequestPayload, fromHex: String) async {
logger.info("[MobileSync] skill catalog handler start requestID=\(request.clientRequestID.uuidString, privacy: .public) forceRefresh=\(request.forceRefresh, privacy: .public) mobileKey=\(String(fromHex.prefix(12)), privacy: .public)")
let plugins = await mobileSkillPlugins(forceRefresh: request.forceRefresh)
let sources = await mobileSkillSources()
logger.info("[MobileSync] skill catalog handler result requestID=\(request.clientRequestID.uuidString, privacy: .public) plugins=\(plugins.count, privacy: .public) sources=\(sources.count, privacy: .public) mobileKey=\(String(fromHex.prefix(12)), privacy: .public)")
let result = SkillCatalogResultPayload(
clientRequestID: request.clientRequestID,
ok: true,
Expand Down Expand Up @@ -207,14 +209,18 @@
}

func handleMobileACPRegistryRequest(_ request: ACPRegistryRequestPayload, fromHex: String) async {
logger.info("[MobileSync] acp registry handler start requestID=\(request.clientRequestID.uuidString, privacy: .public) forceRefresh=\(request.forceRefresh, privacy: .public) mobileKey=\(String(fromHex.prefix(12)), privacy: .public)")
await refreshACPRegistry(forceRefresh: request.forceRefresh)
let ok = acpRegistry != nil
let agents = mobileACPRegistryAgents()
let clients = mobileACPClients()
logger.info("[MobileSync] acp registry handler result requestID=\(request.clientRequestID.uuidString, privacy: .public) ok=\(ok, privacy: .public) agents=\(agents.count, privacy: .public) clients=\(clients.count, privacy: .public) mobileKey=\(String(fromHex.prefix(12)), privacy: .public)")
let result = ACPRegistryResultPayload(
clientRequestID: request.clientRequestID,
ok: ok,
errorMessage: ok ? nil : "Could not load the ACP agent registry.",
registryAgents: mobileACPRegistryAgents(),
installedClients: mobileACPClients()
registryAgents: agents,
installedClients: clients
)
await MobileSyncService.shared.send(.acpRegistryResult(result), toHex: fromHex)
}
Expand Down Expand Up @@ -737,4 +743,4 @@
threadStore.upsert(allSessionSummaries[index])
}

}

Check warning on line 746 in RxCode/App/AppState+MobileRemote.swift

View workflow job for this annotation

GitHub Actions / swiftlint

File should contain 600 lines or less excluding comments and whitespaces: currently contains 642 (file_length)
24 changes: 23 additions & 1 deletion RxCode/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -6601,6 +6601,28 @@
}
}
},
"hook.pullRequest.creating" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Creating pull request…"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "풀 리퀘스트 생성 중…"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "正在创建拉取请求…"
}
}
}
},
"hook.secrets.downloading" : {
"localizations" : {
"en" : {
Expand Down Expand Up @@ -15505,4 +15527,4 @@
}
},
"version" : "1.1"
}
}
1 change: 1 addition & 0 deletions RxCode/Views/ProjectWindowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct ProjectWindowView: View {
.onAppear {
windowState.isProjectWindow = true
}
.hookUI()
.sheet(item: Bindable(windowState).inspectorFile) { file in
FileInspectorView(filePath: file.path, fileName: file.name)
.frame(minWidth: 1000, idealWidth: 1400, maxWidth: 1920,
Expand Down
6 changes: 5 additions & 1 deletion RxCode/Views/Sidebar/ProjectListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ struct ProjectListView: View {
private func startCreatePR(_ project: Project) {
guard creatingPRProjectId == nil else { return }
creatingPRProjectId = project.id
appState.hookProgressStatus = "hook.pullRequest.creating"
Task { @MainActor in
defer { creatingPRProjectId = nil }
defer {
creatingPRProjectId = nil
appState.hookProgressStatus = nil
}
do {
let url = try await appState.createPullRequestForCurrentBranch(project: project)
NSWorkspace.shared.open(url)
Expand Down
6 changes: 5 additions & 1 deletion RxCode/Views/Sidebar/ProjectTreeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,12 @@ private struct ProjectTreeRow: View {
private func startCreatePR() {
guard !creatingPR else { return }
creatingPR = true
appState.hookProgressStatus = "hook.pullRequest.creating"
Task { @MainActor in
defer { creatingPR = false }
defer {
creatingPR = false
appState.hookProgressStatus = nil
}
do {
let url = try await appState.createPullRequestForCurrentBranch(project: project)
NSWorkspace.shared.open(url)
Expand Down
1 change: 1 addition & 0 deletions RxCodeAndroid/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ dependencies {
implementation(libs.accompanist.permissions)

implementation(libs.coil.compose)
implementation(libs.coil.svg)
implementation(libs.compose.markdown)
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.messaging)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package app.rxlab.rxcode

import android.app.Application
import android.util.Log
import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.decode.SvgDecoder
import com.google.firebase.FirebaseApp
import com.google.firebase.crashlytics.FirebaseCrashlytics
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class RxCodeApplication : Application() {
class RxCodeApplication : Application(), ImageLoaderFactory {
override fun onCreate() {
super.onCreate()
Log.w(TAG, "RxCodeApplication launched")
Expand All @@ -20,6 +23,15 @@ class RxCodeApplication : Application() {
}
}

// ACP registry icons (and some autopilot avatars) are served as SVGs, which
// Android's native ImageDecoder can't handle ("Failed to create image decoder
// … 'unimplemented'"). Register Coil's SvgDecoder on the app-wide ImageLoader so
// every AsyncImage can render them.
override fun newImageLoader(): ImageLoader =
ImageLoader.Builder(this)
.components { add(SvgDecoder.Factory()) }
.build()

private companion object {
private const val TAG = "RxCodeStartup"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ import java.util.UUID
/** Shared JSON config: Swift's default JSONEncoder/JSONDecoder behavior. */
val RxJson: Json = Json {
ignoreUnknownKeys = true
encodeDefaults = false
// Swift's JSONEncoder always emits every stored property, and its JSONDecoder
// requires every non-optional one. kotlinx defaults to omitting a property when
// it equals its default value — which silently drops fields like
// `forceRefresh = false`, causing Swift to fail decoding with keyNotFound and
// the relay to drop the whole payload. Always encode defaults so the wire shape
// matches what Swift's non-optional Codable structs expect.
encodeDefaults = true
explicitNulls = false
isLenient = true
coerceInputValues = true
Expand Down
Loading
Loading