<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David</title>
    <description>The latest articles on DEV Community by David (@dsalvado).</description>
    <link>https://dev.to/dsalvado</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4200960%2F958b9d17-36f9-4442-9d9f-29b102de2537.jpg</url>
      <title>DEV Community: David</title>
      <link>https://dev.to/dsalvado</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dsalvado"/>
    <language>en</language>
    <item>
      <title>"ShuttleSCP, three weeks and 30 releases later"</title>
      <dc:creator>David</dc:creator>
      <pubDate>Sat, 14 Nov 2026 14:00:38 +0000</pubDate>
      <link>https://dev.to/dsalvado/shuttlescp-three-weeks-and-30-releases-later-5e2k</link>
      <guid>https://dev.to/dsalvado/shuttlescp-three-weeks-and-30-releases-later-5e2k</guid>
      <description>&lt;p&gt;Three weeks ago I wrote about &lt;a href="https://dev.to/dsalvado/what-i-learned-building-a-real-app-with-claude-code-1af"&gt;building a real app with Claude Code&lt;/a&gt;: ShuttleSCP, a free SFTP, SCP and FTP client for Linux, macOS and Windows, written in Rust with GTK 4. It was at version 0.13.0. It is now at 0.26.0.&lt;/p&gt;

&lt;p&gt;In between: 30 releases, the code grew from about 22,000 to about 34,000 lines of Rust, and the tests from 149 to about 200. Most of the work wasn't new buttons. It was making copies hold up on real networks and real servers, and being able to prove they did.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjpv9c75k9cqjw1nvbuy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjpv9c75k9cqjw1nvbuy.gif" alt=" " width="760" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The "what's next" shipped first
&lt;/h2&gt;

&lt;p&gt;The last article ended with one goal: make the Linux AppImage run on older systems. That was 0.14.0, the next day. It now runs on Ubuntu 20.04, 22.04 and 24.04 and on Debian 12 and 13, and every release is checked on all of them in containers before it ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copying between two servers
&lt;/h2&gt;

&lt;p&gt;The biggest new feature is &lt;strong&gt;site to site&lt;/strong&gt; (0.15.0): one server in each pane, and you drag files from one to the other. The servers never talk to each other. ShuttleSCP reads from one and writes to the other at the same time, without storing the files on your disk, like &lt;code&gt;scp -3&lt;/code&gt;. That means it works between any two kinds of server, even SFTP on one side and FTP on the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making transfers survive real networks
&lt;/h2&gt;

&lt;p&gt;Tests on a fast local network passed. Real servers found the problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Slow servers.&lt;/strong&gt; Downloads from servers slower than about 0.4 MB/s failed with a timeout. The library waited for a whole batch of requests, not for each one. Fixed in 0.21.3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dropped connections.&lt;/strong&gt; A lost SSH connection used to fail the transfer. Now ShuttleSCP logs in again by itself and continues the file where it stopped, up to three times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browsing during a copy.&lt;/strong&gt; On one connection, opening a folder waited behind the copy's queued reads: seconds per click on a slow line. Transfers now get a second connection of their own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closing the app.&lt;/strong&gt; Partial copies are kept. The next login offers to resume them, and the Login dialog has an Unfinished tab listing them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Knowing the copy is right
&lt;/h2&gt;

