diff --git a/_data/authors.yml b/_data/authors.yml index 708306773..750a06c77 100644 --- a/_data/authors.yml +++ b/_data/authors.yml @@ -551,3 +551,27 @@ mitchellallison: email: mitchell_allison@apple.com github: mitchellallison about: "Mitchell Allison works on Distributed Systems in Swift at Apple." + +mads: + name: Mads Odgaard + email: mads@madsodgaard.com + github: madsodgaard + about: Mads is a Google Summer of Code 2025 contributor, where he worked on bringing JNI support to the jextract tool which is part of the Swift Java interoperability project. + +ahmedelrefaey: + name: Ahmed Elrefaey + email: a7med.mahmoud2004@gmail.com + github: a7medev + about: Ahmed is a Google Summer of Code 2025 contributor, where he worked on improving the display of Swift documentation during code completion in SourceKit-LSP and VS Code. + +kelvin: + name: Tien Quoc (Kelvin) Bui + email: tien-quoc.bui@epita.fr + github: tienquocbui + about: Kelvin is a Google Summer of Code 2025 code contributor, where he worked on improving the console output for Swift Testing. + +priyambada: + name: Priyambada Roul + email: priyaroul99@gmail.com + github: roulpriya + about: Priyambada is a software developer based in Bangalore, working at Cashfree Payments, a leading payment processor in India. Shen she's not coding, she enjoys Bharatanatyam dance, painting, sculpting with clay, and experimenting with side projects on GitHub. \ No newline at end of file diff --git a/_posts/2025-11-NN-swift-gsoc-2025-highlight-1-vscode-swiftly.md b/_posts/2025-11-NN-swift-gsoc-2025-highlight-1-vscode-swiftly.md new file mode 100644 index 000000000..4219c3bad --- /dev/null +++ b/_posts/2025-11-NN-swift-gsoc-2025-highlight-1-vscode-swiftly.md @@ -0,0 +1,99 @@ +--- +layout: new-layouts/post +published: true +date: 2025-02-NN 10:00:00 +title: 'Swift GSoC 2025 highlight: Swiftly (Swift installer) support in Visual Studio Code +author: [ktoso, priyambada] +category: "Community" +--- + +Another year of successful Swift participation in [Google Summer of Code](https://summerofcode.withgoogle.com) 2025 came to an end recently, and this year we'd like to shine some light on the projects and work acomplished during the summer! + +Summer of Code is an annual program, organized by Google, which provides hands-on experience for newcomers contributing +to open source projects. Participants usually are students, but do not have to be. + +In this series of four posts, we'll highlight each of the Summer of Code contributors and their projects. +You can navigate between the posts using these convenient links: + +- Bringing Swiftly support to VS Code (this post) +- [JNI mode for swift-java’s source jextract tool](2025-11-NN-swift-gsoc-2025-highlight-2-swift-java-jextract-jni-mode.md) +- [Improve the display of documentation during code completion in SourceKit-LSP](2025-11-NN-swift-gsoc-2025-highlight-3-vscode-swift-lsp-documentation.md) +- [Improved Console Output for Swift Testing](2025-11-NN-swift-gsoc-2025-highlight-4-swift-testing-output.md) + +What follows, is a shortened writeup about their project and experience by the GSoC contributors. +If you'd like to learn more, please check out the full version of their posts on the Swift forums (linked below)! + +--- + +## Bringing Swiftly support to VS Code + +Hi Swift community! 👋 + +I am Priyambada Roul. I'm incredibly excited to share what I've been working on over the past three months as part of Google Summer of Code 2025 with Swift.org, alongside my mentors, @cmcgee1024 @matthewbastien + +My project focused on integrating **Swiftly** (Swift's toolchain manager) into the **VS Code Swift extension.** + +## The Problem We Solved + +We've made switching toolchains easier with Swiftly, allowing you to install and switch between Swift versions without leaving VS Code. + +1. **Switch Swift versions** with a single click + +2. **Install new toolchains** without leaving VS Code + +3. **See real-time progress** during installations + +4. **Automatically sync** with project-specific Swift versions + +## What's New for Swift Developers + +### Swiftly VS Code Integration + +The VS Code extension now provides an entirely **seamless toolchain management experience**: + +* We now support macOS too! + +* See your current Swift version in the VS Code status bar. + +* Click the version to switch between installed toolchains instantly. + +* Install any Swift version directly from VS Code with real-time progress. + +* Automatic detection of .swift-version files with prompts to switch + +### Enhanced Swiftly CLI + +* Swiftly now supports a machine-readable JSON output format. + +* Swiftly now reports toolchain installation progress updates in **JSONL format** + +* We have polished error reporting. + +![](/assets/images/gsoc-25/swiftly-1.jpg) + +![](/assets/images/gsoc-25/swiftly-2.jpg) + +![](/assets/images/gsoc-25/swiftly-3.jpg) + +### Things I learnt + +* Making a VS Code extension. While I have experience with TypeScript from web development, the VS Code extension API and its development workflow are different from what I'm used to. + +* I understood the structure and distribution of Swift toolchains, as well as how different versions can coexist on the same system using symlinks, environment variables, and PATH manipulation, across both macOS and Linux. + +* The extension spawns Swiftly processes and reads their JSON output streams in real-time. This involved learning about IPC mechanisms, stdin/stdout buffering and process lifecycle management. + +Want to see what we built? Check out the repositories: + +* **VS Code Swift Extension**: [github.com/swiftlang/vscode-swift](https://github.com/swiftlang/vscode-swift) + +* **Swiftly CLI**: [github.com/swiftlang/swiftly](https://github.com/swiftlang/swiftly) + +I have linked all pull requests and technical details in my **[detailed project report](https://docs.google.com/document/d/1Mnb9ybmVkpL6pAgrpMbSg6EV3owA2rz_FgltvAXdnUE/edit?tab=t.0)**, which provides an in-depth look into the specific changes. + +This GSoC experience has been transformative. I came in as someone intimidated by large codebases, and I'm leaving with the confidence to tackle complex, multi-tool integrations. I'm excited to continue contributing to Swift community! + + +--- + +If you'd like to learn more about this project, please [check out the full post on the Swift forums](https://forums.swift.org/t/gsoc-2025-bringing-swiftly-support-to-vs-code/81886)! \ No newline at end of file diff --git a/_posts/2025-11-NN-swift-gsoc-2025-highlight-2-swift-java-jextract-jni-mode.md b/_posts/2025-11-NN-swift-gsoc-2025-highlight-2-swift-java-jextract-jni-mode.md new file mode 100644 index 000000000..6d79acfcc --- /dev/null +++ b/_posts/2025-11-NN-swift-gsoc-2025-highlight-2-swift-java-jextract-jni-mode.md @@ -0,0 +1,130 @@ +--- +layout: new-layouts/post +published: true +date: 2025-02-NN 10:00:00 +title: 'Swift GSoC 2025 highlight: JNI mode for SwiftJava interoperability jextract tool +author: [ktoso, mads] +category: "Community" +--- + +Another year of successful Swift participation in [Google Summer of Code](https://summerofcode.withgoogle.com) 2025 came to an end recently, and this year we'd like to shine some light on the projects and work acomplished during the summer! + +Summer of Code is an annual program, organized by Google, which provides hands-on experience for newcomers contributing +to open source projects. Participants usually are students, but do not have to be. + +In this series of four posts, we'll highlight each of the Summer of Code contributors and their projects. + +- [Bringing Swiftly support to VS Code](2025-11-NN-swift-gsoc-2025-highlight-1-vscode-swiftly.md) +- JNI mode for swift-java’s source jextract tool (this post) +- [Improve the display of documentation during code completion in SourceKit-LSP](2025-11-NN-swift-gsoc-2025-highlight-3-vscode-swift-lsp-documentation.md) +- [Improved Console Output for Swift Testing](2025-11-NN-swift-gsoc-2025-highlight-4-swift-testing-output.md) + +--- + +## JNI mode for SwiftJava interoperability jextract tool + +My name is Mads and I am excited to share with you what I have been working on for Swift/Java interoperability over the summer with my mentor Konrad for Google Summer of Code 2025. + +# Overview + +> You can also view Mads' presentation from the Serverside.swift conference about his work on this project: [Expanding Swift/Java Interoperability](https://www.youtube.com/watch?v=tOH6V1IvTAc). + +The [swift-java](https://github.com/swiftlang/swift-java) interoperability library provides the `swift-java jextract` tool, which automatically generates Java sources that are used to call Swift code from Java. Previously, this tool only worked using the [Foreign Function and Memory API (FFM)](https://docs.oracle.com/en/java/javase/21/core/foreign-function-and-memory-api.html), which requires JDK 22+, making it unavailable on platforms such as Android. The goal of this project was to extend the jextract tool, such that it is able to generate Java sources using JNI instead of FFM and thereby allowing more platforms to utilize Swift/Java interoperability. + +I am very glad to report that we have succeeded in that goal, supporting even more features than initially planned! Our initial goal was to achieve feature parity with the FFM mode, but the new JNI mode also supports additional Swift language features such as enums and protocols! + +With the outcome of this project, you can now run the following command to automatically generate Java wrappers for your Swift library using JNI, therefore opening up the possibility of using it on platforms such as Android. + +```bash +swift-java jextract --swift-module MySwiftLibrary \ + --mode jni \ + --input-swift Sources/MySwiftLibrary \ + --output-java out/java \ + --output-swift out/swift +``` + +# How does it work? + +Each Swift class/struct is extracted as a single Java `class`. Functions and variables are generated as Java methods, that internally calls down to a native method that is implemented in Swift using `@_cdecl`. Take a look at the following example: + +```swift +public class MySwiftClass { + public let x: Int64 + public init(x: Int64) { + self.x = x + } + + public func printMe() { + print(“\(self.x)”); + } +} +``` + +It is roughly generated to the equivalent Java `class`: + +```java +public final class MySwiftClass implements JNISwiftInstance { + public static MySwiftClass init(long x, long y, SwiftArena swiftArena$) { + return MySwiftClass.wrapMemoryAddressUnsafe(MySwiftClass.$init(x, y), swiftArena$); + } + + public long getX() { + return MySwiftClass.$getX(this.$memoryAddress()); + } + + public void printMe() { + MySwiftClass.$printMe(this.$memoryAddress()); + } + + private static native long $init(long x, long y); + private static native long $getX(long self); + private static native void $printMe(long self); +} +``` +We also generate additional Swift thunks that actually implement the `native` methods and call the underlying Swift methods. + +You can learn more about how the memory allocation and management works [in the full version of this post of this post on the Swift forums](https://forums.swift.org/t/gsoc-2025-new-jni-mode-added-to-swift-java-jextract-tool/81858)! + +An interesting aspect of an interoperability library such as `swift-java` is the memory management between the two sides, in this case the JVM and Swift. The FFM mode uses the FFM APIs around `MemorySegment` to allocate and manage native memory. We are not so lucky in JNI. In older Java versions there are different ways of allocating memory, such as `Unsafe` or `ByteBuffer.allocateDirect()`. We could have decided to use these and allocate memory on the Java side, like FFM, but instead we decided to move the responsibility to Swift, which allocates the memory instead. This had some nice upsides, as we did not have to mess the the witness tables like FFM does. + +> For more info on memory in FFM, I strongly recommend watching Konrad’s talk [try\! Swift Tokyo 2025 \- Foreign Function and Memory APIs and Swift/Java interoperability](https://www.youtube.com/watch?v=vgtzhTOhEbs) + +The most obvious place we need to allocate memory is when we initialize a wrapped Swift `class`. Take a look at the following generated code for a Swift initializer: +```java +public static MySwiftClass init(SwiftArena swiftArena$) { + return MySwiftClass.wrapMemoryAddressUnsafe(MySwiftClass.$init(), swiftArena$); +} +private static native long $init(); +``` +Here we see that we are calling a native method `$init` which returns a `long`. This value is a pointer to the Swift instance in the memory space of Swift. It is passed to `wrapMemoryAddressUnsafe`, which is basically just storing the pointer in a local field and registering the wrapper to the `SwiftArena`. + +`SwiftArena` is a type that is used to ensure we eventually deallocate the memory when the Java wrapper is no longer needed. There exists two implements of this: + +1. `SwiftArena.ofConfined()`: returns a confined arena which is used with *try-with-resource*, to deallocate all instances at the end of some scope. +2. `SwiftArena.ofAuto()`: returns an arena that deallocates instances once the garbage-collector has decided to do so. + +This concept also exists in the FFM mode, and I recommend watching Konrad’s talk to learn more about them! + +If we take a look at the native implementation of `$init` in Swift, we see how we allocate and initialize the memory: +```swift +// Generated code, not something you would write + +@_cdecl("Java_com_example_swift_MySwiftClass__00024init__JJ") +func Java_com_example_swift_MySwiftClass__00024init__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, x: jlong, y: jlong) -> jlong { + let result$ = UnsafeMutablePointer.allocate(capacity: 1) + result$.initialize(to: MySwiftClass.init(x: Int64(fromJNI: x, in: environment!), y: Int64(fromJNI: y, in: environment!))) + let resultBits$ = Int64(Int(bitPattern: result$)) + return resultBits$.getJNIValue(in: environment!) +} +``` +We are basically allocating memory for a single instance of `MySwiftClass`, initializing it to a new instance and returning the memory address of the pointer. It is the same approach for `struct` as well\! + +# My experience with GSoC + +Google Summer of Code was an awesome experience for me\! I got to work with my favourite language on a library that is very relevant\! A **HUGE** thanks to my mentor @ktoso, who provided invaluable guidance, was always available for questions and allowed me to experiment and take ownership of the work\! + +I would definitely recommend GSoC to anyone interested, it is a great way to engage with the open-source community, develop your skills and work with some talented people\! My number one advice would be to never be afraid of asking seemingly “stupid” questions, they might not be that stupid afterall. + +--- + +If you'd like to learn more about this project, please [check out the full post on the Swift forums](https://forums.swift.org/t/gsoc-2025-new-jni-mode-added-to-swift-java-jextract-tool/81858) as it contains lots of more additional examples and in-depth discussion about memory management and trade-offs this project had to resolve! \ No newline at end of file diff --git a/_posts/2025-11-NN-swift-gsoc-2025-highlight-3-vscode-swift-lsp-documentation.md b/_posts/2025-11-NN-swift-gsoc-2025-highlight-3-vscode-swift-lsp-documentation.md new file mode 100644 index 000000000..f4fd373ce --- /dev/null +++ b/_posts/2025-11-NN-swift-gsoc-2025-highlight-3-vscode-swift-lsp-documentation.md @@ -0,0 +1,64 @@ +--- +layout: new-layouts/post +published: true +date: 2025-02-NN 10:00:00 +title: 'Swift GSoC 2025 highlight: Improve the display of documentation during code completion in SourceKit-LSP +author: [ktoso, ahmedelrefaey, hamish] +category: "Community" +--- + +Another year of successful Swift participation in [Google Summer of Code](https://summerofcode.withgoogle.com) 2025 came to an end recently, and this year we'd like to shine some light on the projects and work acomplished during the summer! + +Summer of Code is an annual program, organized by Google, which provides hands-on experience for newcomers contributing +to open source projects. Participants usually are students, but do not have to be. + +In this series of four posts, we'll highlight each of the Summer of Code contributors and their projects. + +- [Bringing Swiftly support to VS Code](2025-11-NN-swift-gsoc-2025-highlight-1-vscode-swiftly.md) +- [JNI mode for swift-java’s source jextract tool](2025-11-NN-swift-gsoc-2025-highlight-2-swift-java-jextract-jni-mode.md) +- Improve the display of documentation during code completion in SourceKit-LSP (this post) +- [Improved Console Output for Swift Testing](2025-11-NN-swift-gsoc-2025-highlight-4-swift-testing-output.md) + +--- + +## Improve the display of documentation during code completion in SourceKit-LSP + +Hi everyone! + +This is Ahmed Elrefaey, I’m excited to share with you an update on my GSoC project, Improve the display of documentation during code completion in SourceKit-LSP, mentored by Hamish Knight. + +### Project Goals + +The aim of this project is to enhance how documentation is displayed in SourceKit-LSP during code completion by: + +1. Showing the full documentation for a code completion item instead of the first paragraph only, which we call “brief documentation”. +2. Implementing Language Server Protocol’s [signature help](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_signatureHelp) request showing the user which overloads are available, along with their corresponding documentation. + +### Progress + +During this summer, we have made great progress on this project that I want to share with you. + +We have successfully implemented full documentation comment retrieval for completion items by lazily retrieving the full documentation comment upon request to avoid having to fetch all documentation comments at once. + +Here’s what SourceKit-LSP currently provides in VS Code (brief documentation): + +![Brief documentation demo in VS Code.|690x412](/assets/images/gsoc-25/brief.gif) + +And here’s how it looks with full documentation: + +![Full documentation demo in VS Code.|690x412](/assets/images/gsoc-25/full.gif) + +We have also implemented a large portion of signature help support, showing the available overloads and their corresponding documentation while editing. +We reused the existing argument completion logic to determine the overloads and refactored the code completion item description implementation to reuse it in signature help. + +Here’s a quick demo of signature help in VS Code. + +![Signature help demo in VS Code|690x441](/assets/images/gsoc-25/output.gif) + +### Closing Thoughts + +I'm incredibly grateful for this opportunity to contribute to the Swift project, and I really learned a lot from this experience. I'd like to thank my mentor, Hamish Knight, for his unwavering support and guidance throughout this summer. I’d also like to thank Alex Hoppen, Rintaro Ishizaki, and Ben Barham for their valuable feedback during code review. + +--- + +If you'd like to learn more about this project, please [check out the full post on the Swift forums](https://forums.swift.org/t/gsoc-2025-improve-the-display-of-documentation-during-code-completion-in-sourcekit-lsp/81976)! \ No newline at end of file diff --git a/_posts/2025-11-NN-swift-gsoc-2025-highlight-4-swift-testing-output.md b/_posts/2025-11-NN-swift-gsoc-2025-highlight-4-swift-testing-output.md new file mode 100644 index 000000000..2f03219bb --- /dev/null +++ b/_posts/2025-11-NN-swift-gsoc-2025-highlight-4-swift-testing-output.md @@ -0,0 +1,102 @@ +--- +layout: new-layouts/post +published: true +date: 2025-02-NN 10:00:00 +title: 'Swift GSoC 2025 highlight: Improved Console Output for Swift Testing +author: [ktoso, kelvin] +category: "Community" +--- + +Another year of successful Swift participation in [Google Summer of Code](https://summerofcode.withgoogle.com) 2025 came to an end recently, and this year we'd like to shine some light on the projects and work acomplished during the summer! + +Summer of Code is an annual program, organized by Google, which provides hands-on experience for newcomers contributing +to open source projects. Participants usually are students, but do not have to be. + +In this series of four posts, we'll highlight each of the Summer of Code contributors and their projects. + +- [Bringing Swiftly support to VS Code](2025-11-NN-swift-gsoc-2025-highlight-1-vscode-swiftly.md) +- [JNI mode for swift-java’s source jextract tool](2025-11-NN-swift-gsoc-2025-highlight-2-swift-java-jextract-jni-mode.md) +- [Improve the display of documentation during code completion in SourceKit-LSP](2025-11-NN-swift-gsoc-2025-highlight-3-vscode-swift-lsp-documentation.md) +- Improved Console Output for Swift Testing (this post) + +--- + +## Improved Console Output for Swift Testing + +Hello everyone! My name is Kelvin Bui, and I'm excited to share my GSoC 2025 project, where I worked on improving the console output for the Swift Testing framework with my mentor, @stmontgomery. + +### Overview + +This summer, as part of Google Summer of Code 2025, I had the incredible opportunity to work on [improving the console output for the Swift Testing framework](https://www.swift.org/gsoc2025/). The primary goal was to transform the existing static log into a modern, clear, and highly useful tool for developers. The main achievement of this project is the design and implementation of a new, two-phase console reporter, with a primary focus on delivering a comprehensive **Hierarchical Summary** and **Detailed Failure Report**. It also leverages serialization to allow emitting output from a separate supervisor process, in alignment with future project directions. + +### Problem & Motivation + +The default console output for `swift test` was functional but presented several challenges for developers working on large and complex projects: + +* **Difficulty Locating Failures:** In large test suites, critical failure messages were often lost in a long stream of success outputs, making it hard to quickly assess the health of a test run. +* **Lack of Structure:** The flat log format made it difficult to understand the relationship between tests and their parent suites, especially in projects with many nested modules. + +Our vision was to solve these problems by creating an advanced console reporter that is both informative and intuitive. + +## Key Technical Achievements + +**Hierarchical Test Display:** + +* A clear, indented tree structure that visualizes the relationship between suites and tests. +* An "issues as sub-nodes" model for displaying rich failure context directly within the hierarchy. +* An "out-dented" suite summary line that cleanly concludes each suite's output. + +**Serialization-Based Architecture:** + +* A future-proof design that processes `ABI.EncodedEvent` objects, preparing the reporter for an out-of-process harness architecture. +* Logic to build an in-memory representation of the test plan by consuming initial test discovery events and then looking up test details by ID for subsequent events. + +**Rich Failure Reporting:** + +* A dedicated `FAILED TEST DETAILS` section that provides comprehensive information for each failure, including the fully qualified test name, a detailed error message, and the exact source location (`file:line`). + +## Visuals: Before & After + +The Advanced Console Output Recorder fundamentally transforms how developers interact with test results. By introducing a visual hierarchy and detailed contextual information, it elevates the diagnostic experience from a flat, hard-to-parse log into a structured, scannable report. + +**Current Console Output:** +![Current Console Output](/assets/images/gsoc-25/testing-output-1.jpg) + + +Prior to this project, the default `swift test` output presented a linear, undifferentiated stream of events. While functional, this format lacked visual cues, making it challenging to quickly identify test relationships, pinpoint failures within large suites, or understand the overall structure of a test run. The absence of clear demarcation between test suites and individual tests often led to slower debugging cycles and increased cognitive load for developers. + +**New Hierarchical Summary:** +![New Hierarchical Test Results](/assets/images/gsoc-25/testing-output-2.jpg) + +The new recorder introduces a rich, hierarchical display that immediately brings order and clarity to test output. Using Unicode box-drawing characters (with ASCII fallback), it clearly visualizes the nested structure of test modules, suites, and individual tests. This not only makes the test results significantly easier to read and navigate but also provides crucial context around failed tests, displaying detailed issue descriptions directly within their respective hierarchical nodes. This transformation dramatically improves the developer experience by offering instant insights into test organization and failure points. + +![Failed Tests Showcase](/assets/images/gsoc-25/testing-output-3.jpg) + +## Challenges & Lessons Learned + +**Technical lessons:** + +* Designing for serialization & ABI: Refactoring to consume ABI.EncodedEvent taught me the value of decoupling - moving from in-process object graphs to a serialized event stream increases robustness and enables harness-style execution. It also exposed careful trade-offs: serialization simplifies process boundaries but requires stable encoding contracts and more explicit discovery/lookup logic for test metadata. +* Building a thread-safe collector for results required balancing lock granularity and throughput. The adopted strategy (a single lock per event bucket, plus careful mutation patterns) simplifies correctness while keeping contention low for typical test workloads. +* Cross-platform fallbacks: Supporting ASCII fallback for line-drawing characters taught me to design for the weakest terminal capability first, then progressively enhance for modern terminals. Testing across Windows/Linux/macOS terminals and non-interactive CI runners uncovered many small but critical edge-cases (line-wrapping, width detection fallbacks). +* Deciding what to show inline vs. in a details section is a UX trade-off, too much inline detail makes the tree noisy; too little hides useful context. The two-tier approach (short inline message + full details section) balances these needs. + +**Collaboration & process lessons:** + +* Presenting to the workgroup matters: Early live presentation to the Swift Testing workgroup exposed design assumptions quickly and gave direction that influenced major architectural choices. +* Iterative, small PRs win: Breaking work into digestible PRs (skeleton → ABI pivot → UI features) made reviews actionable and reduced reviewer fatigue. +* Incorporating targeted reviewer comments (e.g., ABI pivot) showed the importance of documenting design decisions (why we choose serialization, how the tree is constructed), which speeds later onboarding and review cycles. + +**Personal growth:** + +I learned how to accept and act on high-quality feedback from senior engineers, and how to reframe technical trade-offs as testable hypotheses. The project sharpened my ability to move from mockups to production code while keeping maintainability and cross-platform compatibility as first-class concerns. + +## Acknowledgements + +I'd like to express my deepest gratitude to my mentor, **Stuart Montgomery**, for his exceptional guidance, patience, and technical insights throughout this entire project. His mentorship has been invaluable. + +I'd also like to thank Jonathan Grynspan for his crucial, in-depth architectural feedback, which significantly improved the project's long-term viability. Thank you as well to **[Swift Testing Workgroup](https://www.swift.org/testing-workgroup/)**, and all the other members of the Swift community who provided thoughtful feedback on the forums. This project would not have been possible without your collective expertise and support. + +---- + +If you'd like to learn more about this project, please [check out the full post on the Swift forums](https://forums.swift.org/t/gsoc-2025-improved-console-output-for-swift-testing/82060)! \ No newline at end of file diff --git a/assets/images/gsoc-25/brief.gif b/assets/images/gsoc-25/brief.gif new file mode 100644 index 000000000..124c334a2 Binary files /dev/null and b/assets/images/gsoc-25/brief.gif differ diff --git a/assets/images/gsoc-25/full.gif b/assets/images/gsoc-25/full.gif new file mode 100644 index 000000000..a460cf388 Binary files /dev/null and b/assets/images/gsoc-25/full.gif differ diff --git a/assets/images/gsoc-25/output.gif b/assets/images/gsoc-25/output.gif new file mode 100644 index 000000000..38b66f0aa Binary files /dev/null and b/assets/images/gsoc-25/output.gif differ diff --git a/assets/images/gsoc-25/swiftly-1.jpg b/assets/images/gsoc-25/swiftly-1.jpg new file mode 100644 index 000000000..42da6ad2a Binary files /dev/null and b/assets/images/gsoc-25/swiftly-1.jpg differ diff --git a/assets/images/gsoc-25/swiftly-2.jpg b/assets/images/gsoc-25/swiftly-2.jpg new file mode 100644 index 000000000..7cbdfc704 Binary files /dev/null and b/assets/images/gsoc-25/swiftly-2.jpg differ diff --git a/assets/images/gsoc-25/swiftly-3.jpg b/assets/images/gsoc-25/swiftly-3.jpg new file mode 100644 index 000000000..0907644c4 Binary files /dev/null and b/assets/images/gsoc-25/swiftly-3.jpg differ diff --git a/assets/images/gsoc-25/testing-output-1.jpg b/assets/images/gsoc-25/testing-output-1.jpg new file mode 100644 index 000000000..a30f9fb09 Binary files /dev/null and b/assets/images/gsoc-25/testing-output-1.jpg differ diff --git a/assets/images/gsoc-25/testing-output-2.jpg b/assets/images/gsoc-25/testing-output-2.jpg new file mode 100644 index 000000000..3c7c01e47 Binary files /dev/null and b/assets/images/gsoc-25/testing-output-2.jpg differ diff --git a/assets/images/gsoc-25/testing-output-3.jpg b/assets/images/gsoc-25/testing-output-3.jpg new file mode 100644 index 000000000..51e834ce6 Binary files /dev/null and b/assets/images/gsoc-25/testing-output-3.jpg differ