Add Zen-C implementation of runtimedl with comprehensive documentation#3
Open
KevinGliewe wants to merge 37 commits intoruntimedl-toolfrom
Open
Add Zen-C implementation of runtimedl with comprehensive documentation#3KevinGliewe wants to merge 37 commits intoruntimedl-toolfrom
KevinGliewe wants to merge 37 commits intoruntimedl-toolfrom
Conversation
- Remove PackAsTool, NuGet packaging, and multi-targeting configuration - Add PublishSingleFile, SelfContained, PublishTrimmed, and StripSymbols - Enable compression and invariant globalization for smaller binaries - Target net8.0 only for broad compatibility - Add GitHub Actions workflow to build and release for all platforms: linux-x64, linux-arm64, linux-musl-x64, linux-musl-arm64, win-x64, win-x86, win-arm64, osx-x64, osx-arm64 - Workflow triggers on version tags (v*) and creates GitHub releases - Update README with platform table and download instructions https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
.NET 10 is the latest release; use it for smaller binaries and newer runtime improvements. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Add System.Text.Json source generator (RuntimeDBJsonContext) to avoid reflection-based serialization which is disabled by the trimmer - Change JSON model classes from private to internal for source generator access - Use source-generated JsonSerializerContext in Deserialize calls - Add TrimmerRootAssembly entries to preserve DragonFruit and System.CommandLine Verified: 16MB single-file stripped executable runs correctly. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Rewrite the .NET runtime downloader in Zen-C, compiled with cosmocc (Cosmopolitan libc) to produce a true cross-OS Actually Portable Executable (APE). Single 1.3MB binary runs on Linux, macOS, Windows, FreeBSD, OpenBSD, and NetBSD on both x86_64 and aarch64. Features: - Full CLI with --runtime-type, --platform, --architecture, --version-pattern, --include-prerelease, --output, --download - Auto-detects platform and architecture via uname() - Queries Microsoft's official releases-index.json - Semantic version range matching (>, >=, <, <=, =, ^, ~) - SHA-512 checksum verification - tar.gz extraction via zlib - Progress bar via curl Build: cd src/zc-runtimedl && make (requires zc-ape toolchain) GitHub Action: .github/workflows/build-ape.yml https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Add mbedTLS 3.6.5 for native HTTPS client (no more curl dependency) - Implement HTTP CONNECT proxy support (HTTPS_PROXY env var) - Replace hand-rolled SHA-512 with mbedtls_sha512() - Add native zip extraction via zlib inflate (no more unzip dependency) - Custom entropy source for cosmopolitan libc compatibility - Force TLS 1.2 to avoid PSA crypto init issues with cosmocc - Binary is now fully self-contained: no curl, unzip, or other host tools needed https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Remove cJSON.c, cJSON.h, and vendor/mbedtls/ from the repo - Makefile now downloads mbedTLS 3.6.5 and cJSON 1.7.18 into extern/ - Add .gitignore for extern/, out/, capture-cc.sh - `make distclean` removes downloaded deps https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Split the 1284-line monolith into 7 focused modules: - semver.zc: SemVer parsing and comparison - platform.zc: OS/arch detection and .NET RID mapping - http.zc: HTTPS client wrapping mbedTLS (with proxy support) - archive.zc: tar.gz and zip extraction via zlib - runtimedb.zc: Release metadata query using Zen-C std/json.zc - runtimedl.zc: CLI entry point and orchestration - test_semver.zc: 27 unit tests for semver logic Key changes: - Replaced cJSON dependency with Zen-C's std/json.zc library - Upgraded zc.com compiler from v0.1.0 to v0.4.3 - Added Zen-C std library as build dependency (auto-downloaded) - Added test target to Makefile (`make test`) - cJSON is no longer downloaded or compiled https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
…o 20
- semver.zc: SemVer struct uses String prerelease, parse/cmp/satisfies
use String::split/find/starts_with/eq_str instead of C strcmp/sscanf
- test_semver.zc: Replace custom C test harness with native `test` keyword
and built-in assert() — no main(), no raw block counters
- platform.zc: Replace strcmp() with String::eq_str() in platform_to_rid,
arch_to_rid, type_to_json_key, type_to_file_prefix
- runtimedb.zc: Replace 12 `raw { continue; }` with plain continue,
use String::starts_with/ends_with for filename matching,
use parse_semver() instead of raw _sv_parse()
https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
9 modular part files covering language basics, control flow, structs/enums/traits, memory/C interop, collections (Vec/String/Map/Set/Stack/Queue/Slice), error handling (Option/Result/test blocks), I/O/filesystem/environment, concurrency/networking (Thread/Mutex/TCP/HTTP/WebSocket), and misc modules (JSON/Regex/Time/Math/SIMD/CUDA/Crypto). Combined into zenc-cheatsheet.md (2099 lines). Sources: awesome-zenc examples, zenc test suite (130+ files), local zenc-std source. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Replace raw snprintf calls in build_rid with format_into from io.zc - Add import for extern/zenc-std/io.zc - Create test_platform.zc with 11 tests covering platform_to_rid, arch_to_rid, build_rid, type_to_json_key, and type_to_file_prefix - Update Makefile with test_platform.com build target https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- semver.zc: Replace atoi raw block with pure Zen-C digit parser, remove backward-compat _sv_parse C wrapper - platform.zc: Replace raw snprintf in build_rid with Zen-C format_into - test_semver.zc: Remove _sv_parse test, add 5 new pure Zen-C tests (zero patch, major-only, prerelease ordering, tilde, caret wrong major) - 20 tests pass across semver + platform modules https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Rename p to _p in _str_to_int to suppress Zen-C unused variable warning - Remove test_http.com target from Makefile (http.zc is fully raw C, tests failed) https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- runtimedb.zc: Replace fprintf with println, remove C wrapper function, use Zen-C conditionals instead of raw ternary - runtimedl.zc: Restructure main() to minimize raw block scope, use Zen-C print/println where possible https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Extract parse_octal, read_u16_le, read_u32_le, and mkdirp from raw C blocks into proper Zen-C functions with forward declarations. Add test_archive.zc with 9 unit tests covering octal parsing, little-endian reads, and directory creation. Update Makefile with test_archive target. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Runs `make test` and `make all` on every push/PR that touches src/zc-runtimedl/. Covers semver, platform, and archive test suites. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
…nto Zen-C functions with tests Extract three testable Zen-C functions from the monolithic raw C block: - parse_url: URL parsing using String methods (starts_with, find, substring) - base64_encode: Base64 encoding with correct padding via have_b/have_c flags - parse_proxy_env: Proxy environment variable parsing with scheme stripping Add test_http.zc with 18 unit tests covering URL parsing (6 tests), base64 encoding (6 tests), and proxy env parsing (5 tests). Update Makefile with test_http.com target linking mbedTLS. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Extract 6 functions from raw C to Zen-C in runtimedl_helpers.zc: - strtolower, normalize_runtime_type, is_false_str - get_filename_from_url, detect_archive_format, print_usage Convert checksum verification and archive detection to use Zen-C. Add 21 tests in test_runtimedl.zc covering all extracted functions. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Make read_u16_le/read_u32_le pure Zen-C (no raw blocks) - Rewrite mkdirp using String operations instead of raw C pointer manipulation - Extract 6 new Zen-C functions: is_all_zero, should_be_executable, is_tar_directory, is_tar_file, ensure_parent_dir, build_tar_fullpath - Add set_file_permissions to consolidate chmod logic - Refactor extract_tar_gz/extract_zip to call Zen-C helpers - Expand test suite from 9 to 24 tests covering all helpers https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- semver.zc: remove raw unsigned char cast in _str_to_int (pure Zen-C) - archive.zc: remove raw unsigned char cast in parse_octal (pure Zen-C) - runtimedl_helpers.zc: rewrite strtolower as pure Zen-C loop, replace strcpy raw block with Zen-C byte copy in normalize_runtime_type - http.zc: replace 3 raw unsigned char casts in base64_encode with (u8) casts All remaining raw C blocks are now genuinely unconvertible: struct typedefs with fixed-size arrays, mbedTLS/zlib APIs, POSIX syscalls, getopt_long, void function early return. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
get_filename_from_url returned c_str() from a local String that was destroyed on function return, causing garbled filenames in the download path. Fixed by copying result into a static buffer. Added regression test that forces allocations between the function call and result use to reliably trigger the use-after-free. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Downloads .NET 8 runtime on all supported CI platforms (linux/x64, macos/x64, macos/arm64, windows/x64), then runs `dotnet --info` to verify the correct platform RID was chosen and files aren't corrupt. Build once on ubuntu (APE is cross-platform), test everywhere via matrix strategy with fail-fast disabled. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Runtime-only dotnet installs don't show RID in `dotnet --info`, only Architecture — switch to checking that instead - Add quarantine attribute removal on macOS for APE binary - Switch Windows step to PowerShell for more reliable APE execution - Add `dotnet --list-runtimes` check to verify runtime version - Verify runtime name matches "Microsoft.NETCore.App 8.0" https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
The zc-ape v0.0.2 bootstrap bundles an older zc.com that doesn't
support `test "name" { }` blocks. After bootstrapping cosmocc via
zc-ape, download zc.com v0.4.3 from zenc-lang/zenc which adds
test block support, selective test execution, and other fixes.
https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- Switch test targets from `zc build` to `zc run` since test blocks
(`test "name" { }`) are only compiled with the run subcommand
- Remove `2>/dev/null` so transpilation errors are visible in CI
- Pin zenc-std library to v0.4.3 tag to match the compiler version
(was using `main` branch which may be incompatible)
https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Root cause: zc.com v0.4.3 emits duplicate _zen_panic definitions when multiple modules are compiled together, causing C compilation to fail with "redefinition of '_zen_panic'". Fix: Add dedup-transpiled.sh post-processing step that removes duplicate function definitions from the transpiled C output before passing it to cosmocc. Also remove 2>/dev/null from main build so errors are visible. Verified locally: all 5 test targets and main runtimedl.com build and pass successfully. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
The root cause was capture-cc.sh running cosmocc (which hit the duplicate _zen_panic bug), causing zc.com to report "C compilation failed". Now capture-cc.sh only captures the transpiled .c file and exits 0, so zc.com succeeds and || true is no longer needed. Verified locally: clean build of all targets and tests pass. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- capture-cc.sh now uses absolute path for out/transpiled.c (fixes CI where zc.com may call CC from a different working directory) - Creates a dummy ELF output file so zc.com sees a successful build (zc.com checks if the -o output exists after calling CC) - Removed || true since zc.com now exits 0 Verified locally: clean make test and make all pass. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Add stderr debug logging to capture-cc.sh to diagnose CI failures. Also make the output file path absolute to handle CWD differences between local and CI environments. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
zc.com suppresses stderr from the CC subprocess, making debug echo statements invisible in CI logs. Switch to writing debug info to out/capture-cc-debug.log and display it on zc.com build failure. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
The capture-cc.sh wrapper was never invoked by zc.com in CI (confirmed by file-based debug logging). Replace the entire capture-cc.sh approach with zc.com's built-in `transpile` command which outputs C directly without needing a CC at all. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
The ape-x86_64.elf downloaded from artifacts loses its execute permission. When copied to /usr/bin/ape without +x, the kernel's binfmt_misc handler fails with "Permission denied" when trying to use it as the interpreter for APE binaries. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
macos-13 is no longer supported by GitHub Actions. Since there are no x64 macOS runners available, remove the macOS x64 test entry. The macOS arm64 test (macos-latest) still provides macOS coverage. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
- build-and-release.yml: Add push/PR triggers on src/runtimedl/**, add integration-test job that builds native binaries on Linux/macOS/ Windows, downloads a .NET 8.0 runtime, and verifies architecture. Release now depends on tests passing. - test-zc.yml: Add tag trigger (v*) and release job so Zen-C APE binary is released after tests and integration tests pass. Also fix APE loader permissions in test job. - Remove build-ape.yml which is now redundant with test-zc.yml. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
SharpZipLib's tar extraction (used by runtimedl C#) and the Zen-C tar extraction both don't preserve Unix execute permissions. Add a chmod +x step for the dotnet binary before verification on Unix. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
Package runtimedl.com and ape-x86_64.elf into a runtimedl-ape.tar.gz archive, matching the dotnet workflow's packaging convention. The integration test extracts from the archive, and the release job uploads the archive to GitHub releases. https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a complete rewrite of the runtimedl tool in Zen-C, a modern systems programming language that compiles to C. The new implementation targets Actually Portable Executables (APE) via cosmocc, enabling a single binary to run across Linux, macOS, Windows, FreeBSD, OpenBSD, and NetBSD.
Key Changes
New Zen-C Implementation
Comprehensive Documentation
zenc-cheatsheet.md: 2100+ line reference covering:
Modular documentation split into 9 focused guides:
Build Infrastructure
Testing
Project Configuration
Notable Implementation Details
https://claude.ai/code/session_01FGvdwXkvaAHw3xkTU5YZh9