Arthur-Ficial/apfel
57.2
Adequate · 30 September 2026
13.9k
lines of production code
Swift
primary language
2
measurements over time
What this system is
Apfel is a command-line interface and library for interacting with on-device large language models, specifically optimized for Apple Intelligence. It provides a modular CLI that operates as a Unix tool, an interactive chat client, and an HTTP server, supporting structured JSON output and token budgeting. The system includes a core library for context management and error handling, along with Model Context Protocol (MCP) servers for tool execution and a suite of shell scripts for common developer tasks.
Features
Add apfel(1) man page documenting CLI modes and options
Added the apfel(1) manual page, which documents the command-line interface's three modes (Unix tool, interactive chat, HTTP server) and key options including --schema for structured JSON output, --messages for one-shot multi-turn conversations, --code for code-only responses, and --count-tokens for token budgeting.
man · high confidence
Added example scripts demonstrating ApfelCore usage
New Swift example files have been added to the Examples directory to demonstrate how to use the newly exposed ApfelCore library. These include ContextStrategies for configuring context windows, ErrorHandling for managing API errors, MCPProtocol for protocol requests, OpenAITypes for constructing chat completion requests, and ToolCalling for defining and handling tools.
Examples · high confidence
Initial release of apfel v1.12.0 with project documentation and configuration
This entry marks the initial release of the apfel project at version 1.12.0. It introduces the core project configuration files, including \.gitattributes\ for consistent text and binary file handling, \.spi.yml\ to configure the Swift Package Index builder for the \ApfelCore\ documentation target, and \.version\ to establish the version baseline. The release also includes \AGENTS.md\ pointing to \CLAUDE.md\, which serves as the central project instruction file, and a new \CHANGELOG.md\ to track future changes.
(repo-wide) · high confidence
Introduce ApfelCore library with core error handling, validation, and context management
The Sources/Core directory now contains the foundational ApfelCore library, introducing a structured error system (ApfelError) that classifies model failures into typed cases with specific HTTP status codes and OpenAI-compatible error codes. It adds a ChatRequestValidator to enforce strict input validation, rejecting unsupported parameters (like logprobs or stop sequences), unknown roles, and image content with clear 400/404 responses. Context management is improved via ContextWindow and ContextStrategy, distinguishing between assumed and measured context sizes to handle model warm-up states accurately. Additional utilities include CodeCropper for extracting fenced code blocks, BufferedLineReader for robust MCP subprocess I/O, and DemoInstaller for bundling CLI demos.
Sources/Core · high confidence
Introduce internal benchmarking suite and persistent chat history
Added a new \apfel benchmark\ command that runs performance tests on core operations (text extraction, context trimming, schema conversion, etc.) and outputs a JSON or plain-text report. Additionally, chat mode now supports opt-in persistent history via the \APFEL\_HISTFILE\ environment variable, saving and loading command history across sessions using libedit.
Sources · high confidence
New MCP Calculator server and HTTP test server
Added a new Model Context Protocol (MCP) calculator server in \mcp/calculator/\ that exposes seven math tools (add, subtract, multiply, divide, sqrt, power, round\_number) via stdio transport, allowing Apple's on-device LLM to perform precise calculations. The server includes logic to coerce string arguments to numbers and rejects non-numeric inputs as tool errors. Additionally, an HTTP-based test server (\mcp/http-test-server/\) was added to support integration testing over Streamable HTTP transport, along with round-trip test scripts to verify end-to-end tool calling.
mcp · high confidence
New release automation and distribution maintenance scripts
The project introduces a suite of new shell scripts to manage the release lifecycle and downstream distribution channels. \publish-release.sh\ handles local release qualification, including running integration tests, signing the binary with a Developer ID, and notarizing it before publishing to GitHub. \publish-nixpkgs-bump.sh\ and \nixpkgs-bump-cron.sh\ automate version updates for the Nix package manager, including a launchd agent (\com.arthurficial.apfel-nixpkgs-bump.plist\) for periodic checks and alerting on failures. Additional scripts support distribution health (\dist-watch.sh\), changelog enforcement (\check-changelog.sh\), and documentation generation (\generate-examples.sh\, \generate-demos.sh\).
scripts · high confidence
New shell-script demos for Apple Intelligence
The \demo/\ directory now includes a suite of shell scripts that use the \apfel\ CLI to leverage Apple Intelligence for common developer tasks. Users can generate shell commands (\cmd\), create complex pipe chains (\oneliner\), identify directory contents (\wtd\), explain code or errors (\explain\), get naming suggestions (\naming\), identify processes using ports (\port\), summarize git history (\gitsum\), and narrate system state with humor (\mac-narrator\). These scripts support options to copy output to the clipboard or execute commands with confirmation, and are designed to work within the on-device context window on macOS 26+.
demo · high confidence
Shell completion scripts for bash, zsh, and fish
The CLI now includes generated shell completion scripts for bash, zsh, and fish, enabling tab-completion for commands and flags. These scripts cover the full set of available options, including the new \--schema\, \--messages\, and \--code\ flags, as well as the \completions\ subcommand used to regenerate them.
completions · high confidence
Behavioural changes
Refactored CLI argument parsing into a testable, modular structure
The CLI argument parsing logic has been extracted from the main executable into a dedicated \ApfelCLI\ target, introducing a pure, testable \CLIArguments\ value type that separates parsing from side effects. This refactor centralizes error messaging via \CLIErrors\ templates, standardizes exit codes in \ExitCodes\, and introduces new capabilities including shell completions (\Completions.swift\), persistent chat history with secure file permissions (\ChatHistory.swift\), and improved color output handling (\ColorPolicy.swift\).
Sources/CLI · high confidence
Fixes
Fix server crash on semaphore timeout and add concurrency primitives
The server no longer crashes with a SIGABRT when an AsyncSemaphore wait times out; the timeout now throws a SemaphoreTimeoutError instead. This fix, along with new concurrency primitives (AsyncSemaphore, StreamCleanup, StreamTaskBox, TraceBuffer) moved into the Core/Concurrency module, ensures stable handling of concurrent operations and streaming cleanup.
Sources/Core/Concurrency · high confidence
Fix terminal state corruption on Ctrl-C during chat input
The chat input mechanism now correctly restores the terminal to its original cooked mode when the user presses Ctrl-C, preventing the terminal from remaining in a broken raw/no-echo state after the process exits. This is achieved by capturing terminal settings before line editing begins and installing a signal-safe handler that resets the TTY and exits with code 130, ensuring a clean shell prompt is returned to the user.
Sources/CReadline · high confidence
Refactor chat core into pure, testable modules for streaming, limits, and tool resolution
The chat core logic has been extracted into dedicated, pure Swift modules (BodyLimits, FinishReasonResolver, StreamOutcome, StreamRetryPolicy, ToolResolution) to improve reliability and testability. Key user-facing improvements include: streamed output is now printed exactly once even during network retries, preventing duplicate text; the system now handles closed output pipes gracefully (exiting with status 141 instead of crashing); and token counting for refusals is corrected to avoid double-counting. Additionally, the arbitrary 1024-token default for max\_tokens has been removed, allowing the model to utilize the full 4096-token context window, with overflow handled gracefully via finish\_reason: "length".
Sources/Core/Chat · high confidence
Test coverage
Added comprehensive test coverage for ApfelCore public API and error handling; Expanded integration test suite for CLI, MCP, and server behaviors.
Dependencies
Swift Package updated to tools version 6.3 with new library and dependency structure
The project's Package.swift has been upgraded to Swift tools version 6.3 and restructured to expose the \ApfelCore\ logic as a public library product, alongside the main \apfel\ executable. This change introduces dependencies on Hummingbird (v2.0.0+), the Swift DocC Plugin (v1.4.6+), and the \lesbar\ library (v0.3.0) for on-device file extraction, while adding a \CReadline\ system library target. The resolved dependency pins reflect these updates, notably setting Hummingbird to version 2.26.0 and the DocC Plugin to 1.5.0 in the main package, and establishing a new integration test fixture (\apfelcore-consumer\) to verify consumption of the newly exposed \ApfelCore\ library.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 68 → 57 (-11.3)
- Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 79 → 78 (-1.1)
- Architecture 100 → 91 (-9.2)
- Maturity 65 → 64 (-0.4)
- Readiness 65 → 47 (-18.2)
- Security 67 → 67 (+0.0)
- Performance 63 (new)
Resolved (9)
- Documentation: contradicts the code (docs/tool-calling-guide.md)
- Documentation: no architecture or design documentation (docs/install.md)
- Documentation: no architecture or design documentation (docs/release.md)
- Documentation: no usage examples (README.md)
- Hotspot: Sources/Core/SchemaParser.swift (Sources/Core/SchemaParser.swift)
- Hotspot: Sources/TokenCounter.swift (Sources/TokenCounter.swift)
- Members sharing a duplicated core (4 members, 50+ identical tokens) (Sources/Core/ToolCallHandler.swift)
- SchemaParser.normalizeUnion (cognitive 24) (Sources/Core/SchemaParser.swift)
- SchemaParser.normalizeUnion (cyclomatic 18) (Sources/Core/SchemaParser.swift)
New (73)
- CLI.swift.chat (cognitive 83) (Sources/CLI.swift)
- CLI.swift.chat (cyclomatic 40) (Sources/CLI.swift)
- CLI.swift.countTokens (cognitive 49) (Sources/CLI.swift)
- CLI.swift.countTokens (cyclomatic 32) (Sources/CLI.swift)
- CLI.swift.performUpdate (cognitive 19) (Sources/CLI.swift)
- CLI.swift.performUpdate (cyclomatic 19) (Sources/CLI.swift)
- Conflicting API Surface: The type has a computed property fits: Bool but also a method fits(total: Int, budget: Int): Bool. It is unclear if the method overrides or complements the property, or if the property is deprecated. This creates ambiguity for consumers on whether to check the property or call the method.
- Coverage not measured — Swift suite
- Duplicated block (11 lines × 3) (Sources/Core/OpenAIModels.swift)
- Duplicated block (11 lines × 3) (Sources/Handlers.swift)
- Duplicated block (11–16 lines × 2) (Sources/Handlers.swift)
- Duplicated block (12 lines × 2) (Sources/Core/OpenAIModels.swift)
- Duplicated block (12–15 lines × 2) (Sources/Handlers.swift)
- Duplicated block (13 lines × 3) (Sources/Handlers.swift)
- Duplicated block (13–14 lines × 2) (Sources/CLI.swift)
- Duplicated block (13–19 lines × 2) (Sources/Handlers.swift)
- Duplicated block (15 lines × 2) (Sources/Core/ApfelError.swift)
- Duplicated block (16 lines × 2) (mcp/calculator/server.py)
- Duplicated block (17 lines × 2) (Sources/Benchmark.swift)
- Duplicated block (17–18 lines × 2) (Sources/Core/OpenAIModels.swift)
- …and 53 more
Changes since last survey
- 15 commits — 8 feature/other, 7 fixes
By area
- (root) — 8 commits
- Tests/apfelTests — 4 commits
- Sources/Core — 1 commit
- docs/coreai-impact.md — 1 commit
- docs/integrations.md — 1 commit
Notable commits
- fix: fix(build): pin --build-system native for CLT-only environments (#194) (#499)
- fix: fix(cli): drop exported APFEL_* prompt defaults in input-ignoring modes instead of exiting 2 (#496) (#498)
- fix: fix(context): keep tool-call exchanges whole when trimming client-supplied history (#482) (#500)
- fix: fix(context): stop reporting the assumed window floor as a measurement (#491) (#494)
- fix: fix(mcp): price the auto-execute follow-up as it is built so #221 truncation leaves room for the pinned exchange (#482)
- fix: fix(server): enforce tool_choice and parallel_tool_calls at the response boundary (#480) (#489)
- fix: fix(server): honor max_completion_tokens from modern OpenAI clients (#478) (#488)
- change: docs(claude): sync version 1.11.1 and test counts (1208 unit, 533 integration)
- change: docs(claude): sync version 1.12.0 and test counts (1292 unit, 549 integration)
- change: docs(coreai-impact): drop stale 'all Beta' after macOS 27 GA (#196) (#490)
- change: docs(integrations): make the copy-paste token limits macOS-27-correct (#495)
- change: feat(schema): resolve local $ref/$defs, enforce numeric and array bounds, reject unrepresentable constraints (#479) (#501)
- change: release v1.11.0
- change: release v1.11.1
- change: release v1.12.0
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Arthur-Ficial/apfel was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 30 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 2b8afc100752a47b59a568d0205cbf45b4c94f05 — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-cb25ca4feafa.