The elements I’ve been saying lately actually hinted at what I’m engaged on in the meanwhile. A bash playground that lets me train SwiftBash, SwiftScript and SwiftPorts all tied collectively through ShellKit. There was one half that was on my personal repo: the agentic harness and pure Swift wrappers for OpenAI APIs. I stored pondering that if I wished to finally make my Bash Playground public, then I wanted to even have this closing half on GitHub as effectively.
My mission assertion for iBash is to have a common app that offers me a digital shell with a workspace in a file bundle that may do a lot of the scripting and enhancing work one would wish to do cellular plus a coding agent that lives and works in these sandboxes.
This Coder agent is modelled after PI, with the very same instruments that PI has. Plus two additions: The most recent OpenAI fashions are skilled on enhancing information with the apply_patch device, so I’m utilizing this as a substitute of PI’s search-replace. Additionally there’s a sub_agent device as a result of this manner Coder can do a little bit of exploring with its personal context window and might then come again with its findings to the principle once more with out bloating the principle context window.
The entire thing has gotten to the extent the place I can ask the agent to go searching on this bash sandbox and attempt to discover issues that don’t work as they need to. Then it might probably doc the issues it finds in native markdown information and in addition use the gh device (from SwiftPorts) to open new GitHub points with the steps to breed the difficulty.