&lt;p&gt;Since 0.22.0, every copy is checked against its original by SHA-256 checksum. The server computes its side itself when it can (&lt;code&gt;sha256sum&lt;/code&gt; over SSH, or FTP's &lt;code&gt;HASH&lt;/code&gt; command). When it can't, ShuttleSCP reads the copy back, up to a size you choose. A copy that differs counts as failed, and a move keeps the original.&lt;/p&gt;

&lt;p&gt;This is where testing on the Windows machine paid off: one FTP server answered the hash command with "501 Option not understood", and ShuttleSCP took that as a failure instead of "this server can't do it". It shipped as a fix two hours later.&lt;/p&gt;

&lt;h2&gt;
  
  
  A feature that changed after use
&lt;/h2&gt;

&lt;p&gt;0.20.0 added a limit on &lt;em&gt;transfers&lt;/em&gt; running at once. Using it, it was the wrong unit: one transfer of 500 files and one of a single file counted the same. 0.24.0 changed it to count &lt;em&gt;files&lt;/em&gt;, oldest transfer first, with &lt;strong&gt;Start now&lt;/strong&gt; to jump the queue. The first version wasn't wrong in the code. It was wrong for the person using it, and only using it showed that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two-factor logins
&lt;/h2&gt;

&lt;p&gt;The newest release (0.26.0) logs in to servers that want a key or password and then a one-time code. I tested it on a VM set up with Google Authenticator, and the first finding wasn't a bug in ShuttleSCP: even with my key set up, the server still asked for my password. Its PAM settings put the Unix password in front of the code, so I was being asked for a key, a password &lt;em&gt;and&lt;/em&gt; a code.&lt;/p&gt;

&lt;p&gt;The design question was mine to answer. ShuttleSCP opens a second connection for transfers, and with two-factor each connection needs a fresh code. Two codes per session would be annoying. So on these servers, transfers now run on a second channel of the same SSH connection: one code per session. A dropped connection asks once more, and one login serves both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Six languages, labelled honestly
&lt;/h2&gt;

&lt;p&gt;The interface is in English, French, Spanish, German, Brazilian Portuguese and Simplified Chinese. I only speak English, so the translations were made with AI, and the app says so next to each language name until a native speaker reviews it. A test checks that every translation has the same messages and placeholders as the English.&lt;/p&gt;

&lt;h2&gt;
  
  
  A user guide, with clips the app recorded itself
&lt;/h2&gt;

&lt;p&gt;0.25.0 added a user guide: Help › User Guide opens it offline in your browser, and it's &lt;a href="https://shuttlescp.dsalvado.ca/help/" rel="noopener noreferrer"&gt;online too&lt;/a&gt;. The clip above is from it.&lt;/p&gt;

&lt;p&gt;The clips had to be anonymous: no real hosts, users or paths. Claude didn't screen-record. It wrote a debug-only recorder inside the app: a drawn pointer drives the real interface and picks the app's own Copy Here menu, in a made-up home folder, against throwaway servers with &lt;code&gt;example.com&lt;/code&gt; names, behind a small relay that slows copies down enough to watch. GTK renders each frame, and ImageMagick builds the GIF. It took several rounds: menus didn't appear in the frames, the desktop took the focus away, and the renderer sometimes returned empty frames. Re-recording the clips is now one command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guardrails, and where they failed
&lt;/h2&gt;

&lt;p&gt;The engineering around the app grew too: dependency checks against the RustSec advisory database on every change, weekly Dependabot updates, and secret scanning with gitleaks over the whole history.&lt;/p&gt;

&lt;p&gt;The most useful lesson came from a failure. Claude's merge script once merged a pull request &lt;strong&gt;before CI had finished&lt;/strong&gt;. The command it used to wait returned early, and a shell alias hid the exit code. Nothing broke, but it could have. The script now polls until no check is pending and merges only if every one passed. An assistant that is fast at writing code needs guardrails as strict as a new teammate's, and probably stricter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;ShuttleSCP is still a public beta, and I'm still learning Rust by reading what each change does. Next is more testing on real servers, and native-speaker reviews of the translations. If you try it, I'd like to hear what breaks, good or bad.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download: [shuttlescp.dsalvado.ca](&lt;a href="https://shuttlescp.dsalvado.ca/" rel="noopener noreferrer"&gt;https://shuttlescp.dsalvado.ca/&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;Code (GPL-3.0):&lt;a href="https://github.com/dsalvado/shuttlescp" rel="noopener noreferrer"&gt;github.com/dsalvado/shuttlescp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>opensource</category>
      <category>ai</category>
      <category>showdev</category>
    </item>
    <item>
      <title>What I learned building a real app with Claude Code</title>
      <dc:creator>David</dc:creator>
      <pubDate>Thu, 22 Oct 2026 17:24:45 +0000</pubDate>
      <link>https://dev.to/dsalvado/what-i-learned-building-a-real-app-with-claude-code-1af</link>
      <guid>https://dev.to/dsalvado/what-i-learned-building-a-real-app-with-claude-code-1af</guid>
      <description>&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;I recently finished The Complete Claude Code &amp;amp; Claude Cowork Masterclass. A course shows you what Claude and Claude Code can do. It doesn't show you what it's like to lean on that tool for a real project, with real bugs and real releases. I wanted to find out.&lt;/p&gt;

&lt;p&gt;I had a real problem to use. When I moved my laptop from Windows to Linux, the thing I missed most was WinSCP: my files on the left, the server's on the right, drag a file across, done. There are good file-transfer tools on Linux, but none felt like that to me.&lt;/p&gt;

&lt;p&gt;So that became the project. The result is &lt;a href="https://shuttlescp.dsalvado.ca" rel="noopener noreferrer"&gt;ShuttleSCP&lt;/a&gt;, a free, open-source SFTP, SCP and FTP/FTPS client for Linux, macOS and Windows, written in Rust with GTK 4. It's a public beta at version &lt;code&gt;0.13.0&lt;/code&gt;. This is what I learned getting it there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwimi0jj9v8exemv9ejm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwimi0jj9v8exemv9ejm6.png" alt="ShuttleSCP resuming an upload of three files: local files on the left, the server's on the right, each transfer with its own pause and stop buttons" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How we split the work
&lt;/h2&gt;

&lt;p&gt;The short version: I decided and checked, Claude wrote the code.&lt;/p&gt;

&lt;p&gt;My background is databases and IT infrastructure, not Rust. So I worked the way I would with a capable contractor. I described what I wanted in plain words, it built it, and I tried it. A typical request looked like this one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we add drag and drop? Files within a pane can be dropped into a folder. If dragging from source to target, a menu should come up asking if it's a copy or a move.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A while later there was a branch to test. I used it, said what felt wrong, and it went round again until it was right.&lt;/p&gt;

&lt;p&gt;I also set the ground rules, and they mattered more than I expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every feature goes on its own branch, and nothing merges until I've tried it.&lt;/li&gt;
&lt;li&gt;Explain each step as you go. I wanted to learn the engineering, not just collect an app.&lt;/li&gt;
&lt;li&gt;Never handle my passwords or keys. When something needed a secret, it gave me a script that asked me for it directly.&lt;/li&gt;
&lt;li&gt;Be honest that an AI built this, in the README and on the web page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't read every line of Rust. I can't judge Rust idioms yet. What I did review was what each change did and why, and whether it behaved that way when I used it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What worked
&lt;/h2&gt;

&lt;p&gt;The speed is real. ShuttleSCP is now about 22,000 lines of Rust with 149 automated tests. It runs on Linux, macOS and Windows, and has had eight public beta releases. Alone, I'd still be reading the GTK documentation.&lt;/p&gt;

&lt;p&gt;The bigger surprise was the engineering around the code. These are the parts a solo hobby project usually skips, and they got done properly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD.&lt;/strong&gt; Every pull request is linted and tested on GitHub Actions. Pushing one release tag builds, checks and publishes the Linux AppImage, the macOS disk image and the Windows installer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe self-updates.&lt;/strong&gt; The app checks a release manifest signed with an Ed25519 key, verifies the download's SHA-256, and swaps the file in one step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets in the right place.&lt;/strong&gt; Saved passwords go to GNOME Keyring, the macOS Keychain or the Windows Credential Manager, never a plain file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release hygiene.&lt;/strong&gt; A changelog, release notes and a security policy, from the first release.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also checked its own work in ways I wouldn't have thought of. To review the look of every dialog, it built a debug mode that opens each window, saves a screenshot and quits. When I said the dialogs looked like old GNOME ones, it could compare before and after without me clicking through the app.&lt;/p&gt;

&lt;p&gt;And I learned a lot. I asked it to teach as it went, and it did: why a release is tied to a &lt;code&gt;git tag&lt;/code&gt;, what signing actually protects against, why you never reuse a version number.&lt;/p&gt;

&lt;h2&gt;
  
  
  What didn't
&lt;/h2&gt;

&lt;p&gt;The failures were the most useful part, so here they are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bugs only a person finds
&lt;/h3&gt;

&lt;p&gt;The tests passed and the screenshots looked fine, but using the app told a different story:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first release built by GitHub Actions was missing GTK's add-ons. Icons didn't load and drawing fell back to software. It worked on my laptop because my laptop had them installed.&lt;/li&gt;
&lt;li&gt;In the next release, choosing a theme did nothing, and odd colours showed under the menus. The packaging tool was quietly forcing the default theme.&lt;/li&gt;
&lt;li&gt;My installed app started reporting itself as a "debug" build. Running a development copy had rewritten my desktop's launcher entry to point at itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each was fixed quickly once I described it, and the first two now have automatic checks so they can't come back. But I had to notice them first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version numbers
&lt;/h3&gt;

&lt;p&gt;I had already tagged and published &lt;code&gt;0.9.2&lt;/code&gt; when more work was added under that same number. It had to ship as &lt;code&gt;0.9.3&lt;/code&gt;. A published version can't be reused, because installed copies may already have it. The lesson: check what's actually released before calling something "part of" a version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trusting the status line
&lt;/h3&gt;

&lt;p&gt;At one point Claude told me it was waiting for a CI job to finish. I looked at GitHub Actions and nothing was running. The job had finished successfully, but GitHub never cleared its "in progress" label, and the AI was watching the label instead of the result. It was an honest mistake, and it was mine to catch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned about the work
&lt;/h2&gt;

&lt;p&gt;Writing code turned out to be the smallest part of building software. The rest was still mine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deciding.&lt;/strong&gt; What the app should do, what it should feel like, and what comes next. The AI offers options well, but someone has to pick.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing like a user.&lt;/strong&gt; Every real bug above was found by using the app, not by the test suite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Noticing.&lt;/strong&gt; A wrong label, a stale status, a version that doesn't add up. Twenty years of production support helped more than any Rust knowledge would have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saying no.&lt;/strong&gt; Some suggestions were good and still not for now. Keeping the scope small is what got releases out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think this way of working suits people who know a domain well and can tell when something is off, even if they don't know the language. It doesn't remove the need for judgement. It moves almost all of the work there.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;ShuttleSCP stays in public beta while people try it. Next on my list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make the Linux AppImage run on older systems such as Ubuntu 22.04 and Debian 12. Today it needs a 2024-or-later distribution.&lt;/li&gt;
&lt;li&gt;Keep fixing what testers find, one small release at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you use SFTP or FTP, I'd value your feedback, good or bad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Downloads: &lt;a href="https://shuttlescp.dsalvado.ca" rel="noopener noreferrer"&gt;shuttlescp.dsalvado.ca&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code and issues: &lt;a href="https://github.com/dsalvado/shuttlescp" rel="noopener noreferrer"&gt;github.com/dsalvado/shuttlescp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dsalvado" rel="noopener noreferrer"&gt;
        dsalvado
      &lt;/a&gt; / &lt;a href="https://github.com/dsalvado/shuttlescp" rel="noopener noreferrer"&gt;
        shuttlescp
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A graphical SFTP, SCP and FTP/FTPS client for Linux, macOS and Windows, inspired by WinSCP. Two panes, drag and drop, resumable transfers. Rust and GTK 4.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;ShuttleSCP&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/dsalvado/shuttlescp/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/dsalvado/shuttlescp/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/dsalvado/shuttlescp/releases/latest" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1a3e4e90d8ad9f972d282446df10413e47b351fc1b2cb82b05d70b222271f775/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6473616c7661646f2f73687574746c657363703f6c6162656c3d72656c65617365" alt="Latest release"&gt;&lt;/a&gt;
&lt;a href="https://github.com/dsalvado/shuttlescp/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/18433f64db6e6e501dc30458550734643cd3dc6223fef15cec5ea3e15ee5d274/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e63652d47504c2d2d332e302d2d6f722d2d6c617465722d626c7565" alt="Licence: GPL v3 or later"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A graphical SFTP and FTP client for Linux, macOS and Windows, inspired by WinSCP: your computer's
files on the left, the server's on the right, and copying between them is a drag, a
right-click or a key press away.&lt;/p&gt;
&lt;p&gt;Written in Rust with &lt;a href="https://relm4.org" rel="nofollow noopener noreferrer"&gt;relm4&lt;/a&gt; and GTK 4.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/dsalvado/shuttlescp/docs/screenshot.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fdsalvado%2Fshuttlescp%2FHEAD%2Fdocs%2Fscreenshot.png" alt="ShuttleSCP resuming an upload of three files, with pause and stop buttons for each"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Status: public beta.&lt;/strong&gt; It is used day to day on Linux and macOS, and the Windows
version is new; feedback is very welcome: please
&lt;a href="https://github.com/dsalvado/shuttlescp/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt;
See the &lt;a href="https://github.com/dsalvado/shuttlescp/CHANGELOG.md" rel="noopener noreferrer"&gt;changelog&lt;/a&gt; for what each release brought.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Connections&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SFTP and SCP over SSH, and FTP with plain, explicit or implicit TLS (FTPS), in
passive or active mode.&lt;/li&gt;
&lt;li&gt;SSH login with a password, a private key file (OpenSSH or PuTTY &lt;code&gt;.ppk&lt;/code&gt;, with its
passphrase if protected) or the keys of an SSH agent (the desktop's; on Windows
Windows' OpenSSH agent or PuTTY's Pageant).&lt;/li&gt;
&lt;li&gt;Saved sites, with passwords kept in the desktop keyring…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dsalvado/shuttlescp" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The code is GPL-3.0. If you read Rust, a critical look at it is as welcome as one at the app.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>rust</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
