diff --git a/Apps/Mac/Peekaboo/Features/Settings/AboutSettingsView.swift b/Apps/Mac/Peekaboo/Features/Settings/AboutSettingsView.swift index 5663651b..e3d75a6f 100644 --- a/Apps/Mac/Peekaboo/Features/Settings/AboutSettingsView.swift +++ b/Apps/Mac/Peekaboo/Features/Settings/AboutSettingsView.swift @@ -51,7 +51,7 @@ struct AboutSettingsView: View { AboutLinkRow( icon: "chevron.left.slash.chevron.right", title: "GitHub", - url: "https://github.com/steipete/Peekaboo") + url: "https://github.com/openclaw/Peekaboo") AboutLinkRow(icon: "globe", title: "Website", url: "https://steipete.me") AboutLinkRow(icon: "envelope", title: "Email", url: "mailto:peter@steipete.me") } @@ -94,7 +94,7 @@ struct AboutSettingsView: View { } private func openProjectHome() { - guard let url = URL(string: "https://github.com/steipete/Peekaboo") else { return } + guard let url = URL(string: "https://github.com/openclaw/Peekaboo") else { return } NSWorkspace.shared.open(url) } } diff --git a/Examples/README.md b/Examples/README.md index 923b2ce1..f5abdcd1 100644 --- a/Examples/README.md +++ b/Examples/README.md @@ -122,7 +122,7 @@ import Tachikoma let modelProvider = try AIConfiguration.fromEnvironment() // 2. Get a specific model -let model = try modelProvider.getModel("gpt-4.1") // or "claude-opus-4-20250514", "llama3.3", etc. +let model = try modelProvider.getModel("gpt-5.5") // or "claude-opus-4-8", "llama3.3", etc. ``` ### Simple Text Generation @@ -150,7 +150,7 @@ print(text) ```swift // Compare responses from multiple providers -let providers = ["gpt-4.1", "claude-opus-4-20250514", "llama3.3"] +let providers = ["gpt-5.5", "claude-opus-4-8", "llama3.3"] for providerModel in providers { let model = try modelProvider.getModel(providerModel) @@ -262,9 +262,17 @@ let request = ModelRequest( ) ) -// Anthropic-specific: Use thinking mode -let claudeModel = try modelProvider.getModel("claude-opus-4-20250514-thinking") -// Thinking mode automatically enabled +// Anthropic-specific: Enable adaptive thinking explicitly +let claudeResult = try await generateText( + model: .anthropic(.opus48), + messages: [.user("Solve this complex problem")], + settings: GenerationSettings( + maxTokens: 4000, + providerOptions: ProviderOptions( + anthropic: AnthropicOptions(thinking: .adaptive) + ) + ) +) ``` ### Configuration Options @@ -585,4 +593,4 @@ After exploring these examples: - **Measure performance** with the built-in statistics - **Read the source code** - examples are educational! -Happy coding with Tachikoma! 🎉 \ No newline at end of file +Happy coding with Tachikoma! 🎉 diff --git a/Examples/Sources/SharedExampleUtils/ExampleUtilities.swift b/Examples/Sources/SharedExampleUtils/ExampleUtilities.swift index d914e40d..3070e405 100644 --- a/Examples/Sources/SharedExampleUtils/ExampleUtilities.swift +++ b/Examples/Sources/SharedExampleUtils/ExampleUtilities.swift @@ -200,9 +200,9 @@ public enum ProviderDetector { /// Get recommended model for each provider - updated with latest models public static func recommendedModels() -> [String: String] { [ - "OpenAI": "gpt-4.1", // Latest GPT-4.1 - "Anthropic": "claude-opus-4-20250514", // Claude Opus 4 (May 2025) - "Grok": "grok-4", // Latest Grok + "OpenAI": "gpt-5.5", + "Anthropic": "claude-opus-4-8", + "Grok": "grok-4.3", "Ollama": "llama3.3", // Best Ollama model for function calling ] } diff --git a/Examples/Sources/TachikomaAgent/TachikomaAgent.swift b/Examples/Sources/TachikomaAgent/TachikomaAgent.swift index 0dbea94c..8bb174c7 100644 --- a/Examples/Sources/TachikomaAgent/TachikomaAgent.swift +++ b/Examples/Sources/TachikomaAgent/TachikomaAgent.swift @@ -187,7 +187,7 @@ struct TachikomaAgent: AsyncParsableCommand { } // Prefer models with good function calling support - let functionCallingPreferred = ["gpt-4.1", "claude-opus-4-20250514", "grok-4", "llama3.3"] + let functionCallingPreferred = ["gpt-5.5", "claude-opus-4-8", "grok-4.3", "llama3.3"] for preferred in functionCallingPreferred { if availableModels.contains(preferred) { diff --git a/Examples/Sources/TachikomaBasics/TachikomaBasics.swift b/Examples/Sources/TachikomaBasics/TachikomaBasics.swift index 4b7869c1..d1981820 100644 --- a/Examples/Sources/TachikomaBasics/TachikomaBasics.swift +++ b/Examples/Sources/TachikomaBasics/TachikomaBasics.swift @@ -225,7 +225,7 @@ struct TachikomaBasics: AsyncParsableCommand { // Auto-select the best available model // Prioritized by quality and general capabilities - let preferredOrder = ["claude-opus-4-20250514", "gpt-4.1", "llama3.3", "grok-4"] + let preferredOrder = ["claude-opus-4-8", "gpt-5.5", "llama3.3", "grok-4.3"] for preferred in preferredOrder { if availableModels.contains(preferred) { diff --git a/Examples/Sources/TachikomaComparison/TachikomaComparison.swift b/Examples/Sources/TachikomaComparison/TachikomaComparison.swift index 363351de..51c5b69f 100644 --- a/Examples/Sources/TachikomaComparison/TachikomaComparison.swift +++ b/Examples/Sources/TachikomaComparison/TachikomaComparison.swift @@ -113,7 +113,7 @@ struct TachikomaComparison: AsyncParsableCommand { let availableProviders = recommended.values.filter { availableModels.contains($0) } // Prefer a good mix if we have many available - let preferredOrder = ["gpt-4.1", "claude-opus-4-20250514", "llama3.3", "grok-4"] + let preferredOrder = ["gpt-5.5", "claude-opus-4-8", "llama3.3", "grok-4.3"] var selected: [String] = [] for model in preferredOrder { diff --git a/Examples/Sources/TachikomaMultimodal/TachikomaMultimodal.swift b/Examples/Sources/TachikomaMultimodal/TachikomaMultimodal.swift index d67a451a..9551568f 100644 --- a/Examples/Sources/TachikomaMultimodal/TachikomaMultimodal.swift +++ b/Examples/Sources/TachikomaMultimodal/TachikomaMultimodal.swift @@ -104,7 +104,7 @@ struct TachikomaMultimodal: AsyncParsableCommand { if visionModels.isEmpty { TerminalOutput.print("❌ No vision-capable models available", color: .red) - TerminalOutput.print("💡 Vision models require: GPT-4V, Claude 3+, or LLaVA", color: .yellow) + TerminalOutput.print("💡 Vision models require a vision-capable GPT, Claude, or LLaVA model", color: .yellow) return } @@ -316,7 +316,7 @@ struct TachikomaMultimodal: AsyncParsableCommand { if visionModels.isEmpty { throw NSError(domain: "TachikomaMultimodal", code: 1, userInfo: [ - NSLocalizedDescriptionKey: "No vision-capable models available. Need GPT-4V, Claude 3+, or LLaVA.", + NSLocalizedDescriptionKey: "No vision-capable GPT, Claude, or LLaVA model is available.", ]) } @@ -332,7 +332,7 @@ struct TachikomaMultimodal: AsyncParsableCommand { } // Prefer high-quality vision models - let visionPreferred = ["gpt-4o", "claude-opus-4-20250514", "claude-3-5-sonnet", "llava"] + let visionPreferred = ["gpt-5.5", "claude-opus-4-8", "claude-sonnet-4-6", "llava"] for preferred in visionPreferred { if visionModels.contains(preferred) { @@ -349,8 +349,13 @@ struct TachikomaMultimodal: AsyncParsableCommand { let lowercased = model.lowercased() return lowercased.contains("gpt-4o") || lowercased.contains("gpt-4-vision") || + lowercased.contains("gpt-5") || lowercased.contains("claude-3") || lowercased.contains("claude-4") || + lowercased.contains("claude-fable") || + lowercased.contains("claude-opus-4") || + lowercased.contains("claude-sonnet-4") || + lowercased.contains("claude-haiku-4") || lowercased.contains("llava") || lowercased.contains("vision") } diff --git a/Examples/Sources/TachikomaStreaming/TachikomaStreaming.swift b/Examples/Sources/TachikomaStreaming/TachikomaStreaming.swift index 1bbf270c..9f3fc4af 100644 --- a/Examples/Sources/TachikomaStreaming/TachikomaStreaming.swift +++ b/Examples/Sources/TachikomaStreaming/TachikomaStreaming.swift @@ -314,7 +314,7 @@ struct TachikomaStreaming: AsyncParsableCommand { } // Auto-select best available for streaming - let streamingPreferred = ["claude-opus-4-20250514", "gpt-4.1", "llama3.3", "grok-4"] + let streamingPreferred = ["claude-sonnet-4-6", "gpt-5.5", "llama3.3", "grok-4.3"] for preferred in streamingPreferred { if availableModels.contains(preferred) { @@ -327,15 +327,12 @@ struct TachikomaStreaming: AsyncParsableCommand { /// Select models for racing (up to 4) private func selectRacingModels(from availableModels: [String]) -> [String] { - let recommended = ProviderDetector.recommendedModels() - let availableProviderModels = recommended.values.filter { availableModels.contains($0) } - // Prefer a good mix for racing - let racingOrder = ["gpt-4.1", "claude-opus-4-20250514", "llama3.3", "grok-4"] + let racingOrder = ["gpt-5.5", "claude-sonnet-4-6", "llama3.3", "grok-4.3"] var selected: [String] = [] for model in racingOrder { - if availableProviderModels.contains(model), selected.count < 4 { + if availableModels.contains(model), selected.count < 4 { selected.append(model) } } diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index fb381f2f..debe32ad 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -38,6 +38,24 @@ This document provides a high-level overview of how Tachikoma and PeekabooCore w - **Tachikoma** – still the AI provider surface that the runtime modules call through. See [providers.md](providers.md) for the current provider and model catalog. +### Runtime hosting + +Permission-bound automation can execute in three runtime shapes: + +| Runtime | State and permissions | Transport | +| --- | --- | --- | +| Reusable daemon | Warm snapshots, tracking, browser MCP state; daemon process TCC | `daemon.sock` Bridge protocol | +| Peekaboo.app | GUI-held TCC grants and app lifecycle | `bridge.sock` Bridge protocol | +| MCP server | Process-local services owned by the MCP client | stdio; no Bridge listener | + +CLI automation resolves a healthy daemon first, then a capable Peekaboo.app host, then auto-starts the reusable daemon. +Operations that permit local fallback can run in the CLI process when no host is usable. Explicit socket and +`--no-remote` flags override this selection. + +The daemon and GUI app never share a socket. Each Bridge listener holds an exclusive lease, publishes its socket +atomically, and removes only the filesystem object it owns. See [daemon.md](daemon.md) and +[bridge-host.md](bridge-host.md) for lifecycle, migration, security, and TCC troubleshooting. + ### Dependency Flow **Tachikoma** (AI Model Management) diff --git a/docs/MCP.md b/docs/MCP.md index 69b687d6..d0aced1e 100644 --- a/docs/MCP.md +++ b/docs/MCP.md @@ -13,6 +13,9 @@ This document explains how Peekaboo exposes its automation tools as an MCP serve Peekaboo runs as an MCP server over stdio, exposing its native tools (image, see, click, etc.) to external MCP clients such as Codex, Claude Code, or Cursor. Peekaboo no longer hosts or manages external MCP servers; configure your MCP client to launch `peekaboo mcp` directly. +By default, the MCP process owns its lifecycle and keeps support services process-local. An explicit +`--bridge-socket ` instead attaches MCP tools to that existing Bridge host and skips the embedded support daemon. +In both modes, MCP never publishes `daemon.sock`, `bridge.sock`, or another Bridge listener itself. Action-oriented UI tools include: diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 6fa20099..379d9bd2 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -1,100 +1,88 @@ --- -summary: 'Peekaboo 3.x release checklist (main repo + submodules)' +summary: 'Release Peekaboo CLI, npm package, signed macOS app, and Sparkle appcast.' read_when: - - 'preparing for a release' - - 'cleaning up repos before release' + - 'preparing, publishing, or verifying a Peekaboo release' --- -# Peekaboo Release Checklist +# Peekaboo release checklist -> **Note:** Run commands from the repo root unless a step says otherwise. For long Swift builds/tests, use tmux as documented in AGENTS. -> **No-warning policy:** Lint/format/build/test steps must finish cleanly (no SwiftLint/SwiftFormat warnings, no pnpm warnings). Fix issues before moving on. -> -> **Release policy (betas):** Beta versions are **normal GitHub releases** (not prereleases) and **npm `latest`** must always point at the newest beta. Only use prerelease flags for truly experimental builds that should not be the default. Release notes must be **only the changelog entries** for that version (no install steps, no extra prose). +Run from the repository root. Releases publish `@steipete/peekaboo`, universal CLI archives, checksums, and a +Developer ID signed/notarized `Peekaboo.app` with a Sparkle appcast entry. -**Scope:** Main Peekaboo repo plus submodules `/AXorcist`, `/Commander`, `/Tachikoma`, `/TauTUI`. Each has its own `CHANGELOG.md` and must be released in lock-step. +## 1. Prepare -## 0) Version + metadata prep -- [ ] Bump versions: `package.json`, `version.json`, app Info.plists (CLI + macOS targets), and all MCP server/tool banners (`Core/PeekabooCore/Sources/PeekabooAgentRuntime/MCP/**`). -- [ ] Cut `CHANGELOG.md`: move items from **Unreleased** into the new 3.x section with the correct date. -- [ ] Align docs that mention the version (`docs/tui.md`, `docs/reports/playground-test-result.md`, `AGENTS.md`, any beta strings). -- [ ] Submodules: bump versions + changelogs in AXorcist, Commander, Tachikoma, TauTUI before updating submodule SHAs here. +- Confirm `main` is clean, current, and all submodules are at the intended commits. +- Update `package.json`, both `version.json` files, `Apps/CLI/Sources/Resources/Info.plist`, + `Apps/CLI/TestHost/Info.plist`, `PeekabooMCPVersion.current`, the README badge, and `MARKETING_VERSION` in the Mac, + Inspector, and Playground Xcode projects. +- Move release changes into matching dated sections in `CHANGELOG.md` and `Apps/CLI/CHANGELOG.md`. +- Update user-facing docs and `release/release-notes.md`. Release notes contain only that version's changelog section. +- Update submodule repositories first only when their code or release metadata changed, then commit the gitlink here. -## 1) Format & lint (all repos) -- [ ] Main: `pnpm run format:swift`, `pnpm run lint:swift`, plus `pnpm run format` / `pnpm run lint` if JS/TS changed. -- [ ] AXorcist: `swift run swiftformat .` then `swiftlint`. -- [ ] Commander: `swift run swiftformat .` then `swiftlint`. -- [ ] Tachikoma: `swift run swiftformat .` then `swiftlint`. -- [ ] TauTUI: `swift run swiftformat .` then `swiftlint`. +## 2. Validate -## 2) Tests & builds -- [ ] Main Swift build: `swift build`. -- [ ] Main tests: `(cd Apps/CLI && swift test)`; remove or rewrite any constructs that trigger the known SILGen/frontend crash before continuing. -- [ ] JS/TS tests: `pnpm test` (and `pnpm check` if applicable). -- [ ] Submodules: `swift build && swift test` in AXorcist, Commander, Tachikoma, TauTUI. -- [ ] Optional automation sweep: `pnpm run test:automation` when touching agent flows. - -## 3) Release artifacts -- [ ] `pnpm run prepare-release` (validates versions, changelog, and Swift/TS entry points). -- [ ] `./scripts/release-binaries.sh --create-github-release --publish-npm` (Default: universal arm64+x86_64 binary, npm package, signed/notarized `Peekaboo.app` zip, Sparkle appcast update, and checksums; use `--arm64-only` to skip Intel support or `--skip-mac-app` for CLI-only emergency releases). -- [ ] Verify `dist/` outputs and the generated checksum files. -- [ ] `npm pack --dry-run` to inspect the npm tarball if release scripts changed. - -## 3b) macOS app (Sparkle) -Peekaboo’s macOS app now ships Sparkle updates (Settings → About). Updates are **disabled** unless the app is a bundled `.app` and **Developer ID signed** (see `Apps/Mac/Peekaboo/Core/Updater.swift`). - -The main release script runs this step automatically. Use this section only to dry-run, repair, or upload the app zip for an existing release. - -- [ ] Ensure `Apps/Mac/Peekaboo/Info.plist` has `SUFeedURL`, `SUPublicEDKey`, and `SUEnableAutomaticChecks` set (defaults are already wired to the repo appcast). -- [ ] Ensure release credentials are available: - - Developer ID Application certificate in the login keychain. - - Sparkle EdDSA private key from `.mac-release.env` or `SPARKLE_PRIVATE_KEY_FILE`. - - Notarization credentials via `NOTARYTOOL_PROFILE` or `APP_STORE_CONNECT_KEY_ID`, `APP_STORE_CONNECT_ISSUER_ID`, and `APP_STORE_CONNECT_API_KEY_P8`. -- [ ] Optional local dry run before touching Apple/GitHub/appcast: - - `pnpm run release:mac-app -- --dry-run` -- [ ] Build, **Developer ID sign**, notarize, staple, zip, Sparkle-sign, verify, update `appcast.xml`, and upload. If `release/checksums.txt` already came from `release-binaries.sh`, include `--upload-checksums`; otherwise upload only the app zip and update checksums separately: - - `pnpm run release:mac-app -- --upload --upload-checksums` -- [ ] Confirm the script prints the expected GitHub asset URL, SHA256, zip length, and Sparkle signature. The script also validates `codesign`, `stapler`, `spctl`, extracted zip contents, and `xmllint` when available. -- [ ] Verify with an installed previous build: Settings → About → “Check for Updates…” installs the new build. - -## 3c) Non-Sparkle app bundles for GitHub release -`Peekaboo.app` is owned by the Sparkle step above. Use this section only for additional app bundles that are not distributed through Sparkle, such as Playground. - -- [ ] Build **warning-free** Release apps: - - `./runner xcodebuild -workspace Apps/Peekaboo.xcworkspace -scheme Playground -configuration Release -destination "platform=macOS,arch=arm64" -derivedDataPath /tmp/peekaboo-release-dd build` -- [ ] Launch smoke (optional but preferred): `open -n /tmp/peekaboo-release-dd/Build/Products/Release/Playground.app`, then quit it. -- [ ] Zip the app separately (resource forks preserved): - - `ditto -c -k --sequesterRsrc --keepParent /tmp/peekaboo-release-dd/Build/Products/Release/Playground.app release/Playground.app.zip` -- [ ] Update checksums to include app zips: - - `cd release && shasum -a 256 peekaboo-macos-universal.tar.gz steipete-peekaboo-.tgz Peekaboo-.app.zip Playground.app.zip > checksums.txt` -- [ ] Upload assets (clobber existing checksums): `gh release upload v release/Playground.app.zip release/checksums.txt --clobber` - -## 4) Git hygiene -- [ ] Commit and push submodules first (conventional commits in each subrepo). -- [ ] Update submodule pointers in the main repo and commit via `./scripts/committer`. -- [ ] Commit main repo release changes (changelog, version bumps, generated assets if tracked) via `./scripts/committer`. -- [ ] `git status -sb` should be clean. - -## 5) Tag & publish -- [ ] Tag the release: `git tag v` then `git push --tags`. -- [ ] Publish npm if the release script didn’t: `pnpm publish --tag latest`. -- [ ] Ensure npm points `latest` at the new beta: `npm dist-tag add @steipete/peekaboo@ latest`. -- [ ] Create GitHub release **without** prerelease flag; upload macOS binaries/tarballs + checksum, and paste **only** the CHANGELOG section for that version as the release notes. - -## 6) Post-publish verification -- [ ] `polter peekaboo --version` to confirm the stamped build date matches the new tag. -- [ ] `npm view @steipete/peekaboo dist-tags` to ensure `latest` matches the new beta. -- [ ] Homebrew tap: confirm the `Update Homebrew Formula` release workflow dispatched `steipete/homebrew-tap` and completed successfully. -- [ ] npm install: `npm install -g @steipete/peekaboo@latest` then `peekaboo --version` (or `npx @steipete/peekaboo@latest --version` for a no-install smoke). -- [ ] Homebrew verify: `brew update && brew upgrade steipete/tap/peekaboo && peekaboo --version` and **leave Homebrew-installed** at the end. -- [ ] Fresh-temp smoke: `rm -rf /tmp/peekaboo-empty && mkdir /tmp/peekaboo-empty && cd /tmp/peekaboo-empty && npx peekaboo@ --help` (no runner; outside repo). Ensure CLI/help prints and exits 0. - -## Quick status helpers ```bash -git status -sb -git submodule status +pnpm run format +pnpm run lint +pnpm run lint:docs +pnpm run docs:site +pnpm run test:safe +pnpm run prepare-release ``` -## Notes -- Conventional Commits only. Submodules first, main repo last. -- No stale binaries: run user-facing tests/verification via `polter peekaboo …` so the built binary matches the tree. +Run `pnpm run test:automation` and live provider tests when the release changes those surfaces. Before committing, +run the repository autoreview workflow until no accepted actionable findings remain. + +## 3. Commit and push + +Use `./scripts/committer` with Conventional Commits. Push `main`, pull with `--ff-only`, and confirm a clean tree +before building release artifacts; dirty trees produce invalid version metadata. + +## 4. Publish + +Load release credentials through the maintainer 1Password workflow, then run interactively: + +```bash +./scripts/release-binaries.sh \ + --create-github-release \ + --publish-npm +``` + +The script runs release preparation, builds the universal CLI and npm package, signs/notarizes/staples the macOS app, +generates checksums and Sparkle metadata, and uploads a draft GitHub release. When it pauses at the npm confirmation, +leave the process waiting, inspect the draft assets and notes, then answer `y` to publish npm. The signing identity must +be: + +```text +Developer ID Application: Peter Steinberger (Y5PE65HELJ) +``` + +After npm verification, append a `Verification` section to the draft body with the npm version page, registry tarball +URL, integrity value, publish time, and exact CI/test proof. Keep the changelog section intact, update the draft with +`gh release edit v --notes-file `, inspect the rendered body once more, then publish it: + +```bash +gh release edit v --draft=false +``` + +For beta versions, the script publishes with the `beta` tag. Peekaboo beta releases are still the default release, so +also run `npm dist-tag add @steipete/peekaboo@ latest` before publishing the GitHub draft. + +## 5. Verify + +- `npm view @steipete/peekaboo@` reports the version, tarball, integrity, and publish time; `latest` points to + the new version for stable and beta releases. +- Git tag and non-draft GitHub Release `v` exist. +- Release body contains the complete changelog section plus npm metadata and exact CI/test proof. +- GitHub assets include the CLI archive, npm tarball, app zip, and checksums expected by the script. +- `appcast.xml` is valid and its newest item points to the new GitHub app zip with matching length and signature. +- Extracted CLI and app report the new version; codesign, stapler, and Gatekeeper verification pass. +- A fresh temporary `npx @steipete/peekaboo@ --help` succeeds. +- Release and Homebrew workflows complete successfully. + +Commit and push the generated `appcast.xml` update if the release script leaves it dirty. + +## 6. Close out + +After all public verification passes, add `Unreleased` sections to both changelogs for the next patch version, commit, +push, pull `--ff-only`, and finish on clean `main`. diff --git a/docs/bridge-host.md b/docs/bridge-host.md index c1fd78bd..fff43bc9 100644 --- a/docs/bridge-host.md +++ b/docs/bridge-host.md @@ -86,7 +86,8 @@ Bridge hosts are intended to be long-lived and keep automation state **in memory ## CLI behavior -- By default, automation-oriented CLI commands use the on-demand Peekaboo daemon and fall back to local execution if it cannot start. +- By default, automation-oriented CLI commands use a healthy reusable daemon, then a capable Peekaboo.app GUI host, + then auto-start a daemon, with process-local execution as the final operation-dependent fallback. - Use `--no-remote` to force local execution. - Use `--bridge-socket ` or `PEEKABOO_BRIDGE_SOCKET` to override host discovery. - Use `PEEKABOO_DAEMON_SOCKET` only to change the auto-start daemon socket without treating it as an explicit Bridge override. diff --git a/docs/building.md b/docs/building.md index 49932185..2588d464 100644 --- a/docs/building.md +++ b/docs/building.md @@ -21,7 +21,7 @@ Swift packages, source builds, and pnpm helper scripts. ```bash # Clone -git clone https://github.com/steipete/peekaboo.git +git clone https://github.com/openclaw/Peekaboo.git cd peekaboo # Install JS deps diff --git a/docs/cli-command-reference.md b/docs/cli-command-reference.md index 7faa5237..20ad59df 100644 --- a/docs/cli-command-reference.md +++ b/docs/cli-command-reference.md @@ -22,7 +22,7 @@ Use `peekaboo --help` for inline flag descriptions; this page links to - [`run`](commands/run.md) – Execute `.peekaboo.json` scripts (`--output`, `--no-fail-fast`). - [`sleep`](commands/sleep.md) – Millisecond pauses between steps. - [`clean`](commands/clean.md) – Remove snapshot caches by ID, age, or all at once (`--dry-run` supported). -- [`config`](commands/config.md) – Subcommands: `init`, `show`, `edit`, `validate`, `add`, `login`, `set-credential` (legacy), `add-provider`, `list-providers`, `test-provider`, `remove-provider`, `models`. +- [`config`](commands/config.md) – Subcommands: `init`, `show`, `status`, `edit`, `validate`, `add`, `login`, `set-credential` (legacy), `add-provider`, `list-providers`, `test-provider`, `remove-provider`, `models-provider`. - [`daemon`](commands/daemon.md) – Start/stop/status for the headless daemon (live window tracking, in-memory snapshots). - [`permissions`](commands/permissions.md) – `status` (default), `grant`, and Event Synthesizing request helpers. - [`learn`](commands/learn.md) – Print the complete agent guide (system prompt, tool catalog, Commander signatures). @@ -56,6 +56,6 @@ Use `peekaboo --help` for inline flag descriptions; this page links to - [`agent`](commands/agent.md) – Natural-language automation with dry-run planning, resume, audio modes, and model overrides. - [`browser`](browser-mcp.md) – Dedicated CLI wrapper for the browser MCP tool: Chrome page status/connect/navigation/snapshot/click/fill/type/console/network/screenshot/trace. - `inspect-ui` – Dedicated CLI wrapper for the `inspect_ui` MCP tool, useful for accessibility-tree text/control inspection without screenshots. -- [`mcp`](commands/mcp.md) – `serve`, `list`, `add`, `remove`, `enable`, `disable`, `info`, `test`, `call`, `inspect` (stub) for Model Context Protocol workflows. +- [`mcp`](commands/mcp.md) – Run Peekaboo's MCP server; `serve` is the only subcommand and stdio is the implemented transport. Need structured payloads? Pass `--json` (or `--json-output`) where supported, or orchestrate multiple commands inside `.peekaboo.json` scripts executed via [`peekaboo run`](commands/run.md). diff --git a/docs/commands/agent.md b/docs/commands/agent.md index d7a84dbc..82da7639 100644 --- a/docs/commands/agent.md +++ b/docs/commands/agent.md @@ -29,6 +29,8 @@ read_when: - All agent executions run under `CommandRuntime.makeDefault()`, so environment variables, credentials, and logging levels match the top-level CLI state. - When `--dry-run` is set the agent still reasons about the task, but tool invocations are skipped; this is useful for understanding plans without touching the UI. - Audio flags wire into Tachikoma’s audio stack: `--audio` opens the microphone, `--audio-file` loads a WAV/CAF file, and `--realtime` enables low-latency streaming (OpenAI-only). +- Generation uses `agent.temperature` and `agent.maxTokens` from the shared config written by the macOS Settings UI. + Token requests are capped to model capability; unsupported temperature controls are omitted automatically. ## Chat mode diff --git a/docs/commands/capture.md b/docs/commands/capture.md index ea796470..0c50135c 100644 --- a/docs/commands/capture.md +++ b/docs/commands/capture.md @@ -83,5 +83,8 @@ peekaboo capture video /path/to/demo.mov --every-ms 500 --no-diff ## Troubleshooting - Verify Screen Recording + Accessibility permissions (`peekaboo permissions status`). +- In SSH, LaunchAgent, Codex, and other background launchd sessions, prefer a Bridge host with Screen Recording. + Legacy screen/area capture now rejects wallpaper-only or redacted false-success frames instead of writing them as + valid output. Use `--no-remote --capture-engine cg` only when the caller is in the active Aqua session and has TCC. - Confirm your target (app/window/selector) with `peekaboo list`/`peekaboo see` before rerunning. - Re-run with `--json` or `--verbose` to surface detailed errors. diff --git a/docs/commands/config.md b/docs/commands/config.md index 113d5824..63cc4624 100644 --- a/docs/commands/config.md +++ b/docs/commands/config.md @@ -20,11 +20,11 @@ read_when: | `status` | Display provider credential readiness. | `--timeout` (sec, default 30). | | `login` | Run an OAuth flow (no API key stored) for supported providers. | `login openai` (ChatGPT/Codex), `login anthropic` (Claude Pro/Max). | | `set-credential` | Legacy alias for `add `. | Positional ` ` pair. | -| `add-provider` | Append or replace a custom AI provider entry. | `--type openai|anthropic`, `--name`, `--base-url`, `--api-key`, `--headers key:value,…`, `--description`, `--force`. | +| `add-provider` | Append or replace a custom AI provider entry. | Positional `` plus `--type openai|anthropic`, `--name`, `--base-url`, `--api-key`, `--headers key:value,…`, `--description`, `--force`, `--dry-run`. | | `list-providers` | Dump built-in + custom providers plus whether they’re enabled. | `--json` follows the same schema that the runtime loads. | -| `test-provider` | Fires a quick `/models` request (or Anthropic equivalent) against the provider definition to make sure credentials/base URL are valid. | `--provider-id ` (required), `--timeout-ms`, `--model`. | -| `remove-provider` | Delete a custom provider entry. | `--provider-id ` and optional `--force` to skip confirmation. | -| `models` | Enumerate every model Peekaboo knows about (native, providers, or the specific server you pass). | `--provider-id`, `--include-disabled`. | +| `test-provider` | Fires a quick `/models` request (or Anthropic equivalent) against the provider definition to make sure credentials/base URL are valid. | Positional ``. | +| `remove-provider` | Delete a custom provider entry. | Positional `` plus optional `--force` and `--dry-run`. | +| `models-provider` | Check the provider endpoint and list configured models, or return discovered OpenAI-compatible models with `--discover`. | Positional `` plus optional `--discover` and `--save`. | ## Implementation notes - The underlying auth/config plumbing lives in the shared Tachikoma library and the `tachikoma config` CLI; Peekaboo sets `TachikomaConfiguration.profileDirectoryName = ".peekaboo"` so both tools read/write the same `~/.peekaboo/credentials` without copying environment variables. @@ -32,7 +32,7 @@ read_when: - `add`/`login`/`set-credential` write through `ConfigurationManager.shared`, so they use macOS file permissions + atomic temp-file renames; partial writes won’t corrupt the store even if the process crashes. - Provider readiness in human `init`/`show --effective` output is live-validated with per-provider pings (OpenAI/Codex, Anthropic, Grok/xai, Gemini, OpenRouter). Timeouts default to 30s and are caller overridable. JSON mode skips appended readiness text so stdout remains parseable. - Provider management commands share the same validation helpers: IDs must match `^[A-Za-z0-9-_]+$`, and provider types are limited to `.openai` or `.anthropic`. Headers passed via `--headers KEY:VALUE,…` are parsed into a `[String:String]` dictionary before being serialized back to disk. -- `test-provider` and `models` invoke the actual HTTP client stack (respecting proxy, TLS, and custom headers) rather than mocking responses, which is why they run on the main actor and surface real latencies. +- `test-provider` and every `models-provider` invocation contact the actual endpoint (respecting proxy, TLS, and custom headers). Without `--discover`, the model list still comes from configuration, but endpoint errors and timeouts are reported. With `--discover`, an OpenAI-compatible provider returns the remote model list. - All subcommands are `RuntimeOptionsConfigurable`, so global `--json` or `--verbose` flags work uniformly (handy when you script config changes). ## Examples @@ -55,6 +55,16 @@ peekaboo config add openrouter sk-or-v1-... # OAuth logins (no API key stored) peekaboo config login openai peekaboo config login anthropic + +# Manage a custom OpenAI-compatible endpoint +peekaboo config add-provider local-ollama \ + --type openai \ + --name "Local Ollama" \ + --base-url "http://localhost:11434/v1" \ + --api-key "dummy-key" +peekaboo config test-provider local-ollama +peekaboo config models-provider local-ollama --discover --save +peekaboo config remove-provider local-ollama --force ``` ## Troubleshooting diff --git a/docs/commands/mcp.md b/docs/commands/mcp.md index f307a05f..d73f26bd 100644 --- a/docs/commands/mcp.md +++ b/docs/commands/mcp.md @@ -12,11 +12,13 @@ read_when: ## Subcommands | Name | Purpose | Key options | | --- | --- | --- | -| `serve` | Run Peekaboo’s MCP server over stdio/HTTP/SSE. | `--transport stdio|http|sse` (default stdio), `--port ` for HTTP/SSE. | +| `serve` | Run Peekaboo’s MCP server over stdio/HTTP/SSE. | `--transport stdio|http|sse` (default stdio), `--port ` for HTTP/SSE; global `--bridge-socket ` attaches to an existing Bridge host. | ## Implementation notes - `serve` instantiates `PeekabooMCPServer` and maps the transport string to `PeekabooCore.TransportType`. Stdio is the default for Claude Code integrations. - HTTP/SSE server transports are stubbed; they currently throw “not implemented.” +- The MCP process owns its stdio lifecycle and never hosts a Bridge listener. Support stays process-local by default; + an explicit `--bridge-socket ` uses that existing Bridge host and skips the embedded daemon. - The native tool catalog includes bounded `capture` for live screen/window/region recording or video ingest. It writes retained frames, `contact.png`, `metadata.json`, and optional MP4 output, so use tool allow/deny filters when exposing MCP to untrusted clients. - UI automation tools include action-first additions: `set_value` directly mutates a settable accessibility value, and `perform_action` invokes a named accessibility action on an element from `see`. - `click` preserves element IDs and queries when forwarding to automation, so action-first policy can use accessibility actions before synthetic fallback. @@ -28,6 +30,9 @@ peekaboo mcp # Explicit transport selection peekaboo mcp serve --transport stdio + +# Route MCP tools through an existing Bridge host +peekaboo mcp serve --bridge-socket "$HOME/Library/Application Support/Peekaboo/bridge.sock" ``` ## Troubleshooting diff --git a/docs/commands/permissions.md b/docs/commands/permissions.md index 91cd153d..33e3d297 100644 --- a/docs/commands/permissions.md +++ b/docs/commands/permissions.md @@ -46,7 +46,11 @@ peekaboo permissions request-event-synthesizing ## Troubleshooting - Verify Screen Recording + Accessibility permissions (`peekaboo permissions status`). -- Check the printed `Source:` line. If it says `Peekaboo Bridge`, the status reflects the explicit Bridge socket or selected reusable daemon's TCC grants. Grant Screen Recording to that host process, or force local capture with `--no-remote --capture-engine cg` only when the caller process is running in the active Aqua GUI session and already has permission. SSH, LaunchAgent, Codex, and other background launchd sessions can still return wallpaper-only pixels despite TCC grants, so prefer Bridge there. +- Check the printed `Source:` line. If it says `Peekaboo Bridge`, the status reflects an explicit socket, the selected + reusable daemon, or a healthy Peekaboo.app fallback and its TCC grants. Grant Screen Recording to that host process, + or force local capture with `--no-remote --capture-engine cg` only when the caller process is running in the active + Aqua GUI session and already has permission. SSH, LaunchAgent, Codex, and other background launchd sessions can + still return wallpaper-only pixels despite TCC grants, so prefer Bridge there. - Treat `--capture-engine` as a local-debug override: it disables Bridge selection for that command. - If capture returns a blank desktop, wallpaper, or no windows while `permissions status` reports Screen Recording as denied, run `peekaboo permissions request-screen-recording` and then restart the affected Peekaboo process. Homebrew upgrades can move the CLI to a new Cellar path, so confirm the enabled System Settings row belongs to the current binary. - Confirm your target (app/window/selector) with `peekaboo list`/`peekaboo see` before rerunning. diff --git a/docs/configuration.md b/docs/configuration.md index 2e4e64bf..f8457716 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -21,7 +21,10 @@ Peekaboo resolves settings in this order (highest → lowest): | Setting | Config File | Environment Variable | Description | |---------|-------------|---------------------|-------------| -| AI Providers | `aiProviders.providers` | `PEEKABOO_AI_PROVIDERS` | Comma-separated list (`openai/gpt-4.1,anthropic/claude,grok/grok-4,ollama/llava:latest`). First healthy provider wins. | +| AI Providers | `aiProviders.providers` | `PEEKABOO_AI_PROVIDERS` | Comma-separated list (`openai/gpt-5.5,anthropic/claude-opus-4-8,grok/grok-4.3,ollama/llava:latest`). First healthy provider wins. | +| Agent Model | `agent.defaultModel` | `PEEKABOO_AGENT_MODEL` | Default model for `peekaboo agent`; CLI `--model` wins. | +| Agent Temperature | `agent.temperature` | - | Sampling temperature shared by the app and CLI (default `0.7`); clamped or omitted for models that restrict it. | +| Agent Max Tokens | `agent.maxTokens` | - | Requested output-token budget shared by the app and CLI (default `16384`, accepted range `1...128000`); clamped to provider capability. | | OpenAI API Key | credentials file | `OPENAI_API_KEY` | Required for OpenAI models. | | Anthropic API Key | credentials file | `ANTHROPIC_API_KEY` | Required for Claude models (API-key path). | | Anthropic OAuth | credentials file | `ANTHROPIC_REFRESH_TOKEN`, `ANTHROPIC_ACCESS_TOKEN`, `ANTHROPIC_ACCESS_EXPIRES` | Created by `config login anthropic`; no API key stored. | @@ -48,7 +51,7 @@ Peekaboo resolves settings in this order (highest → lowest): ## Provider Variables -- `PEEKABOO_AI_PROVIDERS`: `provider/model` CSV. Example: `openai/gpt-4.1,anthropic/claude-opus-4,grok/grok-4,ollama/llava:latest`. +- `PEEKABOO_AI_PROVIDERS`: `provider/model` CSV. Example: `openai/gpt-5.5,anthropic/claude-opus-4-8,grok/grok-4.3,ollama/llava:latest`. - `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GROK_API_KEY` | `X_AI_API_KEY` | `XAI_API_KEY`, `GEMINI_API_KEY`: required for their respective providers when using API keys. - `PEEKABOO_OLLAMA_BASE_URL`: change when your Ollama daemon isn’t on `localhost:11434`. @@ -57,6 +60,29 @@ Peekaboo resolves settings in this order (highest → lowest): - `PEEKABOO_DEFAULT_SAVE_PATH`: screenshot destination (created automatically). - `PEEKABOO_CLI_PATH`: point Peekaboo at a debug build (`.build/debug/peekaboo`) without copying binaries around. +## Agent generation settings + +The macOS Settings UI and `peekaboo agent` share `agent.temperature` and `agent.maxTokens` through +`~/.peekaboo/config.json`: + +```json +{ + "agent": { + "defaultModel": "anthropic/claude-fable-5", + "temperature": 0.7, + "maxTokens": 128000 + } +} +``` + +`maxTokens` is an upper request, not a promise: Peekaboo clamps it to the selected model's advertised output limit. +Fable 5 supports up to 128K output and a 1M context window. Anthropic-compatible custom providers inherit known +Fable limits from the model ID, while custom model entries can advertise their own `maxTokens`. + +Temperature is clamped to `0...1` for Anthropic-compatible models and `0...2` elsewhere. Peekaboo omits it entirely +for models that reject sampling controls, including GPT-5-compatible endpoints and current Anthropic adaptive-thinking +models. + ## UI Input Strategy Input strategy controls whether UI interactions use accessibility action invocation or synthetic input. The built-in diff --git a/docs/daemon.md b/docs/daemon.md index fe51c717..bfa4acfa 100644 --- a/docs/daemon.md +++ b/docs/daemon.md @@ -1,160 +1,81 @@ --- -summary: 'Plan for a headless Peekaboo daemon with live window tracking and MCP integration' +summary: 'Reference for Peekaboo daemon lifecycle, routing, sockets, and migration.' read_when: - - 'planning or implementing the Peekaboo daemon lifecycle' - - 'adding live window tracking or daemon status reporting' - - 'wiring MCP to run in daemon mode' + - 'debugging reusable daemon startup, status, migration, or idle exit' + - 'understanding CLI, GUI Bridge, and MCP runtime ownership' --- -# Peekaboo Daemon +# Peekaboo daemon -## Goals -- Provide a headless daemon with explicit lifecycle commands: - - `peekaboo daemon start` - - `peekaboo daemon stop` - - `peekaboo daemon status` -- When running as MCP (`peekaboo mcp`), automatically enter daemon mode: - - In-memory snapshot store - - Live window tracking - - Enhanced observability -- Improve accuracy and speed via cached state + event-driven updates. -- Keep stateful MCP-backed services, such as Chrome DevTools MCP, warm across separate `peekaboo` invocations. +Peekaboo's reusable daemon keeps automation services, snapshots, window tracking, and browser MCP state warm across +separate CLI invocations. It runs from the same `peekaboo` binary and is managed with: -## Non-goals (initially) -- No GUI or menu bar UI for the daemon. -- No launchd agent/daemon integration. -- No external network listeners beyond MCP’s stdio transport (HTTP/SSE still out of scope). - -## User Experience -### Commands -- `peekaboo daemon start` - - Starts a headless daemon **from the same `peekaboo` binary** (on-demand). - - Ensures bridge socket is up and window tracking is active. -- `peekaboo daemon stop` - - Gracefully shuts down the daemon. - - Cleans up observers and sockets. -- `peekaboo daemon status` - - Reports: - - Running state + PID - - Bridge socket path + handshake - - Activity state + idle timeout/deadline for auto-started daemons - - Permissions (Screen Recording, Accessibility) - - Snapshot cache stats (count, last access) - - Window tracker stats (tracked windows, last event timestamp) - - MCP mode indicator (if daemon was launched by MCP) - -### Output format -- Human-readable by default, `--json` supported (same style as `bridge status`). - -## Architecture -### High-level -``` -CLI (peekaboo) ─┐ - ├── Daemon Controller ──> Headless Daemon Host -MCP (stdio) ───┘ │ - ├─ PeekabooServices (InMemorySnapshotManager) - ├─ WindowTrackerService (AX + CG fallback) - ├─ Bridge Host (socket) - └─ Observability / Metrics +```bash +peekaboo daemon start +peekaboo daemon status +peekaboo daemon stop ``` -### New components -- **PeekabooDaemon** - - Owns a long-lived `PeekabooServices(snapshotManager: InMemorySnapshotManager())`. - - Starts Bridge host listener and WindowTrackerService. - - Exposes stop/status and browser MCP operations over the local Bridge socket. +## Runtime ownership -- **WindowTrackerService** (new service, likely in `PeekabooAutomationKit`) - - Uses AX notifications (`AXWindowCreated`, `AXWindowMoved`, `AXWindowResized`, etc.). - - Maintains an in-memory registry keyed by `CGWindowID` + AX identifier. - - Periodic CGWindowList diff for resilience (apps that don’t emit AX events). +Each long-lived host has one distinct role and socket: -- **SnapshotInvalidation** (new logic in snapshot manager or automation layer) - - When a tracked window moves/resizes, mark snapshot stale or update bounds. - - On interaction, re-verify window position before clicking/typing. +| Runtime | Socket | Lifecycle | +| --- | --- | --- | +| Reusable CLI daemon | `~/Library/Application Support/Peekaboo/daemon.sock` | Auto-started with idle exit, or manual until stopped. | +| Peekaboo.app Bridge | `~/Library/Application Support/Peekaboo/bridge.sock` | Owned by the GUI app and its TCC grants. | +| MCP server | stdio | Owned by the MCP client; no Bridge listener or published socket. | -### Auto daemon routing -- Automation-oriented CLI commands prefer the default Peekaboo daemon socket. -- The reusable daemon owns `~/Library/Application Support/Peekaboo/daemon.sock`; it never shares - Peekaboo.app's `bridge.sock`. -- If no reusable daemon is running, normal commands use a healthy Peekaboo.app GUI host before auto-starting a daemon, - preserving existing app-held TCC grants. -- On upgrade, daemon control detects a still-running legacy auto or manual daemon on `bridge.sock`. Daemons that - advertise conditional stop migrate to the dedicated listener while preserving lifecycle mode, poll interval, and - auto idle timeout. -- Migration defers while the daemon has active requests. Older daemons without conditional stop remain on the legacy - socket until they exit or are explicitly stopped, avoiding a status-to-stop race. Daemon stop drains accepted - connections before shutting down operational services. -- If no default daemon is reachable, command runtime starts `peekaboo daemon run --mode auto` and reconnects. -- Auto daemons track Bridge request activity and shut down after an idle timeout (default 300 seconds). -- `peekaboo list apps`, `peekaboo app list`, `--no-remote`, `PEEKABOO_NO_REMOTE`, explicit input strategy overrides, and explicit capture engine overrides keep commands local. -- `PEEKABOO_DAEMON_SOCKET` changes only the auto-start daemon socket; `PEEKABOO_BRIDGE_SOCKET` remains an explicit Bridge override and disables auto-start. -- Bridge protocol 1.5 lets `image`/`see` run desktop observation inside the daemon. The daemon writes screenshot files locally and returns paths, timings, diagnostics, and optional element data without serializing screenshot bytes through Bridge JSON. -- Runtime routing is split across focused helpers: socket resolution, daemon launch policy, bridge capability policy, input override detection, local service construction, and host resolution. Keep new routing exceptions in those helpers instead of growing `CommandRuntime`. +Normal automation commands prefer the reusable daemon when it is healthy. If it is unavailable, they use a healthy +Peekaboo.app host with the required capability before auto-starting a daemon. If no remote host is usable, the command +falls back to process-local services when that operation permits it. -## Placement -- Single entry point: `peekaboo` runs in **daemon mode** when requested. -- On-demand only; no launchd agent. +Explicit `--bridge-socket` or `PEEKABOO_BRIDGE_SOCKET` selects only that Bridge path and disables daemon auto-start. +`PEEKABOO_DAEMON_SOCKET` changes the reusable daemon path without becoming an explicit Bridge override. +`--no-remote` or `PEEKABOO_NO_REMOTE` forces local execution. -## Status/Observability Fields -- `daemon.running` (bool) -- `daemon.pid` -- `daemon.startedAt` -- `daemon.mode` (auto|manual|mcp) -- `bridge.socketPath` -- `bridge.handshake` (hostKind, ops, version) -- `permissions.screenRecording` -- `permissions.accessibility` -- `snapshots.count` -- `snapshots.lastAccessedAt` -- `tracker.trackedWindows` -- `tracker.lastEventAt` -- `tracker.axObservers` -- `tracker.cgPollIntervalMs` -- `browser.connected` -- `browser.toolCount` -- `browser.detectedBrowsers` -- `activity.activeRequests` -- `activity.lastActivityAt` -- `activity.idleTimeoutSeconds` -- `activity.idleExitAt` +## Lifecycle modes -## Implementation Phases -1) **Daemon scaffolding** - - Create headless executable target. - - Add `peekaboo daemon start|stop|status` commands. - - Implement local control channel (Unix socket or pidfile + health probe). +- **Auto**: launched on demand by a CLI command; exits after inactivity (default 300 seconds). +- **Manual**: launched by `peekaboo daemon start`; remains running until `peekaboo daemon stop`. -2) **Daemon mode services** - - Add `DaemonServices` initializer using InMemorySnapshotManager. - - Ensure Bridge host runs inside daemon. +`PEEKABOO_DAEMON_IDLE_TIMEOUT_SECONDS` changes the auto idle timeout. Accepted requests count as activity, and shutdown +waits for accepted connections and operational services to drain. -3) **WindowTrackerService** - - AX observer subscriptions + CGWindowList polling fallback. - - Registry API: list tracked windows, last event, etc. +Standalone `mcp` daemon mode is intentionally unavailable. `peekaboo mcp` owns its stdio lifecycle and uses only +process-local support such as window tracking. -4) **Snapshot invalidation + focus verification** - - Integrate with click/type/focus paths. - - Prefer re-verify bounds when window moved. +## Socket ownership -5) **MCP integration** - - `peekaboo mcp serve` routes stateful browser calls to the daemon when a Bridge host is available. - - The daemon owns Chrome DevTools MCP process lifetime, selected page state, and snapshot UID state. +Bridge listeners hold an exclusive lease beside their socket for the listener's full lifetime. Publication is atomic: +a host binds and secures a private temporary socket, then publishes it without replacing an owned path. Stale recovery +requires proof that no same-user process has the exact UNIX path open; a failed connection alone is not enough. -6) **Telemetry + tests** - - Unit tests for tracker diffing. - - CLI status snapshot tests. - - MCP server smoke test in daemon mode. +Shutdown removes a socket only when its filesystem identity still matches the listener that created it. Client +connect, read, and write operations are nonblocking and deadline-bound so abandoned connections cannot exhaust the +host. -## Build/Run -- CLI: - - `pnpm run build:cli` -- Daemon (headless target): - - `pnpm run build:swift` (add a dedicated script if needed) -- Status: - - `peekaboo daemon status --json` +## Legacy migration -## Open Questions -- Should daemon auto-install a launchd agent, or only run on-demand? -- Do we want `peekaboo mcp` to spawn a separate daemon or just run in-process (current plan)? -- How aggressive should CGWindowList polling be when AX notifications are quiet? +Older daemons may still occupy Peekaboo.app's `bridge.sock`. Current daemon control detects the host kind before acting: + +- Peekaboo.app is never mistaken for a daemon. +- Auto and manual daemons that advertise conditional stop migrate to `daemon.sock` while preserving lifecycle mode, + polling interval, and idle timeout. +- Migration defers while requests are active. +- Older daemons without conditional stop remain on the legacy socket until they exit or are explicitly stopped. + +## Status + +`peekaboo daemon status --json` reports: + +- PID, start time, lifecycle mode, and socket path +- Bridge protocol version, host kind, and advertised operations +- active requests, last activity, idle timeout, and idle deadline +- Screen Recording, Accessibility, and Automation permissions +- snapshot count and last access +- tracked windows, AX observers, and poll interval +- browser MCP connection, tool count, and detected browsers + +See [`peekaboo daemon`](commands/daemon.md) for command flags and [Bridge host](bridge-host.md) for transport and +security details. diff --git a/docs/homebrew-setup.md b/docs/homebrew-setup.md index 9aeffa1e..a508c270 100644 --- a/docs/homebrew-setup.md +++ b/docs/homebrew-setup.md @@ -149,10 +149,10 @@ cask "peekaboo" do version "2.0.0" sha256 "..." - url "https://github.com/steipete/peekaboo/releases/download/v#{version}/Peekaboo.app.zip" + url "https://github.com/openclaw/Peekaboo/releases/download/v#{version}/Peekaboo.app.zip" name "Peekaboo" desc "Screenshot and AI analysis tool" - homepage "https://github.com/steipete/peekaboo" + homepage "https://github.com/openclaw/Peekaboo" app "Peekaboo.app" end diff --git a/docs/index.md b/docs/index.md index 38c2e48d..621b8915 100644 --- a/docs/index.md +++ b/docs/index.md @@ -27,6 +27,8 @@ Peekaboo is a macOS automation toolkit for humans and agents. It captures pixels - **[Automation](automation.md)** — click, type, scroll, drag, hotkeys, menus, dialogs, windows, Spaces. - **[Agent](commands/agent.md)** — natural-language plan/act loop with provider switching, resumable sessions, and visualizer feedback. - **[MCP](MCP.md)** — expose every Peekaboo tool over stdio for Codex, Claude Code, and Cursor. +- **[Daemon](daemon.md)** — warm CLI runtime, lifecycle, sockets, and migration. +- **[Bridge host](bridge-host.md)** — TCC broker transport, discovery, security, and troubleshooting. ## Reference diff --git a/docs/mcp-testing.md b/docs/mcp-testing.md index 0b86c52a..7ab29694 100644 --- a/docs/mcp-testing.md +++ b/docs/mcp-testing.md @@ -77,7 +77,7 @@ node reloaderoo/dist/bin/reloaderoo.js inspect list-resources -- "$PEEKABOO_BIN" node reloaderoo/dist/bin/reloaderoo.js inspect list-prompts -- "$PEEKABOO_BIN" mcp # Test with AI provider -PEEKABOO_AI_PROVIDERS="anthropic/claude-opus-4-20250514" node reloaderoo/dist/bin/reloaderoo.js inspect call-tool analyze --params '{"image_path": "/tmp/screenshot.png", "question": "What is shown in this image?"}' -- "$PEEKABOO_BIN" mcp +PEEKABOO_AI_PROVIDERS="anthropic/claude-opus-4-8" node reloaderoo/dist/bin/reloaderoo.js inspect call-tool analyze --params '{"image_path": "/tmp/screenshot.png", "question": "What is shown in this image?"}' -- "$PEEKABOO_BIN" mcp ``` #### Proxy Mode (Hot-Reload Development) @@ -110,7 +110,7 @@ claude mcp add peekaboo peekaboo mcp # Add with environment variables claude mcp add peekaboo peekaboo mcp \ - -e PEEKABOO_AI_PROVIDERS="anthropic/claude-opus-4-20250514" + -e PEEKABOO_AI_PROVIDERS="anthropic/claude-opus-4-8" # List configured servers claude mcp list @@ -176,7 +176,7 @@ pnpm run build:cli # Rebuild after changes (or use your local watcher) ```bash # Set AI provider for agent tools -export PEEKABOO_AI_PROVIDERS="anthropic/claude-opus-4-20250514" +export PEEKABOO_AI_PROVIDERS="anthropic/claude-opus-4-8" # Enable debug logging export DEBUG="peekaboo:*" @@ -221,7 +221,7 @@ Test that all tools are properly exposed: // Expected tool: runAgent { "task": "Take a screenshot of the current window", - "provider": "anthropic/claude-opus-4-20250514" + "provider": "anthropic/claude-opus-4-8" } ``` diff --git a/docs/modern-api.md b/docs/modern-api.md index e27976f2..845ea07b 100644 --- a/docs/modern-api.md +++ b/docs/modern-api.md @@ -59,7 +59,7 @@ let response2 = try await generate("Hello", using: .anthropic(.opus4)) let response3 = try await generate("Hello", using: .openai(.custom("ft:gpt-5.5:my-org:abc123"))) // OpenRouter models -let response4 = try await generate("Hello", using: .openRouter("anthropic/claude-3.5-sonnet")) +let response4 = try await generate("Hello", using: .openRouter("anthropic/claude-sonnet-4-6")) // Custom OpenAI-compatible endpoints let response5 = try await generate("Hello", using: .openaiCompatible( @@ -517,7 +517,7 @@ extension PeekabooCLI { return .openai(.gpt55) case let custom where custom.contains("/"): - // OpenRouter format like "anthropic/claude-3.5-sonnet" + // OpenRouter format like "anthropic/claude-sonnet-4-6" return .openRouter(modelId: custom) default: // Try as custom model ID @@ -688,7 +688,7 @@ struct BasicGenerationExample { print("4. OpenRouter model:") let openRouter = try await generate( "Write a haiku about code", - using: .openRouter("anthropic/claude-3.5-sonnet") + using: .openRouter("anthropic/claude-sonnet-4-6") ) print(openRouter) } @@ -922,7 +922,7 @@ struct ToolCallingExample { ### Provider System Modernization - [ ] **Refactor all providers to use modern patterns** - [ ] OpenAI provider with latest API support (GPT-5, o4-mini, etc.) - - [ ] Anthropic provider with Claude 3.5 and tools + - [ ] Anthropic provider with Claude 4.x/Fable and tools - [ ] Add Google AI (Gemini) provider - [ ] Add Mistral AI provider - [ ] Add Groq provider for fast inference diff --git a/docs/permissions.md b/docs/permissions.md index 471e7a17..80b4dc14 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -46,8 +46,8 @@ For build and runtime version details, see [platform-support.md](platform-suppor ## Bridge and subprocess runners `peekaboo permissions status` prints a `Source:` line. If it says `Peekaboo Bridge`, capture and automation -permissions are being checked through the explicit Bridge socket or selected reusable daemon. Grant Screen -Recording and Accessibility to that host process, +permissions are being checked through an explicit socket, the selected reusable daemon, or a healthy Peekaboo.app +fallback. Grant Screen Recording and Accessibility to that host process, or bypass Bridge for local capture only when the caller is known to run in the active Aqua GUI session: ```bash diff --git a/docs/provider.md b/docs/provider.md index fcc6fd75..3278bc62 100644 --- a/docs/provider.md +++ b/docs/provider.md @@ -1,373 +1,15 @@ --- -summary: 'Review Custom AI Provider Configuration guidance' +summary: 'Route legacy provider documentation links to the canonical provider references.' read_when: - - 'planning work related to custom ai provider configuration' - - 'debugging or extending features described here' + - 'following an older link about custom AI provider configuration' --- -# Custom AI Provider Configuration +# Provider configuration -This document explains how to configure AI providers in Peekaboo, including built-ins (OpenAI, Anthropic, Grok/xAI, Gemini) and custom OpenAI-/Anthropic-compatible endpoints. +Provider documentation is maintained in these canonical references: -See also: -- `providers/README.md` for capability comparison and links to provider-specific docs. -- `providers/openai.md`, `providers/anthropic.md`, `providers/grok.md`, `providers/ollama.md` for deep dives and current status. +- [AI providers](providers.md): supported providers, credentials, model selection, and troubleshooting. +- [Configuration](configuration.md): precedence, shared agent settings, environment variables, and paths. +- [`peekaboo config`](commands/config.md): OpenAI- and Anthropic-compatible endpoint configuration. -## Overview - -Peekaboo supports custom AI providers through configuration-based setup. This allows you to: - -- Use OpenRouter to access 300+ models through a unified API -- Connect to specialized providers like Groq, Together AI, Perplexity -- Set up self-hosted AI endpoints -- Override built-in providers with custom endpoints -- Configure multiple endpoints with different models - -## Built-in vs Custom Providers - -### Built-in Providers -- **OpenAI**: GPT-5 family, GPT-4.1, GPT-4o, o4-mini (API key; OAuth tokens are resolved but can be rejected by OpenAI API endpoints if the login client lacks platform API scopes) -- **Anthropic**: Claude 4 / Max / Pro / 3.x (OAuth or API key) -- **Grok (xAI)**: Grok 4, Grok 2 series (API key; `grok` canonical, `xai` alias) -- **Gemini**: Gemini 1.5 family (API key) -- **Ollama**: Local models with tool support - -### Custom Providers -- **OpenRouter**: Unified access to 300+ models -- **Groq**: Ultra-fast inference with LPU technology -- **Together AI**: High-performance open-source models -- **Perplexity**: AI-powered search with citations -- **Self-hosted**: Your own AI endpoints - -## Configuration - -### Provider Schema - -Custom providers are configured in `~/.peekaboo/config.json`: - -```json -{ - "customProviders": { - "openrouter": { - "name": "OpenRouter", - "description": "Access to 300+ models via unified API", - "type": "openai", - "options": { - "baseURL": "https://openrouter.ai/api/v1", - "apiKey": "${OPENROUTER_API_KEY}", - "headers": { - "HTTP-Referer": "https://peekaboo.app", - "X-Title": "Peekaboo" - } - }, - "models": { - "anthropic/claude-3.5-sonnet": { - "name": "Claude 3.5 Sonnet (OpenRouter)", - "maxTokens": 8192, - "supportsTools": true, - "supportsVision": true - }, - "openai/gpt-4": { - "name": "GPT-4 (OpenRouter)", - "maxTokens": 8192, - "supportsTools": true - } - }, - "enabled": true - } - } -} -``` - -### Provider Types - -- **`openai`**: OpenAI-compatible endpoints (Chat Completions API) -- **`anthropic`**: Anthropic-compatible endpoints (Messages API) - -### Environment Variables vs Credentials - -- Peekaboo never copies environment values into files automatically. Env vars are read live and shown as `ready (env)` in `config show/init`. -- Credentials you add manually are stored in `~/.peekaboo/credentials` with `chmod 600`. -- OAuth (OpenAI/Codex, Anthropic Max) stores refresh/access tokens + expiry in the credentials file; no API key is written. -- In `customProviders[*].options.apiKey`, prefer the shell-style `${VAR}` form for env-var references — it is resolved by the runtime that talks to the model. When passing this through a shell command, quote it as `'${VAR}'` so the literal reference is saved. The legacy `{env:VAR}` form remains supported for compatibility. - -```bash -# Set API key (stored after validation) -peekaboo config add openai sk-... -peekaboo config add anthropic sk-ant-... -peekaboo config add grok xai-... -peekaboo config add gemini ya29.... - -# OAuth (no API key stored) -peekaboo config login openai -peekaboo config login anthropic -``` - -Note: OpenAI OAuth currently depends on the scopes granted by OpenAI's OAuth client. If API-backed calls report missing scopes, configure `OPENAI_API_KEY` or run `peekaboo config add openai `. - -## CLI Management - -### Add Provider (custom, OpenAI/Anthropic compatible) - -```bash -peekaboo config add-provider \ - --id openrouter \ - --name "OpenRouter" \ - --type openai \ - --url "https://openrouter.ai/api/v1" \ - --api-key OPENROUTER_API_KEY \ - --discover-models -``` - -### List Providers - -```bash -# Custom providers only -peekaboo config list-providers - -# Include built-in providers -peekaboo config list-providers --include-built-in -``` - -### Test Connection - -```bash -peekaboo config test-provider openrouter -``` - -### List Models - -```bash -# Show configured models -peekaboo config models-provider openrouter - -# Refresh from API -peekaboo config models-provider openrouter --refresh -``` - -### Remove Provider - -```bash -peekaboo config remove-provider openrouter -``` - -## Usage with Agent - -Once configured, use custom providers with the agent command: - -```bash -# Use OpenRouter's Claude 3.5 Sonnet -peekaboo agent "take a screenshot" --model openrouter/anthropic/claude-3.5-sonnet - -# Use Groq's Llama 3 -peekaboo agent "click the button" --model groq/llama3-70b-8192 - -# Built-in providers work unchanged -peekaboo agent "analyze image" --model anthropic/claude-opus-4 -``` - -## Popular Provider Examples - -### OpenRouter - -```bash -peekaboo config add-provider \ - --id openrouter \ - --name "OpenRouter" \ - --type openai \ - --url "https://openrouter.ai/api/v1" \ - --api-key OPENROUTER_API_KEY - -peekaboo config add openai or-your-key-here -``` - -### Groq - -```bash -peekaboo config add-provider \ - --id groq \ - --name "Groq" \ - --type openai \ - --url "https://api.groq.com/openai/v1" \ - --api-key GROQ_API_KEY - -peekaboo config add grok gsk-your-key-here -``` - -### Together AI - -```bash -peekaboo config add-provider \ - --id together \ - --name "Together AI" \ - --type openai \ - --url "https://api.together.xyz/v1" \ - --api-key TOGETHER_API_KEY - -peekaboo config set-credential TOGETHER_API_KEY your-key-here -``` - -### Self-hosted - -```bash -peekaboo config add-provider \ - --id myserver \ - --name "My AI Server" \ - --type openai \ - --url "https://ai.company.com/v1" \ - --api-key MY_API_KEY - -peekaboo config set-credential MY_API_KEY your-key-here -``` - -## Provider Configuration Options - -### Headers - -Custom headers for API requests: - -```json -"headers": { - "HTTP-Referer": "https://peekaboo.app", - "X-Title": "Peekaboo", - "Authorization": "Bearer custom-token" -} -``` - -### Model Definitions - -Define available models with capabilities: - -```json -"models": { - "model-id": { - "name": "Display Name", - "maxTokens": 8192, - "supportsTools": true, - "supportsVision": false, - "parameters": { - "temperature": "0.7", - "top_p": "0.9" - } - } -} -``` - -### Provider Options - -```json -"options": { - "baseURL": "https://api.provider.com/v1", - "apiKey": "${API_KEY}", - "timeout": 30, - "retryAttempts": 3, - "headers": {}, - "defaultParameters": {} -} -``` - -## Mac App Integration - -The Mac app settings provide a GUI for managing custom providers: - -1. **Settings → AI Providers** -2. **Add Custom Provider** button -3. Provider configuration form with connection testing -4. Model discovery and selection -5. Enable/disable providers - -## Troubleshooting - -### Connection Issues - -```bash -# Test provider connection -peekaboo config test-provider openrouter - -# Check configuration -peekaboo config show --effective - -# Validate config syntax -peekaboo config validate -``` - -### Authentication Errors - -- Verify API key is set: `peekaboo config show --effective` -- Check credentials file permissions: `ls -la ~/.peekaboo/credentials` -- Test API key with provider's documentation - -### Model Not Found - -- List available models: `peekaboo config models-provider openrouter` -- Refresh model list: `peekaboo config models-provider openrouter --refresh` -- Check provider documentation for model names - -## Security Considerations - -- API keys are stored separately in `~/.peekaboo/credentials` (chmod 600) -- Never commit API keys to configuration files -- Use environment variable references: `${API_KEY}` in JSON, or `'${API_KEY}'` in shell commands -- Rotate API keys regularly -- Use least-privilege API keys when available - -## Advanced Usage - -### Model Selection Priority - -```bash -# Provider string format: provider-id/model-path -peekaboo agent "task" --model openrouter/anthropic/claude-3.5-sonnet -peekaboo agent "task" --model groq/llama3-70b-8192 -peekaboo agent "task" --model myserver/custom-model -``` - -### Fallback Configuration - -Configure multiple providers for redundancy: - -```json -"aiProviders": { - "providers": "openrouter/anthropic/claude-3.5-sonnet,anthropic/claude-opus-4,openai/gpt-4.1" -} -``` - -### Cost Optimization - -Use OpenRouter's smart routing for cost optimization: - -```json -"openrouter": { - "options": { - "headers": { - "X-Title": "Peekaboo Cost-Optimized" - } - } -} -``` - -## File Locations - -- **Configuration**: `~/.peekaboo/config.json` -- **Credentials**: `~/.peekaboo/credentials` -- **Logs**: `~/.peekaboo/logs/peekaboo.log` - -## API Compatibility - -### OpenAI-Compatible Providers - -Support standard OpenAI Chat Completions API: -- Request/response format matches OpenAI -- Tool calling support varies by provider -- Vision capabilities vary by model - -### Anthropic-Compatible Providers - -Support Anthropic Messages API: -- Different request/response format -- System prompts handled separately -- Native tool calling support - -For implementation details, see: -- `Core/PeekabooCore/Sources/PeekabooCore/Configuration/` -- `Core/PeekabooCore/Sources/PeekabooCore/AI/` +Keeping the schemas and examples in those pages avoids conflicting model lists and stale configuration samples. diff --git a/docs/providers.md b/docs/providers.md index 9d46fb80..fbf9d67c 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -67,6 +67,10 @@ peekaboo agent --model lmstudio/openai/gpt-oss-120b "summarize this window" Defaults come from `agent.defaultModel` in `~/.peekaboo/config.json`. Anthropic defaults stay on Opus 4.8 for zero-retention compatibility; select Fable explicitly when your Anthropic organization allows it. Set a per-project default with `PEEKABOO_AGENT_MODEL`. +The app and CLI share `agent.temperature` and `agent.maxTokens`. Peekaboo clamps those requests to provider +capabilities; Fable supports a 1M context window and up to 128K output. See +[configuration.md](configuration.md#agent-generation-settings). + ## Tool calling The agent expects tool-calling capable models. If your provider doesn't support it (some tiny local models), Peekaboo falls back to a structured-output prompt — slower and less reliable. Stick with mainstream tool-calling models for production runs. diff --git a/docs/providers/README.md b/docs/providers/README.md index 393bc642..dc9000e4 100644 --- a/docs/providers/README.md +++ b/docs/providers/README.md @@ -1,5 +1,5 @@ --- -summary: 'Index of AI provider docs (OpenAI, Anthropic, Gemini, MiniMax, Grok, Ollama)' +summary: 'Index of AI provider docs (OpenAI, Anthropic, Gemini, MiniMax, Grok, Ollama).' read_when: - 'choosing or configuring AI providers for Peekaboo' - 'looking for provider-specific plans or status' @@ -8,7 +8,7 @@ read_when: # Providers index - **OpenAI** — `openai.md`: architecture, migration status, and guidance for adding models. -- **Anthropic** — `anthropic.md`: plan/status, streaming/tool notes, and Claude CLI examples. +- **Anthropic** — `anthropic.md`: Fable/Claude models, output limits, generation settings, and credentials. - **Google** — configured with `GEMINI_API_KEY`; supports Gemini 3.1 Pro Preview and Gemini 3 Flash. - **MiniMax** — configured with `MINIMAX_API_KEY`; supports MiniMax M2.7 through the Anthropic-compatible API. - **MiniMax China** — use `minimax-cn/...` with `MINIMAX_CN_API_KEY` or the shared `MINIMAX_API_KEY`; routes to `api.minimaxi.com`. @@ -22,8 +22,8 @@ configuration syntax, and environment variable reference. | Provider | Tools | Vision | Streaming | Local/offline | Auth | | --- | --- | --- | --- | --- | --- | -| OpenAI | Yes (function/tool calling) | Yes (gpt-4o/4.1) | Yes | No | API key | -| Anthropic | Yes | Yes (Sonnet/Opus vision) | Yes (SSE) | No | API key or OAuth (Claude Pro/Max) | +| OpenAI | Yes (function/tool calling) | Yes | Yes | No | API key or OAuth | +| Anthropic | Yes | Yes | Model-dependent; Fable/Opus 4.8 currently non-streaming | No | API key or OAuth (Claude Pro/Max) | | Google | Yes | Yes | Yes | No | API key | | MiniMax | Yes | No | Yes | No | API key | | MiniMax China | Yes | No | Yes | No | API key | diff --git a/docs/providers/anthropic.md b/docs/providers/anthropic.md index 8c3575c8..b663b006 100644 --- a/docs/providers/anthropic.md +++ b/docs/providers/anthropic.md @@ -1,45 +1,57 @@ --- -summary: 'Anthropic provider plan, status, and usage examples for Peekaboo' +summary: 'Configure and use Anthropic Claude models in Peekaboo.' read_when: - - 'planning or extending Anthropic/Claude support' - - 'debugging Anthropic provider behavior or SDK wiring' - - 'needing CLI examples for Claude models' + - 'selecting Claude models or Anthropic credentials' + - 'debugging Fable limits, generation settings, or compatible endpoints' --- -# Anthropic in Peekaboo +# Anthropic Claude -## Overview -Peekaboo ships a native Swift integration for Anthropic Claude models so agents and CLI commands can use Claude alongside OpenAI or local providers. The goal is parity with our OpenAI architecture while avoiding external SDK dependencies. +Peekaboo uses Tachikoma's native Anthropic Messages integration for API-key and OAuth-backed Claude models, including +tool calls, vision, thinking blocks, and provider-specific event handling. -## SDK options (evaluated) -- Community Swift SDKs (AnthropicSwiftSDK, SwiftAnthropic): featureful but add external deps and may lag API updates. -- Official TypeScript SDK: always current but would require a Node bridge and add overhead. -- **Chosen**: custom Swift implementation to match Peekaboo’s protocol-based model layer and keep dependencies lean. +## Current models -## Implementation status (verification) -- Core types (`AnthropicTypes`, request/response/content blocks, tool definitions, error types) and `AnthropicModel` conform to the shared `ModelInterface`. -- Streaming is fully implemented with SSE parsing for all Claude events (`message_start`, `content_block_*`, `message_delta/stop`) and tool streaming. -- Tool/function calling maps Peekaboo tool schemas to Anthropic `input_schema`, supports `tool_use`, and converts results back to Peekaboo tool envelopes. -- Endpoint and headers: `POST https://api.anthropic.com/v1/messages` with `x-api-key` and `anthropic-version: 2023-06-01`. +| Model | Context | Max output | Notes | +| --- | ---: | ---: | --- | +| `claude-fable-5` | 1M | 128K | Explicit opt-in for long-horizon agent work. | +| `claude-opus-4-8` | 1M | 128K | Default Anthropic choice; compatible with zero-retention organizations. | +| `claude-sonnet-4-6` | 1M | 64K | Balanced speed and capability. | +| `claude-haiku-4-5` | 200K | 64K | Fast, lower-cost tasks. | + +Fable is not the automatic Anthropic default. Select it explicitly when your Anthropic organization allows the model: -## Usage examples ```bash -# Use Claude 3 Opus for complex tasks -peekaboo agent "Analyze the UI structure of Safari" --model claude-3-opus-20240229 - -# Balanced performance with Claude 3.5 Sonnet -peekaboo agent "Click the Submit button" --model claude-3-5-sonnet-latest - -# Fast responses with Claude 3 Haiku -peekaboo agent "What windows are currently open?" --model claude-3-haiku-20240307 - -# Configure Anthropic as default -export ANTHROPIC_API_KEY=sk-ant-... -export PEEKABOO_AI_PROVIDERS="anthropic/claude-3-opus-latest,openai/gpt-4.1" -peekaboo agent "Help me organize my desktop" +peekaboo agent --model claude-fable-5 "inspect this app and summarize its workflow" ``` -## Next steps / maintenance -- Keep parity with Anthropic model/version names as they ship. -- Add regression tests for tool streaming and error mapping when new event types appear. -- Re-run the verification checklist when upgrading the API version header. +## Credentials + +```bash +peekaboo config add anthropic sk-ant-... +# or +peekaboo config login anthropic +``` + +Environment credentials remain available for automation: + +```bash +ANTHROPIC_API_KEY=sk-ant-... \ + peekaboo agent --model claude-opus-4-8 "describe the current window" +``` + +## Generation settings + +The app and CLI read the same `agent.temperature` and `agent.maxTokens` values from +`~/.peekaboo/config.json`. Peekaboo clamps the token request to the selected model's output capability and strips +sampling parameters from current adaptive-thinking models when the Anthropic API does not accept them. + +Fable and Opus 4.8 currently use the non-streaming generation path so signed thinking history and rollback behavior +remain valid. Agent progress events still report start, assistant output, tool activity, completion, and errors. + +Anthropic-compatible custom providers inherit known Fable capability limits when their model ID is +`claude-fable-5` (including provider-qualified forms). A custom model's explicit `maxTokens` value takes precedence +for other IDs. + +See [configuration.md](../configuration.md) for the shared settings schema and [providers.md](../providers.md) for +the full provider catalog. diff --git a/docs/quickstart.md b/docs/quickstart.md index ad296b8a..d3ad1fc5 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -40,6 +40,9 @@ If you are running from SSH, a LaunchAgent, Codex, or another background launchd host with Screen Recording permission. Local capture-engine overrides are for debugging and can produce wallpaper-only screenshots in background sessions. +Normal CLI automation uses a healthy reusable daemon, then a capable Peekaboo.app Bridge host, and otherwise starts +the daemon on demand. `peekaboo bridge status --verbose` shows the selected runtime. + ## 3. Inspect the UI `see` returns a structured map of clickable elements with stable IDs: diff --git a/docs/spec.md b/docs/spec.md index f968ad7d..66747389 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -119,7 +119,7 @@ Common helpers: - Lives under `Apps/CLI/Sources/PeekabooCLI/Commands/AI/AgentCommand.swift`. - Supports natural-language tasks, `--dry-run`, `--max-steps`, `--resume` / `--resume-session`, `--list-sessions`, `--no-cache`, and audio options. - Output modes (`minimal`, `compact`, `enhanced`, `quiet`, `verbose`) adapt to terminal capabilities via `TerminalDetector`. -- Uses Tachikoma to call GPT‑5.5, Claude Opus 4.7, or Gemini 3.1. Session metadata is stored via `AgentSessionInfo` for resume flows. +- Uses Tachikoma to call GPT-5.5, Claude Fable 5/Opus 4.8, or Gemini 3.1. Session metadata is stored via `AgentSessionInfo` for resume flows. ### 7.2 MCP (`peekaboo mcp`) - `serve` starts `PeekabooMCPServer` over stdio/HTTP/SSE. diff --git a/docs/testing/tools.md b/docs/testing/tools.md index 553639eb..958d2d9b 100644 --- a/docs/testing/tools.md +++ b/docs/testing/tools.md @@ -213,7 +213,7 @@ The following subsections spell out the concrete steps, required Playground surf - **2025-12-17 CLI evidence**: `.artifacts/playground-tools/20251217-192349-clipboard-{save-original,set-file,get-file-text,set-image,get-image,restore-original}.json` plus exported `/tmp/peekaboo-clipboard-out.png`. #### `config` -- **Focus**: `config show`, `config validate`, `config models`. +- **Focus**: `config show`, `config validate`, `config models-provider`. - **Steps**: 1. Snapshot `~/.peekaboo/config.json` (read-only). 2. Run `polter peekaboo -- config validate --verbose`. diff --git a/docs/tui.md b/docs/tui.md index 867e8c6e..2366876b 100644 --- a/docs/tui.md +++ b/docs/tui.md @@ -32,7 +32,7 @@ Provides rich formatting with improved typography: - Contextual progress information ``` -👻 Peekaboo Agent v3.1.1 using Claude Opus 4.7 (main/abc123, 2026-05-11) +👻 Peekaboo Agent v3.5.0 using Claude Fable 5 (main/abc123, 2026-06-12) 👁 see screen ✅ Captured screen (dialog detected, 5 elements) (1.2s) 🖱 click 'OK' ✅ Clicked 'OK' in dialog (0.8s) diff --git a/scripts/release-binaries.sh b/scripts/release-binaries.sh index 3d73f06d..b8180f52 100755 --- a/scripts/release-binaries.sh +++ b/scripts/release-binaries.sh @@ -368,13 +368,13 @@ peekaboo image --app Safari --path screenshot.png # List applications peekaboo list apps -# Analyze image with AI -peekaboo analyze image.png "What is shown?" +# Capture and analyze a window with AI +peekaboo image --app Safari --analyze "What is shown?" \`\`\` ## Documentation -Full documentation: https://github.com/steipete/peekaboo +Full documentation: https://github.com/openclaw/Peekaboo ## License