The I can have Claude iron out these wrinkles one after the other. Take for instance challenge 46 from the screenshot above. My claude made PR 54 for that, after asking me through the Claude cellular app an structure query. It resolved a assessment remark from codex, babysat the construct till all platforms have been inexperienced. On the finish I may simply merge the PR and delete the department.
My hope is that if I maintain doing this loop lengthy sufficient that the floor of the bash instructions in SwiftBash will grow to be indistinguishable from actual bash. An agentic self-improvement loop.
Let’s go over all my OSS initiatives and see what’s new.
SwiftText: I’ve been writing a markdown parser for no cause
swifttext had a hand-rolled markdown parser that I’d been patching for over a 12 months. Each time one thing rendered weirdly in a PDF, I’d open MarkdownLexer.swift, discover the sting case, add one other regex, ship it.
Then final week I went swift-markdown — Apple’s personal markdown library, sitting at github.com/swiftlang/swift-markdown, utilized by DocC, completely maintained, with the complete CommonMark + GFM AST floor I’d been attempting to approximate by hand. I’d been ignoring it for years as a result of I assumed it was DocC-internal.
It’s not DocC-internal. It’s a Swift bundle. You’ll be able to simply use it. I admit that I’ve a extreme case of “not invented right here” syndrome, however for Apple I make an exception…
SwiftText 1.1.9 replaces my parser with swift-markdown. Picture alt-text now traverses nested inline content material accurately (which my parser had been silently flattening), and the PDF renderer now not forces a web page break earlier than each H1/H2 — so lengthy technical paperwork cease losing paper between each part.
There was one factor although that Apple’s markdown parser continues to be missing: it doesn’t deal with footnotes. However I’m able to work round this with a pre- and post-processing step.
SwiftMCP: the */ bug, and a solution to cut up servers
The bug-of-the-week award goes to a macro-expansion regression in SwiftMCP 1.4.5-original. I had generated documentation feedback as /** ... */ blocks. The issue: if anybody (together with me) wrote a docstring containing */ — mostly "**/*" in a glob instance — the doc block closed early and the remaining spilled into uncooked Swift supply, producing cascades of “unterminated string literal” errors with no apparent trigger. Switching to /// line feedback fastened it. The v1.4.5 tag was re-pointed on the repair; 1.4.6 widens the swift-syntax vary so SwiftMCP coexists peacefully with SwiftScript.
Extra attention-grabbing structurally: @MCPExtension. Now you can annotate extension YourServer in any file and even every other goal with @MCPExtension, and the instruments/sources/prompts outlined there get aggregated into the first @MCPServer. The generated Shopper floor is prolonged in lock-step, so callers see one shopper no matter which goal a given device lives in. This was the architectural piece I wanted for giant MCP servers to cease ballooning into single-file monoliths.
SwiftMail: the Proton Mail Bridge incident
Somebody tried to make use of SwiftMail with Proton Mail Bridge, which runs on a non-standard native port with out conventional STARTTLS semantics, and found that my “infer TLS from the port quantity” heuristic guessed flawed. Fixing it correctly meant exposing an express MailTransportSecurity enum — .automated (the previous guesser), .implicitTLS, .requiredSTARTTLS, .plaintext — so callers can override the inference.
The larger repair was much less glamorous however most likely impacts extra individuals: envelope-date parsing. I’d been strict about RFC 5322 dates, which sounded cheap till I attempted to index a 15-year-old mailbox and watched 1000’s of “couldn’t parse date” warnings scroll previous. Actual mail within the wild makes use of lowercase month names, omits time zones, embeds (UTC) parentheticals, and nonetheless makes use of out of date US zone abbreviations like PST. SwiftMail 1.6.4 accepts all of these and stops complaining.
There’s additionally an MIME repair that I’m barely embarrassed by: HTML emails with attachments have been lacking a closing boundary, so strict parsers have been treating the attachment as nonetheless nested contained in the HTML half. It rendered effective in Gmail and Apple Mail, however extra pedantic shoppers would mangle it. Now fastened.Put up: the downstream beneficiary
Put up is the IMAP/SMTP daemon and CLI that’s principally my testbed for every thing above. The v1.6.6 launch shipped this week and is, by my very own admission, probably the most boring launch notes I’ve ever written: not a single line of Put up’s personal code modified. It’s pure dependency uptake.
However that uptake issues, as a result of every thing from SwiftMail’s higher date parsing and MIME repair, SwiftMCP’s base64 binary correction, and SwiftText’s PDF page-break repair lands in put up and postd robotically. put up ship now produces strictly-correct MIME for HTML-plus-attachment messages, put up fetch stops complaining about 15-year-old date strings, put up pdf now not wastes paper earlier than each heading, and the MCP daemon round-trips attachment bytes accurately. The purpose of the layered stack is that releases like this are allowed to be boring.
SwiftPorts: bringing the terminal to life
If the SwiftText story is about deleting a parser, the SwiftPorts story is about including one again in a spot it truly belonged.
GlamKit is the headline. It’s a pure-Swift port of Allure’s Glamour — markdown → ANSI rendering. The gh repo view and glab repo view instructions now render the README proper in your terminal, with syntax-highlighted code blocks, actual GFM tables drawn with box-drawing characters, and correctly themed headings. It makes use of swift-markdown for the parse step (see above), so the AST dealing with is stable; I solely needed to write the ANSI styling layer on high.
After I added the device backing for Coder I discovered that PI is utilizing rg aka ripgrep fd for discover – so naturally I wanted so as to add these as ports to the gathering. And I discovered the grep subcommand was lacking from the git port as effectively.
- RipgrepKit — a pure-Swift port of BurntSushi/ripgrep. It now reads world gitignore, walks mum or dad directories for repository ignore inheritance, and matches upstream
rgbehaviour shut sufficient that I’ve been utilizing it as my every dayrg. - FdKit — pure-Swift port of sharkdp/fd with LS_COLORS help, match highlighting, the works.
- git grep — lastly added as a subcommand within the swiftgit port.
The pace at which we’re including Swift ports of well-known utilities to SwiftPorts is making my head spin. A lot of the work additionally went into sandboxing help. The place libraries and utilities use FileManager.default for accessing information we’ve got no solution to block file entry. So the one means is to sprinkle in numerous permission checks earlier than handing over a path.
SwiftBash: 100 small issues
SwiftBash bought probably the most commits of any repo this fortnight, however only a few of them are headline-worthy individually. It’s the thousand-paper-cuts section the place each script somebody runs surfaces yet one more factor the interpreter dealt with subtly flawed.
The sample that stunned me most: [ -t N ] (the test-if-fd-is-a-tty examine that each colour-detection idiom depends on) and $'...' (ANSI-C quoting). I’d shipped with out them as a result of no script in my very own assortment used them, however each well-written CLI makes use of them to resolve whether or not to emit color. As soon as these landed, half my very own ported instruments all of the sudden began auto-detecting terminals accurately.
Different notable bits:
- Bun’s JavaScriptCore on Linux, Home windows, and Android. The JSC put up talked about Apple platforms; SwiftBash 1.5-line picks up Bun’s prebuilt JavaScriptCore in all places else, so
swift-jsnow boots a full JS runtime on platforms the place Apple doesn’t ship JSC in any respect. much lessandextraas in-process pager builtins. No exterior course of, paging respects the sandbox.- Mode flags
-e / -u / -x / -v— each “set -euo pipefail” script you’ve ever seen now truly behaves as meant. compgenplus public completion sources, so embedders can hook tab-completion into their very own UIs.${var:offset:size}with full nesting — the offset can itself be a substitution expression. Bash has been doing this for many years; my parser was bailing on the primary nested brace.
ShellKit: the contract beneath
Most readers gained’t contact ShellKit immediately, but it surely’s the explanation the opposite repos compose with out round dependencies.
ShellKit is the abstraction layer for “what’s the shell setting, actually?” — stdin/stdout/stderr sinks, setting, sandbox coverage, community coverage, the method desk, and the binary catalog. The default is host-system passthrough; embedders override per-task. Each CLI device I publish reaches host sources solely by Shell.present, by no means FileManager or Basis.Course of immediately. That’s what makes the identical rg / fd / much less / bash binary work the identical means whether or not you run it from an actual terminal, from inside SwiftBash, or from inside a sandboxed iOS app.
This fortnight ShellKit picked up the Shell.processLauncher subprocess primitive (so embedders can intercept course of launches with out monkey-patching), a cleaner Sandbox.Denial description that doesn’t leak absolute host paths into error messages, and a way more trustworthy BinCatalog that is aware of concerning the script interpreters, git/gh/glab, the compression household, and the platform-specific binaries. CI now runs on macOS, iOS, Linux, Home windows, and Android.
I additionally wished to have correct help for compgen – the bash means of tab completion in addition to genuine dealing with of $PATH. All instructions now present in one of many customary bin folders or as builtin.
SwiftScript: a Swift interpreter that respects your sandbox
SwiftScript runs .swift information with out swiftc. The latest work routes each Basis IO door — file reads, community calls, course of launch, identification lookups, exit — by Shell.present. Mixed with SubprocessModule bridging import Subprocess to Shell.processLauncher, now you can embed a Swift interpreter in your app and have the script actually unable to flee your sandbox, even when it calls Subprocess.run.
It’s the identical thought as JavaScriptCore from final put up, utilized to Swift itself. Probably the most satisfying half: a third-party .swift file can import Basis, write probably the most innocent-looking strive Information(contentsOf:), and nonetheless hit your sandbox boundary as a substitute of the consumer’s house listing.
SwiftAgents: opening the field
That is the massive one for me. SwiftAgents is the LLM-and-agents SDK that’s been sitting inside a personal repo known as AgentCorp for the higher a part of two years, quietly doing the precise work behind virtually every thing else I ship. It’s now open on GitHub.
The form of it: pure, lovely Swift wrappers across the LLM APIs as they really evolve. I began writing it when OpenAI nonetheless solely had the Completions endpoint. Then I rewrote the floor for Assistants. Then for Responses. The present incarnation additionally covers Conversations, and the entire thing is structured as a Swift port of the OpenAI Brokers SDK — modelled after their abstractions, however expressed in idiomatic Swift, with robust typing, async/await, and the sort of API floor that looks like Basis slightly than a transpiled Python shim.
There are two pattern apps, one is Coder CLI – a fundamental coding agent for the terminal. The opposite is an actual time voice agent I’m tinkering with.
The realtime voice agent helps you to cellphone with a handy guide a rough and good voice agent that may edit information within the app’s paperwork folder through its built-in coding agent. It transcribes the dialog and it has the flexibility to ask OpenClaw through the chat completions API. This was the take a look at mattress for including realtime session help to SwiftAgents.
Subsequent Steps
Truthfully, I don’t know if the realtime agent even works at this level, the primary massive step was to get all of it onto GitHub. Subsequent I’ll must guarantee that it’s nonetheless working with the modified and unified dependencies. As soon as I’ve it working once more, I’ll make sure to present it off in a video.
Additionally iBash is rising in leaps and bounds and I’m trying ahead to providing you with a tour of it quickly. I’m hesitant to open supply it as a result of I’d wish to put it on the app retailer first. Additionally possibly do an open beta with Testflight. That could be enjoyable and assist me discover extra points.
After which there are some additions to the LLM APIs that I wish to do in my SDK. OpenAI lately added the potential of calling their APIs through internet sockets, so most likely that. Completely happy to listen to your ideas and concepts on any of the above!
Associated
Classes: Administrative

