SPB Git

spb/zyquo-agent Public MIT

The autonomous agent that actually operates your Mac — plans, runs real commands, verifies its own work.

Swift 94.7% Shell 4.1% Python 0.7% Makefile 0.5%

docs: ultra-detailed README with icon, badges, screenshots; MIT LICENSE; hardened .gitignore

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
simon-pierre boucher committed 11 days ago (Jul 30, 2026) parent 041b04c

Showing 8 changed files with +644 and −38

modified .gitignore +68 −1
@@ -1,6 +1,73 @@
1 +#
2 +# .gitignore
3 +# Zyquo Agent
4 +#
5 +# Author: Simon-Pierre Boucher
6 +# Mail: contact@spboucher.ai
7 +#
8 +
9 +# ---- Secrets (NEVER commit) -------------------------------------------------
1 10 .secrets/
11 +*.env.keys
12 +.env
13 +.env.local
14 +*.p12
15 +*.mobileprovision
16 +AuthKey_*.p8
17 +
18 +# ---- Swift Package Manager --------------------------------------------------
2 19 .build/
20 +.swiftpm/
21 +*.xcframework
22 +
23 +# ---- Build products / distribution -----------------------------------------
24 +build/
3 25 dist/
26 +DerivedData/
27 +*.dmg
28 +*.o
29 +*.dSYM/
4 30 *.icns.tmp
5 .DS_Store
31 +
32 +# ---- Xcode (not used to build, but keep clones clean) ----------------------
33 +*.xcodeproj/xcuserdata/
34 +*.xcworkspace/xcuserdata/
35 +*.xcuserstate
36 +*.xcuserdatad/
37 +xcuserdata/
38 +*.xcscmblueprint
39 +*.xccheckout
40 +*.moved-aside
41 +*.hmap
42 +*.ipa
43 +timeline.xctimeline
44 +playground.xcworkspace
45 +
46 +# ---- Dependency managers ---------------------------------------------------
47 +Pods/
48 +Carthage/Build/
49 +.netrc
50 +
51 +# ---- Tooling / caches ------------------------------------------------------
6 52 scripts/__pycache__/
53 +__pycache__/
54 +*.pyc
55 +.mypy_cache/
56 +
57 +# ---- macOS -----------------------------------------------------------------
58 +.DS_Store
59 +.DS_Store?
60 +._*
61 +.Spotlight-V100
62 +.Trashes
63 +.AppleDouble
64 +.LSOverride
65 +Icon?
66 +ehthumbs.db
67 +Thumbs.db
68 +
69 +# ---- Editors ---------------------------------------------------------------
70 +.idea/
71 +.vscode/
72 +*.swp
73 +*~
added LICENSE +21 −0
@@ -0,0 +1,21 @@
1 +MIT License
2 +
3 +Copyright (c) 2026 Simon-Pierre Boucher
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 +SOFTWARE.
modified README.md +555 −37
@@ -1,61 +1,579 @@
1 +<div align="center">
2 +
3 +<img src="assets/icon.png" alt="Zyquo Agent" width="180" height="180">
4 +
1 5 # Zyquo Agent
2 6
3 **Zyquo Agent** is the autonomous-agent member of the Zyquo family — a native macOS app
4 (Swift + SwiftUI, built with the Swift Package Manager, no Xcode IDE) that turns the same
5 cloud models as **Zyquo Cloud** into a deeply agentic assistant that can operate your Mac:
6 running `bash` commands and AppleScript, reading and writing files in per-task workspaces,
7 and iterating in a real plan→act→observe→reflect loop until the task is done — with
8 approvals, a risk-classifying policy gate, and a full audit log in front of every action.
7 +### **The autonomous agent that actually operates your Mac.**
8 +
9 +*Plans. Runs real commands. Verifies its own work. Asks before anything risky.*
10 +
11 +<br>
12 +
13 +[![Release](https://img.shields.io/github/v/release/spboucher-ai/zyquo-agent?style=for-the-badge&color=7A5AF0&labelColor=1B1A20)](https://github.com/spboucher-ai/zyquo-agent/releases/latest)
14 +[![Platform](https://img.shields.io/badge/platform-macOS%2013%2B-7A5AF0?style=for-the-badge&labelColor=1B1A20&logo=apple)](https://www.apple.com/macos/)
15 +[![Swift](https://img.shields.io/badge/Swift-6.0-F05138?style=for-the-badge&labelColor=1B1A20&logo=swift&logoColor=white)](https://swift.org)
16 +[![License](https://img.shields.io/badge/license-MIT-2FA36B?style=for-the-badge&labelColor=1B1A20)](LICENSE)
17 +
18 +[![Downloads](https://img.shields.io/github/downloads/spboucher-ai/zyquo-agent/total?style=flat-square&color=7A5AF0&labelColor=2E2A3A&label=downloads)](https://github.com/spboucher-ai/zyquo-agent/releases)
19 +[![Notarized](https://img.shields.io/badge/Gatekeeper-Notarized%20Developer%20ID-2FA36B?style=flat-square&labelColor=2E2A3A)](#-installation)
20 +[![Universal](https://img.shields.io/badge/binary-Universal%20(arm64%20%2B%20x86__64)-7A5AF0?style=flat-square&labelColor=2E2A3A)](#-building-from-source)
21 +[![Providers](https://img.shields.io/badge/providers-12-9B82F6?style=flat-square&labelColor=2E2A3A)](#-providers--models)
22 +[![Models](https://img.shields.io/badge/models-170%20(77%20agent--verified)-9B82F6?style=flat-square&labelColor=2E2A3A)](docs/VERIFICATION.md)
23 +[![Tool calling](https://img.shields.io/badge/tool--calling-77%2F80%20live%20verified-2FA36B?style=flat-square&labelColor=2E2A3A)](docs/VERIFICATION.md)
24 +[![Safety tests](https://img.shields.io/badge/safety%20tests-8%2F8-2FA36B?style=flat-square&labelColor=2E2A3A)](docs/EVALUATION.md)
25 +[![No Xcode](https://img.shields.io/badge/built%20with-SwiftPM%20only-D9822B?style=flat-square&labelColor=2E2A3A)](#-building-from-source)
26 +
27 +<br>
28 +
29 +**[⬇️ Download the DMG](https://github.com/spboucher-ai/zyquo-agent/releases/latest)** · **[📖 Docs](docs/)** · **[🔬 Verification report](docs/VERIFICATION.md)** · **[🧪 Evaluation report](docs/EVALUATION.md)**
30 +
31 +</div>
32 +
33 +<br>
34 +
35 +---
36 +
37 +<br>
38 +
39 +## 📋 Table of Contents
40 +
41 +- [✨ What is Zyquo Agent?](#-what-is-zyquo-agent)
42 +- [🖼️ Screenshots](#️-screenshots)
43 +- [🚀 Features](#-features)
44 + - [The agent engine](#the-agent-engine)
45 + - [The tools it can actually use](#the-tools-it-can-actually-use)
46 + - [Safety: the headline feature](#-safety-the-headline-feature)
47 + - [Workspaces](#-workspaces)
48 + - [Memory & context compaction](#-memory--context-compaction)
49 + - [The command-center interface](#-the-command-center-interface)
50 + - [Productivity](#-productivity)
51 +- [🤖 Providers & Models](#-providers--models)
52 +- [💾 Installation](#-installation)
53 +- [⚙️ Requirements](#️-requirements)
54 +- [📖 Usage](#-usage)
55 + - [Your first task](#your-first-task)
56 + - [Choosing a safety mode](#choosing-a-safety-mode)
57 + - [Keyboard shortcuts](#keyboard-shortcuts)
58 + - [The command-line interface](#the-command-line-interface)
59 +- [🔨 Building from Source](#-building-from-source)
60 +- [🏗️ Architecture](#️-architecture)
61 +- [🔬 Verification & Evaluation](#-verification--evaluation)
62 +- [🗺️ Roadmap](#️-roadmap)
63 +- [🤝 Contributing](#-contributing)
64 +- [📄 License](#-license)
65 +- [👤 Author](#-author)
66 +
67 +<br>
68 +
69 +---
70 +
71 +<br>
72 +
73 +## ✨ What is Zyquo Agent?
74 +
75 +**Zyquo Agent** is a native macOS app that turns cloud LLMs into an agent that *does things on your Mac* — it runs `bash` commands, drives other apps with AppleScript, reads and writes files, and keeps iterating until the task is genuinely done.
76 +
77 +It is not a chat window with a shell attached. It is a real **plan → act → observe → reflect** loop:
78 +
79 +```
80 +you describe a task
81 +
82 +the agent drafts a checklist → shown live in the Plan panel
83 +
84 +it calls a tool (bash / osascript / file ops)
85 +
86 +◆ every action passes a policy gate → risky ones stop and ask YOU
87 +
88 +it reads the actual result, revises the plan, and continues
89 +
90 +it verifies its own work with tools before declaring "done"
91 +```
92 +
93 +Everything is visible while it happens: streamed thinking, the exact command about to run, live `stdout`/`stderr`, exit codes, plan check-offs, token/time budgets — and an **append-only audit log** of every single action it took.
94 +
95 +Zyquo Agent is the agentic member of the **Zyquo** family (**Zyquo Cloud** — chat client · **Zyquo Local** — on-device models · **Zyquo Agent** — this). It reuses Cloud's provider layer and encrypted key vault, so your keys and model list feel identical across the family.
96 +
97 +> **Built entirely without the Xcode IDE** — Swift Package Manager and the command-line toolchain only.
98 +
99 +<br>
100 +
101 +---
102 +
103 +<br>
104 +
105 +## 🖼️ Screenshots
106 +
107 +<div align="center">
108 +
109 +### The command center at rest
110 +
111 +<img src="assets/screenshots/empty-state.png" alt="Zyquo Agent empty state" width="90%">
112 +
113 +<br><br>
114 +
115 +### A real run: step cards, live terminal feed, budget meters
116 +
117 +<img src="assets/screenshots/live-run.png" alt="Zyquo Agent live run" width="90%">
118 +
119 +*The agent wrote a file, then verified it with `list_dir` and `read_file` before answering. The drawer streams every action as it happens; the right panel tracks steps, tokens, and time against your budgets.*
120 +
121 +<br><br>
122 +
123 +### Safety settings: modes, boundaries, and your own allow/deny rules
124 +
125 +<img src="assets/screenshots/settings-safety.png" alt="Zyquo Agent safety settings" width="90%">
126 +
127 +</div>
128 +
129 +<br>
130 +
131 +---
132 +
133 +<br>
134 +
135 +## 🚀 Features
136 +
137 +### The agent engine
138 +
139 +| | |
140 +|---|---|
141 +| 🔄 **True agentic loop** | A `stop_reason`-keyed while-loop (`AgentLoop`, a Swift actor): stream a model turn → execute its tool calls → thread the results back → repeat until the model answers without calling tools. Handles truncation, refusals, and transient provider errors (one automatic retry with backoff). |
142 +| 🧠 **Reasoning-model aware** | Thinking/reasoning tokens stream into a collapsible section, separate from the answer. |
143 +| 📋 **Live editable plan** | The agent maintains a real checklist through an internal `update_plan` tool — items go pending → active → done/failed, persisted to `.zyquo/plan.json`, rendered in the Plan panel, and **editable by you** mid-run. |
144 +| ♻️ **Re-planning on failure** | A failed step doesn't derail the run: the agent self-critiques, revises the plan, and continues. (Verified end-to-end: [scenario s6](docs/EVALUATION.md).) |
145 +| 🛑 **LoopGuard** | Step / token / wall-clock budgets plus **repetition** detection (same failing call 3×) and **stall** detection (6 steps with no progress). On a trip it **pauses and asks you** — never silently spins or aborts. |
146 +| ⚡ **Streaming everything** | Text, thinking, and even partial tool-call *arguments* stream live, so you watch the command being composed before it runs. |
147 +| ⏹️ **Real cancellation** | ⌘. (or SIGINT on the CLI) cancels the model stream **and kills the running child process** (SIGTERM → SIGKILL), recording a `cancelled` outcome. Verified by test. |
9 148
10 Sibling apps: **Zyquo Cloud** (chat client) · **Zyquo Local** (on-device models) · **Zyquo Agent** (this).
149 +### The tools it can actually use
11 150
12 ## Requirements
151 +| Tool | What it does |
152 +|---|---|
153 +| `bash` | Runs commands via `/bin/bash -lc` with the workspace as cwd. Line-by-line `stdout`/`stderr` streaming, per-command timeout, exit code capture, 200 KB output cap with truncation notice, fully cancellable. |
154 +| `osascript` | Executes AppleScript to automate macOS apps (Finder, Notes, Mail, Calendar, System Events…). Detects TCC denials and explains how to grant Automation access. |
155 +| `read_file` | Reads a file with offset/limit paging (50 KB per call cap). |
156 +| `write_file` | Creates or overwrites a file, tracked in the workspace. |
157 +| `edit_file` | Exact-unique string replacement — **fails loudly** if the target text matches zero or multiple times, so edits can't silently hit the wrong line. |
158 +| `list_dir` | Directory listing with optional depth. |
159 +| `search_files` | Grep-like content search returning `file:line` matches, capped. |
160 +| `update_plan` | Internal (never touches the policy gate) — how the agent maintains its checklist. |
13 161
14 - macOS 13.0+ (Apple Silicon or Intel)
15 - Swift 6 command-line toolchain (Command Line Tools — the Xcode IDE is not used)
16 - The build pins `SDKROOT` to the MacOSX26 SDK (SDK 27's SwiftUI macros require Xcode); the
17 Makefile handles this automatically.
162 +Adding a tool is deliberately trivial: conform to the `Tool` protocol (name, description, JSON-Schema parameters, `execute`) and register it in `ToolRegistry`.
163 +
164 +### 🛡️ Safety: the headline feature
165 +
166 +This is the part most agent tools treat as an afterthought.
167 +
168 +**Three modes, switchable per task, always visible in the header:**
169 +
170 +| Mode | Behavior |
171 +|---|---|
172 +| **Manual** | Every gated action asks first. |
173 +| **Guarded** *(default)* | Curated read-only commands and in-workspace file writes run automatically; anything mutating asks. |
174 +| **Autonomous** | Runs freely within budget — **except** the always-ask class, which still asks. |
175 +
176 +**The gate itself** (`PolicyEngine`, a Swift actor) evaluates `deny → ask → allow`, **per subcommand**:
177 +
178 +- 🔍 **Commands are parsed, not pattern-matched.** Compound lines split on `&&`, `||`, `;`, `|` and newlines (quote-aware); `$(…)`/backtick substitutions are extracted and classified too; wrappers (`env`, `nohup`, `time`, `xargs`, `nice`) are stripped first. The verdict is the **most severe** across all subcommands — `ls && rm -rf ~/x` asks, because the second half asks.
179 +- ⛔ **Hard denies** that no approval can unlock: `rm -rf /` and equivalents, fork bombs, `mkfs`, `diskutil eraseDisk`, writes to `/System`.
180 +- ⚠️ **Always-ask circuit breakers, in *every* mode including Autonomous:** any `sudo`, `rm -rf` outside the workspace, `curl … | sh`, overwrites outside the workspace, `kill`/`pkill`, `defaults write`, `launchctl`, `csrutil`, `chmod -R` outside the workspace, writes to `/Library` `/usr` `/etc`, `git push --force`, `shutdown`, `security`, and AppleScript containing `with administrator privileges`.
181 +- 🚫 **`sudo` is never run silently.** Ever. Proven by a test that *forces* a `sudo` tool call and confirms denial in all three modes.
182 +- ✅ **Inline approval cards** show the exact payload, the risk level and reason, the cwd, and the agent's stated intent — with **Approve**, **Approve & Remember**, **Edit** (re-classified after your edit), and **Deny**.
183 +- 📝 **"Approve & remember"** stores the *narrowest* token-prefix rule (`brew list` matches `brew list --versions`, never `brew install`) — and a remembered rule can **never** override a circuit breaker.
184 +- 📜 **Append-only audit log** (`.zyquo/audit.jsonl`) records every executed action: timestamp, kind, exact payload, cwd, ruling, exit code, truncated output. Viewable in-app, exportable.
185 +
186 +Pattern matching is treated as UX, not a security boundary — it's paired with workspace scoping, human approval, and a complete audit trail.
187 +
188 +### 📁 Workspaces
189 +
190 +Every task gets its own directory under `~/Library/Application Support/ZyquoAgent/Workspaces/`. `bash` runs there; file tools are scoped there by default and **escaping requires explicit approval**. Created and modified files are tracked with badges, checkpoints can snapshot the agent's work, and reopening an old task restores its workspace and full step history.
191 +
192 +### 🗜️ Memory & context compaction
193 +
194 +Long autonomous runs don't fall off the context window:
195 +
196 +- Live token accounting, calibrated by the provider's own usage numbers.
197 +- At **85%** of the model's context, older completed steps are summarized into one compact record by the *same* model (with a mechanical fallback) — while the task, the plan, `MEMORY.md`, and the **most recent 6 steps stay verbatim**. A thrash guard enforces a minimum gap between compactions.
198 +- 📤 **Output offloading:** any tool result over 8 KB is written to `.zyquo/outputs/` and replaced in-context by its first ~40 lines plus a path the agent can re-read on demand.
199 +- 📌 **`MEMORY.md`** lives in the workspace root and is owned by the agent — it records durable facts that survive compaction *and* whole sessions.
200 +
201 +*Verified live: a task that triggered **4 compactions** still produced a fully correct result.*
202 +
203 +### 🖥️ The command-center interface
204 +
205 +- **Sidebar** — tasks grouped Pinned / Today / Yesterday / Previous 7 Days / Older, each with an animated status pill (Planning · Running · Awaiting approval · Done · Failed), model badge, and a live activity indicator.
206 +- **Conversation column** — your prompts as bubbles; the agent's work as **step cards**: thought line, tool chips, the exact command in monospace, color-coded streaming output, exit codes, expandable truncation, collapsible thinking, and inline approval / guard-trip / compaction cards. Final answers render as full Markdown with syntax-highlighted code.
207 +- **Plan panel** — the live checklist with animated check-offs, a progress bar, and step/token/time meters against your budgets.
208 +- **Activity drawer** — three tabs: **Live** (raw streaming terminal feed with cwd), **Audit Log** (every executed action), **Files** (workspace tree with created/modified badges, preview, reveal in Finder).
209 +- **Header** — editable title, model picker (all 170 models, agent-capable ones emphasized), the safety-mode segmented control, workspace chip, export, and an info popover showing the actual system prompt and budgets.
210 +- Light theme is the flagship; a deep plum-charcoal dark theme is derived from the same tokens. Five accent colors.
211 +
212 +### 🎯 Productivity
213 +
214 +- 📚 **29 built-in task templates** across 6 categories — Files & Folders (6), Development (6), Automation/AppleScript (5), Data (4), System Info (4), Writing (4) — with `{{variable}}` fill-in. Plus your own.
215 +- 🎭 **Personas** — a system-prompt addendum, preferred model, and default safety mode, applied per task.
216 +- ⚡ **Quick Task panel** (⌥Space) — a Spotlight-style floating panel that runs a one-off task and can be promoted to a full task.
217 +- 🔍 **⌘K command palette** — fuzzy search over tasks, templates, and actions.
218 +- 📤 **Export** transcripts to Markdown or PDF · 🔎 full-text search across all tasks · 🏷️ auto-generated task titles · 🔔 menu bar extra showing running-task status.
219 +- 🔐 **Encrypted key vault** — AES-256-GCM, HKDF-derived and machine-bound, stored at `~/Library/Application Support/ZyquoAgent/vault.zq`. **Deliberately not the Keychain**, matching the rest of the Zyquo family. Environment variables take precedence at run time.
220 +
221 +<br>
222 +
223 +---
224 +
225 +<br>
226 +
227 +## 🤖 Providers & Models
228 +
229 +Zyquo Agent ships the same **170-model catalog** as Zyquo Cloud across **12 providers**, and marks the ~80-model subset that's genuinely suited to multi-step agentic work (strong reasoning + reliable native function calling + adequate context).
230 +
231 +| Provider | Provider | Provider |
232 +|---|---|---|
233 +| 🟢 OpenAI | 🟣 Anthropic | ⚫ xAI |
234 +| 🟠 Mistral | 🔵 Google Gemini | 🟡 Alibaba Qwen |
235 +| 🐋 DeepSeek | 🌙 Kimi (Moonshot) | 🔍 Perplexity |
236 +| 🤝 Together AI | ☁️ DeepInfra | ⚡ Cerebras |
237 +
238 +Plus **custom OpenAI-compatible endpoints**. Two clients cover everything: a native `AnthropicClient` (`/v1/messages`, `tool_use`/`tool_result` blocks, `input_json_delta` streaming) and one `OpenAICompatibleClient` (index-keyed `tool_calls` deltas, `role:"tool"` messages) — normalized behind a single `ProviderClient` protocol so the agent loop never sees a wire format.
239 +
240 +**Every agent-capable model was verified live**, not assumed: **77 of 80 pass** the full battery — receives the schema, emits a valid *streamed* tool call, consumes a threaded `tool_result`, and produces a correct final answer. Full per-model table with latencies: **[docs/VERIFICATION.md](docs/VERIFICATION.md)**.
241 +
242 +Two real provider quirks were found and fixed in the process:
243 +- **Gemini 3+ thought signatures** — Gemini rejects a threaded tool result if the originating call's opaque `thought_signature` isn't echoed back verbatim; it's now captured and round-tripped.
244 +- **OpenAI GPT-5.4+** — `/chat/completions` refuses function tools unless `reasoning_effort` is `none`; the client now downgrades it automatically when tools are attached.
245 +
246 +The 3 remaining failures are external and documented: DeepInfra's two Gemini re-hosts strip Google's required signature (the same models work via the native Gemini provider), and `kimi-k3` is capacity-throttled upstream.
247 +
248 +Default agent model: **`claude-sonnet-5`**.
249 +
250 +> 🔑 **Bring your own keys.** Zyquo Agent ships with none and talks only to the providers you configure.
251 +
252 +<br>
253 +
254 +---
255 +
256 +<br>
257 +
258 +## 💾 Installation
259 +
260 +### Option 1 — Download the DMG *(recommended)*
261 +
262 +<div align="center">
263 +
264 +### **[⬇️ Download Zyquo Agent 1.0.0](https://github.com/spboucher-ai/zyquo-agent/releases/latest/download/ZyquoAgent.dmg)**
265 +
266 +</div>
267 +
268 +1. Download `ZyquoAgent.dmg` from the [latest release](https://github.com/spboucher-ai/zyquo-agent/releases/latest).
269 +2. Open it and drag **Zyquo Agent** to your **Applications** folder.
270 +3. Launch it. **No Gatekeeper warning, no right-click-to-open workaround** — the app is signed with a Developer ID, notarized by Apple, and stapled:
271 +
272 +```console
273 +$ spctl -a -vv "/Applications/Zyquo Agent.app"
274 +/Applications/Zyquo Agent.app: accepted
275 +source=Notarized Developer ID
276 +origin=Developer ID Application: Simon-Pierre Boucher (3YM54G49SN)
277 +```
278 +
279 +4. Open **Settings → Providers & Keys** (⌘,) and paste at least one API key.
280 +
281 +### Option 2 — Build from source
282 +
283 +See [Building from Source](#-building-from-source).
284 +
285 +### First-run permissions
286 +
287 +The first time the agent runs AppleScript against another app, macOS asks for **Automation** permission. If you deny it, grant it later in **System Settings → Privacy & Security → Automation**; the app explains this inline when it hits a TCC denial.
288 +
289 +<br>
290 +
291 +---
18 292
19 ## Build
293 +<br>
294 +
295 +## ⚙️ Requirements
296 +
297 +| | |
298 +|---|---|
299 +| **macOS** | 13.0 Ventura or later |
300 +| **Architecture** | Apple Silicon *or* Intel — the release is a Universal binary (`arm64` + `x86_64`) |
301 +| **Disk** | ~15 MB for the app, plus whatever your task workspaces use |
302 +| **API key** | At least one from a supported provider (BYOK — none included) |
303 +| **Network** | Only to the providers you configure |
304 +| **To build** | Swift 6 command-line toolchain. The **Xcode IDE is not required**; `rsvg-convert` (Homebrew) only if you regenerate the icon. |
305 +
306 +Runtime dependency: exactly one — [`swift-markdown`](https://github.com/swiftlang/swift-markdown) for rendering. Everything else is Foundation, SwiftUI, AppKit, and CryptoKit.
307 +
308 +<br>
309 +
310 +---
311 +
312 +<br>
313 +
314 +## 📖 Usage
315 +
316 +### Your first task
317 +
318 +1. Press **⌘N** (or click **New Task**).
319 +2. Pick a model, and a safety mode — **Guarded** is a sensible default.
320 +3. Describe the outcome you want, not the commands. Press **⌘↩**.
321 +4. Watch it work. When an approval card appears, read the command, then **Approve**, **Edit**, or **Deny**.
322 +
323 +Good first tasks (all shipped as templates):
324 +
325 +```
326 +Organize my Downloads folder by file type into subfolders
327 +Set up a Python project with a venv, add pytest, and run the tests
328 +Find every file over 100 MB in this folder and summarize what's using space
329 +Batch-rename these screenshots to a YYYY-MM-DD-description pattern
330 +Read this CSV and give me totals per category
331 +Export my Notes to Markdown files
332 +```
333 +
334 +### Choosing a safety mode
335 +
336 +| If you… | Use |
337 +|---|---|
338 +| are trying it out, or the task touches anything you care about | **Manual** |
339 +| want it to move but keep your hand on anything mutating | **Guarded** ✅ |
340 +| have a long, well-understood, low-stakes task | **Autonomous** |
341 +
342 +In all three, destructive and elevated actions **still** require your approval.
343 +
344 +### Keyboard shortcuts
345 +
346 +| Shortcut | Action | | Shortcut | Action |
347 +|---|---|---|---|---|
348 +| `⌘N` | New task | | `⌘K` | Command palette |
349 +| `⌘↩` | Run | | `⌘F` | Search tasks |
350 +| `⌘.` | Stop | | `⌘⇧A` | Open audit log |
351 +| `⌥Space` | Quick Task panel | | `⌘⇧E` | Export transcript |
352 +| `⌘,` | Settings | | | |
353 +
354 +### The command-line interface
355 +
356 +The app binary doubles as a headless CLI — useful for scripting and CI:
357 +
358 +```bash
359 +BIN="/Applications/Zyquo Agent.app/Contents/MacOS/ZyquoAgent"
360 +
361 +# Run a task headlessly, with live rendering and stdin approval prompts
362 +"$BIN" --run "summarize the largest files in this folder" \
363 + --model claude-sonnet-5 --mode guarded --workspace ~/scratch --max-steps 20
364 +
365 +# Scripted runs: auto-approve mode-driven prompts.
366 +# NOTE: --yes never auto-approves the always-ask class — those are auto-DENIED
367 +# unless you additionally pass --allow-destructive.
368 +"$BIN" --run "…" --yes
369 +
370 +"$BIN" --load-vault # import provider keys from environment variables
371 +"$BIN" --verify # live tool-calling verification across the catalog
372 +"$BIN" --verify-policy # PolicyEngine safety self-check (38 assertions)
373 +"$BIN" --run-mock # offline engine smoke test, no keys or network
374 +```
375 +
376 +Keys resolve from the environment first (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, …), then the encrypted vault.
377 +
378 +<br>
379 +
380 +---
381 +
382 +<br>
383 +
384 +## 🔨 Building from Source
20 385
21 386 ```bash
22 make dev # release build → dist/Zyquo Agent.app (ad-hoc signed, fast iteration)
23 make run # make dev + open the app
24 make release # universal binary, Developer ID sign, notarize, staple (Phase 8)
25 make icon # regenerate AppIcon.icns from assets/icon/zyquo-agent.svg
26 make test # swift test (requires an XCTest-capable toolchain)
387 +git clone https://github.com/spboucher-ai/zyquo-agent.git
388 +cd zyquo-agent
389 +
390 +make dev # release build → dist/Zyquo Agent.app (ad-hoc signed) — fast iteration
391 +make run # build, bundle, and launch
392 +make icon # regenerate AppIcon.icns from assets/icon/zyquo-agent.svg
27 393 make clean
28 394 ```
29 395
30 Plain SPM also works: `swift build -c release` (export
31 `SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk` first).
396 +Plain SwiftPM works too:
397 +
398 +```bash
399 +export SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX26.sdk
400 +swift build -c release
401 +```
402 +
403 +<details>
404 +<summary><b>Why <code>SDKROOT</code> is pinned</b></summary>
405 +
406 +<br>
407 +
408 +SDK 27 declares SwiftUI's `@State` and friends as *macros*, and the macro plugin (`libSwiftUIMacros.dylib`) ships only with the full Xcode install. SDK 26 keeps the property-wrapper forms, so a Command-Line-Tools-only toolchain can build the whole app. The `Makefile` sets this for you.
409 +
410 +</details>
411 +
412 +<details>
413 +<summary><b>Producing a signed, notarized release</b></summary>
414 +
415 +<br>
416 +
417 +`make release` builds a Universal binary (`arm64` + `x86_64` via `lipo`), assembles the bundle, then signs, notarizes, staples, and verifies it. It requires your own Developer ID certificate and a `notarytool` keychain profile — edit `IDENTITY` and `NOTARY_PROFILE` in the `Makefile`.
418 +
419 +```bash
420 +make release # app: sign → notarize → staple → spctl
421 +scripts/notarize.sh "dist/Zyquo Agent.app" "<identity>" "<profile>" \
422 + Resources/ZyquoAgent.entitlements dmg # …and a notarized DMG
423 +```
424 +
425 +The script **fails loudly** unless `spctl` reports `source=Notarized Developer ID`.
426 +
427 +> ⚠️ Keep `Resources/ZyquoAgent.entitlements` pure ASCII with no XML comments — the AMFI parser `codesign` uses rejects both.
428 +
429 +</details>
32 430
33 ## CLI modes
431 +<details>
432 +<summary><b>Running the checks</b></summary>
34 433
35 The app binary doubles as a headless CLI:
434 +<br>
36 435
37 436 ```bash
38 ZyquoAgent --run "create a folder ~/zqtest with a hello.txt, then list it" # agent loop POC
39 ZyquoAgent --verify # Phase 7 provider tool-calling harness (needs API keys)
40 ZyquoAgent --verify-policy # PolicyEngine safety self-checks
41 ZyquoAgent --load-vault # seed the encrypted key vault from environment variables
437 +.build/release/ZyquoAgent --verify-policy # 38 safety assertions
438 +.build/release/ZyquoAgent --run-mock # offline end-to-end engine test
439 +.build/release/ZyquoAgent --run-ui-smoke # UI state-machine test
440 +scripts/agent-eval.sh all # full live scenario + safety suite (needs keys)
42 441 ```
43 442
44 ## Data locations
443 +`swift test` requires an XCTest-capable toolchain; the XCTest files are there for Xcode/CI, and the executable checks above are the equivalents that run anywhere.
45 444
46 - App data: `~/Library/Application Support/ZyquoAgent/`
47 - Per-task workspaces: `~/Library/Application Support/ZyquoAgent/Workspaces/`
48 - Encrypted key vault (AES-256-GCM, no Keychain — same design as Zyquo Cloud): `…/ZyquoAgent/vault.zq`
445 +</details>
49 446
50 ## Documentation
447 +<br>
51 448
52 - `docs/PLAN.md` — phase-by-phase build plan and checkpoints
53 - `docs/AGENT-RESEARCH.md` — the agent-design research the architecture traces back to
54 - `docs/PROVIDER-REUSE.md` — the Zyquo Cloud provider study and porting contract
449 +---
450 +
451 +<br>
452 +
453 +## 🏗️ Architecture
454 +
455 +**82 Swift files, ~19,000 lines**, no Xcode project file.
456 +
457 +```
458 +Sources/ZyquoAgent/
459 +├── App/ @main, CLI modes, SwiftUI shell, menu bar (5 files)
460 +├── Agent/ AgentLoop · Planner · MemoryManager · LoopGuard
461 +│ Transcript · AgentStep · AgentEvent · prompt (8 files)
462 +├── Tools/ Tool protocol · ToolRegistry · ShellTool
463 +│ AppleScriptTool · FileTools (5 files)
464 +├── Execution/ ExecutionService · PolicyEngine · AuditLog (4 files)
465 +├── Workspace/ WorkspaceManager (1 file)
466 +├── Providers/ ProviderClient · Anthropic · OpenAI-compatible (4 files)
467 +├── Models/ ToolSpec/ToolCall/ToolResult · AgentTask
468 +│ catalog types · templates (9 files)
469 +├── Services/ ModelCatalog · SecureKeyStore · Streaming (6 files)
470 +├── ViewModels/ TaskStore · RunController · approval bridge (8 files)
471 +├── Views/ Command center, settings, palette, Markdown (25 files)
472 +├── DesignSystem/ ZyquoTheme tokens, components, glyph (4 files)
473 +└── Verify/ Live provider verification harness (1 file)
474 +```
475 +
476 +**Design rules that hold throughout:**
477 +
478 +- `AgentLoop`, `ExecutionService`, `PolicyEngine`, `AuditLog`, and `WorkspaceManager` are **actors**; structured concurrency everywhere; every long operation is cancellable.
479 +- Shell execution **never** leaks into views or view models — it lives behind `ExecutionService`, and everything passes `PolicyEngine` first.
480 +- The UI renders exclusively from an `AgentEvent` stream and the persisted `Transcript`.
481 +- Every color, font, spacing, and radius comes from `ZyquoTheme` tokens — no raw hex in views.
482 +
483 +The architecture traces directly back to research documented in **[docs/AGENT-RESEARCH.md](docs/AGENT-RESEARCH.md)** (413 lines, 79 cited sources), and the provider layer to **[docs/PROVIDER-REUSE.md](docs/PROVIDER-REUSE.md)**.
484 +
485 +<br>
486 +
487 +---
488 +
489 +<br>
490 +
491 +## 🔬 Verification & Evaluation
492 +
493 +Nothing here is claimed on vibes — it was measured, and the failures are documented too.
494 +
495 +| Suite | Result | Report |
496 +|---|---|---|
497 +| **Provider tool-calling** (live, every agent-capable model) | **77 / 80** green | [docs/VERIFICATION.md](docs/VERIFICATION.md) |
498 +| **End-to-end scenarios** (live, real workspaces) | **11 / 11** pass | [docs/EVALUATION.md](docs/EVALUATION.md) |
499 +| **Safety tests** (live) | **8 / 8** pass | [docs/EVALUATION.md](docs/EVALUATION.md) |
500 +| **PolicyEngine self-check** | **38 / 38** | `--verify-policy` |
501 +
502 +Scenarios cover: nested file structures, batch renaming, writing *and running* a Python script, CSV analysis checked against ground truth, largest-file discovery, **re-planning after a deliberate failure**, **forced memory compaction**, AppleScript automation, multi-tool log analysis, and cross-provider parity on a second provider.
503 +
504 +Safety tests confirm: `sudo` never executes in any mode (including a test that *forces* a sudo tool call), out-of-workspace deletes are auto-denied, cancellation kills the child process, `rm -rf /` is hard-denied, and no key material reaches any transcript, log, or workspace file.
505 +
506 +<br>
507 +
508 +---
509 +
510 +<br>
511 +
512 +## 🗺️ Roadmap
513 +
514 +- [ ] Enforce the two settings that are currently persisted-but-advisory: `requireApprovalForAppleScript` in Autonomous mode, and `workspaceEscapePolicy = deny` *(the engine already asks for AppleScript in Manual/Guarded and always asks on workspace escape — these would add stricter hooks)*
515 +- [ ] Optional **Seatbelt sandbox profile** for Autonomous runs, on top of the policy gate
516 +- [ ] Read-only **explorer sub-agent** that returns summaries without mutating state
517 +- [ ] **HTTP fetch tool** (the `Tool` protocol is built for this)
518 +- [ ] Improve auto-generated task titles — short prompts can produce clipped titles
519 +- [ ] Workspace **checkpoint restore** exposed in the UI
520 +- [ ] Structured exit codes and policy rulings surfaced per step card (currently in the audit log)
521 +- [ ] Re-verify `kimi-k3` when Moonshot's capacity recovers
55 522
56 API keys are **never** committed, logged, or embedded; they live only in the encrypted
57 vault (or env vars during testing).
523 +<br>
58 524
59 525 ---
60 526
61 Author: Simon-Pierre Boucher · contact@spboucher.ai
527 +<br>
528 +
529 +## 🤝 Contributing
530 +
531 +Issues and pull requests are welcome.
532 +
533 +If you contribute code, please keep the project's conventions:
534 +
535 +1. **Every code file starts with the standard header** (name, `Zyquo Agent`, author, mail) — there's a sweep that checks.
536 +2. **Zero build warnings.**
537 +3. **Design tokens only** — no raw hex values or magic numbers in views; add a token to `ZyquoTheme` if one is genuinely missing.
538 +4. **Never bypass the safety gate.** There must be no code path that executes a shell command or AppleScript without going through `PolicyEngine`, and no action that isn't audited.
539 +5. **Never commit secrets.** API keys belong in the vault or the environment. `.secrets/` is gitignored.
540 +6. Before opening a PR, run: `swift build -c release`, `--verify-policy`, `--run-mock`, and `--run-ui-smoke`.
541 +
542 +<br>
543 +
544 +---
545 +
546 +<br>
547 +
548 +## 📄 License
549 +
550 +Released under the **MIT License** — see [LICENSE](LICENSE).
551 +
552 +<br>
553 +
554 +---
555 +
556 +<br>
557 +
558 +## 👤 Author
559 +
560 +<div align="center">
561 +
562 +**Simon-Pierre Boucher**
563 +
564 +[![Email](https://img.shields.io/badge/contact@spboucher.ai-7A5AF0?style=for-the-badge&logo=maildotru&logoColor=white&labelColor=1B1A20)](mailto:contact@spboucher.ai)
565 +
566 +<br>
567 +
568 +**The Zyquo family** — one design language, three characters
569 +☁️ Zyquo Cloud *(chat)* · 💠 Zyquo Local *(on-device)* · ⚡ **Zyquo Agent** *(autonomous)*
570 +
571 +<br>
572 +
573 +<sub>Built on macOS with Swift, SwiftUI, and the command line — no Xcode IDE.</sub>
574 +
575 +<br>
576 +
577 +⭐ **If Zyquo Agent is useful to you, a star is genuinely appreciated.**
578 +
579 +</div>
added assets/icon-512.png +0 −0

Binary file not shown.

added assets/icon.png +0 −0

Binary file not shown.

added assets/screenshots/empty-state.png +0 −0

Binary file not shown.

added assets/screenshots/live-run.png +0 −0

Binary file not shown.

added assets/screenshots/settings-safety.png +0 −0

Binary file not shown.