CLAUDE.md — Zyquo Local
Project Identity
Zyquo Local is the on-device sibling of Zyquo Cloud: a legendary, native macOS AI chat client written in Swift + SwiftUI, built entirely without Xcode where possible (Swift Package Manager + command-line toolchain), that runs large language models 100% locally on Apple Silicon using MLX. No API keys, no network calls for inference, no data ever leaving the Mac.
The core promise: the user opens the app, browses Hugging Face directly inside the interface, downloads MLX models with one click, and chats with them — with the same legendary design language and polish as Zyquo Cloud. Zyquo Local must feel like the definitive local-LLM app for the Mac: faster, cleaner, and more beautiful than LM Studio or Ollama frontends.
Naming conventions (use these consistently everywhere):
- Display name / product name:
Zyquo Local - App bundle:
Zyquo Local.app - Bundle identifier:
com.zyquo.local - Executable / SPM target:
ZyquoLocal(no space) - Data folder:
~/Library/Application Support/ZyquoLocal/ - Models storage:
~/Library/Application Support/ZyquoLocal/Models/ - Repo module prefix in file headers:
Zyquo Local - Platform: Apple Silicon (arm64) ONLY. MLX requires Apple Silicon. At launch, detect Intel Macs and show a clear, polite unsupported-hardware screen.
📋 MANDATORY FILE HEADER — EVERY CODE FILE
Every single code file you write (all .swift files, plus Makefile, shell scripts, Package.swift, verification scripts — anything containing code) MUST begin with this header comment, adapted to the file's comment syntax:
//
// <FileName>.swift
// Zyquo Local
//
// Author: Simon-Pierre Boucher
// Mail: contact@spboucher.ai
//For shell scripts / Makefiles:
#
# <filename>
# Zyquo Local
#
# Author: Simon-Pierre Boucher
# Mail: contact@spboucher.ai
#No exceptions. If you ever create or refactor a file and the header is missing, add it. Before declaring the project done, run a sweep over the repository to verify every code file carries the header.
🧭 METHODOLOGY — WORK METHODICALLY, KEEP EVERYTHING COHERENT
You must execute this project strictly in phase order (0 → 8). Do not jump ahead, do not interleave phases, do not start the UI before the inference engine compiles and generates text, and do not write engine code before Phase 0 research is complete.
Working rules:
- One phase at a time. At the start of each phase, write a short plan (checklist) into
docs/PLAN.md; check items off as you complete them. At the end of each phase, perform a phase checkpoint: build the project (swift build), run what's runnable, fix all warnings/errors, and write a 3–5 line phase summary indocs/PLAN.mdbefore moving on. - Phase gates: Phase 0 is complete only when
docs/MLX-RESEARCH.mdanddocs/MODELS.mdare complete (see Phase 0). Phase 2 is complete only when a minimal CLI proof-of-concept loads one small MLX model and streams generated tokens to stdout. Phase 3 is complete only when a model can be searched, downloaded with live progress, resumed after interruption, and deleted. Phase 4 spec is the contract for all UI in Phase 6. Phase 7 is complete only when the model verification table is fully green. Phase 8 is complete only whenspctlsays "Notarized Developer ID". - Single source of truth, everywhere:
- Curated model data → only from
ModelCatalog(generated fromdocs/MODELS.md). Live Hugging Face results come fromHubServiceonly. - Colors, fonts, spacing, radii → only from
ZyquoThemedesign tokens. Zero raw hex values or magic numbers in views. - All inference behavior → only in the
Engine/layer, never leaking into ViewModels or Views. - Product naming → only per the conventions above. Never
Zyquoalone, neverZyquoLocalin user-facing text.
- Curated model data → only from
- Coherence sweeps: after Phases 3, 6, and 8, do a dedicated consistency pass over the whole codebase: naming conventions uniform (types
UpperCamelCase, one term per concept — alwaysLocalModel, never a mix ofModel/LLM/LocalModel), no dead code, file headers present, folder structure matches Phase 2 exactly. - Compile early, compile often. Never accumulate more than one file of unbuilt changes. If the build breaks, fixing it is the immediate priority.
- Commit discipline: one logical unit per commit, message prefixed by phase (e.g.,
phase3: resumable downloads with progress). Never commit model weights or large binaries. - When research and reality disagree (e.g., a model in
docs/MODELS.mdfails to load in Phase 7), updatedocs/MODELS.mdANDModelCatalogtogether — the two must never drift apart.
⚠️ PHASE 0 — MANDATORY INTENSIVE WEB RESEARCH (DO THIS FIRST, BEFORE WRITING ANY CODE)
Do NOT rely on your training data — MLX Swift APIs, package structure, and the Hugging Face model landscape change fast. Research the CURRENT state of everything below using official sources (github.com/ml-explore/mlx-swift, github.com/ml-explore/mlx-swift-examples, huggingface.co/docs, huggingface.co/mlx-community, github.com/huggingface/swift-transformers). Produce TWO research documents before writing any code.
0.A — docs/MLX-RESEARCH.md — the MLX Swift stack
Document precisely:
- Current MLX Swift packages and how to depend on them via SPM:
mlx-swift(core: MLX, MLXNN, MLXRandom, MLXFast…) and the LLM layer (MLXLLM/MLXLMCommon/MLXVLM— verify their current home: mlx-swift-examples repo or a dedicated package), exact repository URLs, current stable versions/tags, and minimum macOS requirement. - The exact current API for: loading a model from a local directory (
ModelContainer/loadModelContainer/ factory APIs — verify names), tokenization, applying chat templates, streaming token-by-token generation (callback orAsyncSequence), generation parameters supported (temperature, topP, repetitionPenalty, maxTokens, seed…), KV cache handling for multi-turn chat, and how to unload/free a model. - Model directory format MLX expects on disk:
config.json,*.safetensors(possibly sharded +model.safetensors.index.json),tokenizer.json/tokenizer_config.json, chat template location. Which files are strictly required. - Supported architectures in the current MLX Swift LLM layer (Llama, Qwen2/2.5/3, Mistral, Gemma/2/3, Phi-3/4, DeepSeek/distills, SmolLM, OpenELM, etc. — verify the actual list) so the app can warn before downloading an unsupported model.
- ⚠️ The no-Xcode build question — resolve this definitively: MLX contains Metal kernels. Verify whether
swift buildworks with only Command Line Tools, or whether the Metal shader compiler requires full Xcode (xcrun -sdk macosx metal). Test it. Document the finding and the working recipe indocs/BUILD.md. If full Xcode (or its Metal toolchain component) turns out to be strictly required for compiling MLX's shaders, the rule adapts to: build viaswift build/xcodebuildfrom the command line only — never the Xcode IDE, no.xcodeprojauthored by hand — and the Makefile must automate everything end-to-end regardless. - swift-transformers / Hub API in Swift: what
huggingface/swift-transformersoffers for Hub downloads and tokenizers, and whether to use it or implementHubServicedirectly on the HTTP API (document both paths, pick one, justify in the doc). - Memory model: unified memory implications, MLX GPU memory/cache limits (
MLX.GPU.set(cacheLimit:)etc.), and how to estimate RAM needed for a model (≈ weights size + KV cache + overhead).
0.B — docs/MODELS.md — the curated model catalog + Hub integration
- Hugging Face Hub HTTP API, fully documented: model search (
GET /api/models?author=mlx-community&search=…&sort=downloads), model info + file listing (/api/models/{repo_id}withsiblings), file download URLs (https://huggingface.co/{repo}/resolve/main/{file}), LFS redirects,HEADfor file sizes, rate limits, optional user HF token for gated models (Llama, Gemma) viaAuthorization: Bearer. - The
mlx-communityorganization — the primary source of ready-to-run MLX models. Document the naming scheme (Model-Name-4bit,-8bit,-bf16) and what the quantization suffixes mean for quality/RAM. - A curated "Featured" catalog of 20–30 excellent models across sizes, verified to exist RIGHT NOW on the Hub with exact repo IDs and download sizes. Cover: tiny (≤3B: Qwen small, Llama 3.2 small, SmolLM, Gemma small), mid (7–14B: Qwen, Mistral/Ministral, Llama, Phi, Gemma), large (27–70B+ for 64GB+ Macs), plus coding models and reasoning models (DeepSeek-R1 distills, QwQ-class). For each: repo ID, params, quant, disk size, min recommended RAM, category tags, one-line description.
- RAM recommendation table: which model sizes fit comfortably on 8 / 16 / 24 / 32 / 48 / 64 / 128 GB Macs — this feeds the in-app compatibility badges.
PHASE 1 — Project Setup
- Toolchain: Swift Package Manager.
Package.swiftwith executable targetZyquoLocal, depending on the MLX packages identified in Phase 0. Build withswift build -c releaseper the recipe indocs/BUILD.md. - App bundle:
Makefilethat: (1) builds release, (2) assemblesZyquo Local.app(Contents/MacOS/ZyquoLocal,Info.plist,Resources/AppIcon.icns, and any Metal library/bundle resources MLX requires — verify resource bundling for SPM-built apps), (3) signs (Phase 8; ad-hoc formake dev). - Info.plist:
CFBundleDisplayName=Zyquo Local, bundle IDcom.zyquo.local,LSMinimumSystemVersionper MLX requirements (macOS 14.0 if MLX requires it — set from Phase 0 findings),NSHighResolutionCapable,LSApplicationCategoryType(public.app-category.productivity),LSArchitecturePriorityarm64. - Entry point:
@mainSwiftUIApp; proper activation when launched from terminal. - Dependencies: only MLX packages + (if chosen) swift-transformers + optionally Apple's
swift-markdown. Nothing else.
PHASE 2 — Architecture + Inference Proof-of-Concept
Sources/ZyquoLocal/
├── App/ # @main, windows, menu bar extra, Apple Silicon gate
├── DesignSystem/ # ZyquoTheme — same token system as Zyquo Cloud, Local palette
├── Models/ # Conversation, Message, LocalModel, DownloadTask, Persona…
├── Engine/
│ ├── InferenceEngine.swift # actor: load/unload, warmup, streaming generate
│ ├── GenerationParams.swift # temp, topP, repetitionPenalty, maxTokens, seed
│ ├── ChatSession.swift # multi-turn history → prompt via chat template, KV cache reuse
│ └── MemoryAdvisor.swift # RAM estimation, fits/tight/won't-fit verdicts
├── Hub/
│ ├── HubService.swift # HF search, model info, file listing
│ ├── DownloadManager.swift # queued, resumable, per-file progress, checksum
│ └── ModelStore.swift # on-disk library: scan, validate, size, delete
├── Services/
│ ├── PersistenceService.swift # conversations as JSON in Application Support
│ └── ModelCatalog.swift # curated Featured catalog from docs/MODELS.md
├── ViewModels/
└── Views/InferenceEngineis an actor. One model loaded at a time (v1). Loading states:unloaded → loading(progress) → ready → generating. Generation exposed asAsyncThrowingStream<GenerationEvent>where events include.token(String),.stats(tokensPerSec, ...),.finished(reason). Cancellation must actually stop the generation loop.ChatSessionbuilds the prompt from conversation history using the model's own chat template (fromtokenizer_config.json), truncates oldest turns when exceeding the context window (keep the system prompt), and reuses KV cache across turns when the API allows.- Stats are first-class: measure time-to-first-token, tokens/sec, generated token count, and peak memory for every response.
- PHASE GATE: before any UI, ship a tiny CLI mode (
ZyquoLocal --poc <model-dir> "<prompt>") that loads a small model (e.g., a ≤1B mlx-community model) and streams tokens to stdout with final stats. This proves the whole stack.
PHASE 3 — HUGGING FACE INTEGRATION: BROWSE & DOWNLOAD IN-APP (THE HEART OF THE APP)
This must be flawless — it is the feature that defines Zyquo Local.
HubService:
- Search the Hub live (default scope:
mlx-community, toggle "All of Hugging Face" with an MLX-compatibility filter based onconfig.jsonarchitectures from Phase 0.A.4) - Sort by downloads / likes / recency; filter by size class and quantization
- Fetch full file listings with per-file sizes; compute total download size before starting
- Optional HF token field in Settings for gated models (Llama, Gemma) — stored in the app's config, masked in UI, sent only to huggingface.co
DownloadManager:
- Download all required files of a repo (per Phase 0.A.3's required-file list) into
Models/{org}/{repo}/ - Resumable (HTTP Range) across app restarts; pause / resume / cancel per model
- Live progress: per-file and overall bytes, speed (MB/s), ETA;
URLSessionbackground-friendly configuration, 2 concurrent file downloads max - Integrity: verify final file sizes against the Hub listing (and checksums where available); atomic completion (download to
.partial, move into place, mark model valid only when all files verified) - Disk space pre-check before starting; clear error if insufficient
ModelStore:
- Scans the Models folder at launch; validates each model directory (required files present); reports size on disk
- Delete model (with confirmation showing reclaimed space); reveal in Finder
- Tracks last-used date and per-model default generation params
PHASE 4 — DESIGN SYSTEM & UI SPECIFICATION (LIGHT THEME, PIXEL-PERFECT)
Zyquo Local shares the same design DNA and token system as Zyquo Cloud (ZyquoTheme), with a distinct "Local" identity: where Cloud is sky-blue and airy, Local is grounded, warm, on-device — an emerald-graphite story evoking silicon and privacy.
4.1 — Light theme specification
| Token | Value (light) | Usage |
|---|---|---|
background |
#FAFBFA (warm neutral off-white, faint green undertone) |
Main canvas |
surface |
#FFFFFF |
Cards, assistant bubbles, input bar |
surfaceSecondary |
#F2F5F3 |
Hover, code blocks |
sidebar |
NSVisualEffectView .sidebar material |
Sidebar |
accent |
#0E9F6E (refined emerald — "on-device" green) |
Primary actions, selection, links, send |
accentSubtle |
#E7F6F0 |
Selected rows, user bubble tint |
textPrimary |
#1A1E1C |
Body text |
textSecondary |
#6B7472 |
Metadata |
textTertiary |
#9EA8A5 |
Placeholders |
border |
#E4E9E6 |
0.5pt hairlines |
success / warning / danger |
#2FA36B / #D9822B / #D64545 |
Status |
Same global rules as Zyquo Cloud: no pure black on pure white, 0.5pt hairlines, ultra-soft shadows (black.opacity(0.06), radius 12, y 2) only on floating panels, dark theme derived from tokens (deep graphite-green, not flat gray), light theme is the flagship.
Typography (identical scale to Zyquo Cloud): title 20pt semibold; body 13.5pt regular, line-height 1.45; bodyEmphasis 13.5pt medium; caption 11pt; code 12.5pt SF Mono; user-adjustable chat size 12–18pt. Spacing 4/8/12/16/20/24/32; radii 6/10/14; message column max 760pt centered.
4.2 — Layout & screens (exact spec)
Main window — NavigationSplitView, min 980×640, default 1240×800:
- Sidebar (260pt, translucent): "Zyquo Local" wordmark (icon glyph + name); two top-level sections: Chats (search, New Chat button, conversations grouped Pinned/Today/Yesterday/Previous 7 Days/Older, each row = title + model badge + relative time, hover pin/delete) and Library (entry to the Model Library screen, with a live badge showing active downloads count + a mini overall progress ring). Footer: settings gear + currently loaded model chip with a colored RAM dot.
- Chat area:
- Header (52pt): editable conversation title; centered model chip (model name + quant badge, e.g. "Qwen2.5-7B · 4bit"; click → model switcher popover listing downloaded models with RAM verdict badges; switching triggers unload/load with inline progress in the chip); right: performance toggle (shows live tokens/sec while generating), export, info popover (system prompt, params, context usage bar showing tokens used / context window).
- Transcript: identical structure to Zyquo Cloud (user right in
accentSubtlebubbles, assistant left onsurface, 16pt rhythm, hover timestamps, jump-to-bottom pill, full Markdown + syntax-highlighted code blocks with copy, collapsible "Thinking…" section for reasoning models like R1-distills — parse<think>tags). Under each assistant message, a subtlecaptionstats line:⚡ 42.3 tok/s · 512 tokens · 1.2s to first token. - Model-loading state: when a model is loading, the chat area shows an elegant centered loading card (model name, animated progress, RAM being allocated) — input disabled with a clear hint.
- Input bar: identical floating card as Zyquo Cloud (radius 14, soft shadow); attach button for text files (txt, md, code, csv, json → injected into the message); parameters quick-toggle; circular emerald send button (⌘↩); stop button during generation.
- Empty state (no model downloaded yet): a beautiful onboarding hero — icon, "Download your first model", 3–4 recommended starter models as cards (name, size, RAM fit for THIS Mac, one-line description, Download button). This is many users' first screen: it must be stunning.
Model Library screen (pushed in the detail column, or ⌘L):
- Two tabs: "Installed" and "Discover".
- Installed: grid/list of downloaded models — name, quant badge, params, disk size, last used, RAM verdict badge (green "Fits" / orange "Tight" / red "Too large" for this machine via
MemoryAdvisor), actions: Load, chat shortcut, per-model default params, Reveal in Finder, Delete (confirmation with reclaimed GB). Header shows total disk used by models. - Discover: search field (live Hub search), scope segmented control (Featured / mlx-community / All MLX-compatible), filters (size class, quantization), sort (downloads/likes/newest). Result cards: model name, org, params + quant, download size, downloads count, RAM verdict for this Mac, short description; primary Download button → card flips into live progress state (progress bar, MB/s, ETA, pause/cancel). The Featured tab renders the curated catalog from
docs/MODELS.mdwith editorial one-liners — it must feel hand-picked, like an App Store front page. - Downloads drawer: a bottom bar (or popover from the sidebar badge) listing all active/queued downloads with individual controls.
Settings (native tabs, 720×520): 1. General (default model on launch, keep model loaded in background toggle) 2. Models & Storage (models folder location + change, total usage, HF token field masked, auto-verify downloads) 3. Inference (default generation params with explanations, GPU cache limit, context length cap) 4. Appearance (Light/Dark/System, accent choices: emerald default + graphite, sky, amber, rose; font size slider with live preview) 5. Shortcuts 6. Advanced (reveal data folder, export/import conversations).
Quick Chat panel (⌥Space): same Spotlight-style floating panel as Zyquo Cloud, using the currently loaded model; if none is loaded, offers one-click load of the last-used model.
Compare mode: 2 columns (v1: two models — note both must fit in RAM together; MemoryAdvisor gates this), same prompt broadcast, independent streaming and stats — a spectacular way to visually compare local models.
4.3 — Motion & micro-interactions
Same standard as Zyquo Cloud: smooth streaming (no jitter), blinking caret at stream tail, 150ms fade+rise on sent messages, 80ms hover eases, 0.97 press scale, .snappy popovers, 60fps always (lazy transcript rendering). Plus Local-specific: download progress animates fluidly (no jumpy bars), the model chip morphs smoothly between unloaded/loading/ready states, and tokens/sec ticker updates at 4Hz max (no flicker).
4.4 — Design quality gate
Before declaring the project done, review every screen: consistent token usage, aligned baselines, no clipped text, correct dark mode, clean font-size scaling, ALL states designed (no models yet, model loading, downloading, download failed, out of RAM, generating, error). If a screen looks "developer-made" rather than "designed", iterate until it doesn't.
PHASE 5 — APP ICON: ULTRA-LEGENDARY "LOCAL" ICON, DESIGNED IN SVG
Designed in SVG first (assets/icon/zyquo-local.svg), then converted to .icns. It must be the visual sibling of the Zyquo Cloud icon — same squircle, same Z-monogram DNA, same premium quality — but telling the on-device story instead of the sky.
Creative direction:
- Concept — the Z on silicon. Two directions to explore (render both, keep the best):
- Z-chip: the bold Z monogram seated at the center of a subtly stylized silicon die — a minimal square chip outline with fine traces/pins radiating from its edges, the Z glowing like an active core. Reads as "the intelligence lives on THIS chip".
- Z-core: the Z itself drawn as a luminous circuit path — its strokes are clean conductor traces with rounded corners and 2–3 tiny node dots at the bends, glowing emerald on a deep graphite field. One shape, letterform + circuitry.
- Canvas: macOS Big Sur–style rounded squircle (Apple curvature).
- Palette (mirrors the app): deep graphite-to-near-black vertical gradient background with a faint green undertone (
#1E2622 → #0F1412territory), the Z/traces in luminous emerald (#17C787 → #0E9F6Egradient) with a restrained outer glow, plus near-white micro-highlights on trace nodes. Where Cloud is day-sky and airy, Local is dark-silicon and glowing — side by side in the Dock, the pair must be instantly recognizable as siblings. - Precision & iteration: clean paths,
viewBox="0 0 1024 1024", optical centering, glow effects that don't turn to mud when downscaled. Render at 1024/512/256/128/64/32/16, LOOK at each, refine; bake a simplified variant (drop traces, keep glowing Z) for 16/32px if needed.
Pipeline (Makefile): zyquo-local.svg → PNGs (16→1024, incl. @2x) via rsvg-convert or a small CoreGraphics rasterizer → AppIcon.iconset → iconutil -c icns. SVG stays in the repo as source of truth. Derive the monochrome menu bar template icon (18×18pt, isTemplate = true) and the in-app empty-state/wordmark glyph from the same SVG.
PHASE 6 — Features (This is where Zyquo Local becomes LEGENDARY)
Core chat
- Multi-conversation sidebar: search, pin, rename, delete, folders/tags
- Full token-streaming with stop button; per-message stats line (tok/s, tokens, TTFT)
- Model switcher per conversation (among downloaded models), with load progress and RAM verdicts; conversation remembers its model
- Message actions: copy, edit & resend, regenerate (optionally with another model), delete, quote-reply
- Reasoning display for thinking models (R1 distills, QwQ-class): parse
<think>…</think>into the collapsible section - System prompt per conversation + global default; context usage bar (tokens used vs context window) with automatic oldest-turn truncation
- Per-conversation generation params: temperature, top_p, repetition penalty, max tokens, seed — with sensible defaults and inline explanations
Model management (the differentiator)
- Full in-app Hub browse/search/download (Phase 3) with the Featured curated catalog
MemoryAdvisorverdicts everywhere a model is shown (Fits / Tight / Too large for this specific Mac, based on physical RAM detected viasysctl hw.memsize)- One model loaded at a time; explicit Load/Unload; optional "keep loaded" setting; unload frees memory verifiably
- Live memory readout while a model is loaded (app footprint) in the footer chip
Attachments & productivity
- Drag & drop / attach text files (txt, md, code, csv, json) into messages
- Prompt Library: ship ≥50 quality templates + user templates with
{{input}}variables - Personas: system prompt + preferred model + params
- Quick Chat panel (⌥Space)
- Compare mode (2 local models side-by-side, RAM-gated)
- Export conversation → Markdown and PDF; full-text search across conversations
- Auto-generated conversation titles using the loaded model itself (short, cheap prompt after first exchange)
macOS-native polish
- Shortcuts: ⌘N new chat, ⌘K model switcher/command palette, ⌘L Library, ⌘F search, ⌘↩ send, ⌘⇧E export, ⌥Space Quick Chat
- Menu bar extra (toggleable): quick chat + download progress at a glance
- Launch fast; the app itself must stay light — all heaviness lives in explicit model loading
PHASE 7 — LOCAL MODEL VERIFICATION (MANDATORY)
No API keys here — verification means proving that downloading and running real models works end-to-end on this machine:
- Build a verification harness (
zyquo-verifyCLI target or script) that:- Downloads at least 5 models from the Featured catalog spanning architectures and sizes (e.g., one ≤1B, one ~3B, one ~7–8B, one reasoning distill, one coding model — pick what fits this Mac's RAM)
- For each: validates the downloaded files, loads the model, runs a deterministic generation (
temperature 0, prompt"Reply with exactly: OK"), verifies non-empty coherent output, runs a multi-turn exchange (context carry-over works), runs a streaming cancellation test, unloads, and confirms memory is released - Records tok/s and TTFT per model
- Additionally, dry-verify the ENTIRE Featured catalog against the live Hub: every repo ID exists, files are listed, sizes match
docs/MODELS.md. - Produce a results table: model → download ✅/❌ → load ✅/❌ → generate ✅/❌ → tok/s. Fix every failure (wrong repo ID, unsupported arch, template issue) and iterate until green. Remove or replace catalog entries that are genuinely broken.
- Downloaded test models may be deleted afterward to reclaim disk, keeping the smallest one for ongoing dev.
PHASE 8 — SIGNING & NOTARIZATION (REAL, NOT AD-HOC)
The user has an existing, working signing/notarization setup for another project. Before doing anything, read and inspect the folder:
/Users/simon-pierreboucher/Desktop/other/OTHER/zyquo-termLocate everything related to signing and notarization there: scripts, Makefile targets, the Developer ID Application identity name, Team ID, notarytool keychain profile or Apple ID + app-specific password, entitlements files, any .env/config. Reuse the exact same identity, Team ID, and notarytool credentials/profile for Zyquo Local. Never invent placeholders, never print secrets, never commit them.
Then implement make release:
- Build release binary (arm64 only — MLX), assemble
Zyquo Local.appincluding any MLX resource bundles/metallibs entitlements.plistwith Hardened Runtime; only what's needed (network client for Hugging Face downloads; add JIT/unsigned-memory entitlements ONLY if MLX demonstrably requires them — test without first)codesign --force --options runtime --timestamp --entitlements entitlements.plist --sign "Developer ID Application: <identity from zyquo-term>" "Zyquo Local.app"— sign nested frameworks/dylibs/metallibs first, then the appditto -c -k --keepParent→xcrun notarytool submit "Zyquo Local.zip" --keychain-profile "<profile from zyquo-term>" --waitxcrun stapler staple "Zyquo Local.app"; verifyspctl -a -vvsays "accepted, source=Notarized Developer ID" andstapler validatepasses- Optional signed+stapled DMG via
hdiutil - On failure:
notarytool log, fix (nested code signatures are the classic culprit with bundled Metal libraries), resubmit until it passes.
Keep make dev with ad-hoc signing for iteration.
Engineering Standards
- Swift 5.9+ (Swift 6 mode if the toolchain allows); zero compiler warnings
InferenceEngineas an actor; all Hub/network typesCodablestructs — no dictionary spelunking- Robust error surfaces: human-readable messages for every failure class (no disk space, download interrupted → auto-resume offer, gated model → HF token hint, unsupported architecture, out-of-memory during load → suggest smaller quant)
- Cancellation everywhere: downloads, model loading, generation
- All UI strings centralized; design tokens only — no hardcoded colors/sizes in views
README.md+docs/BUILD.mdwith the exact no-Xcode(-IDE) build recipe- Commit in logical increments with clear messages; never commit model weights
Definition of Done
make releaseproduces a Developer ID–signed, notarized, stapledZyquo Local.app(verified byspctl)- In-app Hugging Face browsing + one-click resumable downloads work flawlessly, with the Featured curated catalog live-verified
- Chat with downloaded MLX models works: streaming, multi-turn with context management, stop, stats (tok/s, TTFT), reasoning display
MemoryAdvisorverdicts are accurate for this machine; loading/unloading verifiably frees memory- The silicon-themed SVG icon exists, is striking at all sizes, embedded as
.icns+ menu bar template icon; clearly the sibling of the Zyquo Cloud icon - The emerald light theme matches the Phase 4 spec exactly and passes the design quality gate; dark theme derived and correct
- Naming coherent everywhere:
Zyquo Localuser-facing,com.zyquo.local,ZyquoLocaltarget/data folder - Phase 7 verification table fully green;
docs/MODELS.mdandModelCatalogin perfect sync - Every code file starts with the mandatory Author/Mail header (verified by a repository-wide sweep)
docs/PLAN.mdshows every phase completed with its checkpoint summary- Zyquo Local feels like a polished, legendary native Mac app — the best local-LLM experience on macOS