feat: agent install path — paste-able prompt + install.json contract + llms.txt - #12
Open
todddickerson wants to merge 1 commit into
Open
feat: agent install path — paste-able prompt + install.json contract + llms.txt#12todddickerson wants to merge 1 commit into
todddickerson wants to merge 1 commit into
Conversation
…+ llms.txt Lets a coding agent (Claude Code, OpenClaw, Cursor, Codex, Hermes) install and verify FunButton unattended, then hand off the three macOS TCC grants a human must do by hand (no agent can grant them). - AGENT-INSTALL.md: copy-paste, model-agnostic prompt. brew -> curl -> manual with success/failure detection; a 4-check VERIFY block (app present, no quarantine, version == latest, launch log shows Whisper + llama-server up); explicit STOP-and-hand-off for Microphone/Accessibility/Input Monitoring with exact panes; surfaces the ~1.1 GB first-run model download. - apps/web/app/install.json: machine-readable contract (schema_version 1). Dynamic edge route resolving latest version + DMG sha256 live from the GitHub API digest, with a last-known-good fallback. Methods, TCC perms, model size, verify block. - apps/web/app/llms.txt: discovery surface per the llms.txt convention. - apps/web/app/page.tsx: secondary "installing with a coding agent?" card (copy button + links). Brew stays the primary human path. - README.md: "Install with a coding agent" section cross-linking AGENT-INSTALL.md. Proved end to end by following AGENT-INSTALL.md verbatim on the Mac Studio: brew cask install, no quarantine, version 0.1.8, launch log shows "embedded STT model loaded" + "llama-server ready". /install.json and /llms.txt serve 200 with correct content-type. All gates green (cargo fmt/clippy/build/ test 78 passed, worker tsc, web build+eslint, crash-guard grep doc-only). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reviewer's GuideAdds an agent-focused installation path for FunButton, including a copy-paste prompt, machine-readable install contract, and LLM discovery surface, and surfaces these via the web landing page and README. Sequence diagram for resolving install.json via GitHub APIsequenceDiagram
participant Agent
participant InstallJsonRoute as install.json_route
participant GitHubAPI as GitHub_API
Agent->>InstallJsonRoute: GET /install.json
activate InstallJsonRoute
InstallJsonRoute->>InstallJsonRoute: resolveRelease()
activate InstallJsonRoute
InstallJsonRoute->>GitHubAPI: fetch /repos/todddickerson/funbutton/releases/latest
activate GitHubAPI
GitHubAPI-->>InstallJsonRoute: Release JSON
deactivate GitHubAPI
InstallJsonRoute->>InstallJsonRoute: pickDmg(rel)
InstallJsonRoute->>InstallJsonRoute: sha256From(dmg.digest)
InstallJsonRoute-->>InstallJsonRoute: resolved release | null
deactivate InstallJsonRoute
alt resolved release
InstallJsonRoute->>InstallJsonRoute: buildContract(resolved)
else no release or error
InstallJsonRoute->>InstallJsonRoute: buildContract(FALLBACK)
end
InstallJsonRoute-->>Agent: 200 JSON (schema_version 1, latest_version, download, install_methods, verify)
deactivate InstallJsonRoute
Sequence diagram for the new agent install UI copy promptsequenceDiagram
actor User
participant Browser
participant AgentInstall as AgentInstall_component
participant CopyButton as CopyButton_component
participant Clipboard as navigator.clipboard
User->>Browser: Open landing page
Browser->>AgentInstall: render AgentInstall()
AgentInstall->>CopyButton: render CopyButton(text=AGENT_PROMPT, label="copy prompt")
User->>CopyButton: click button
activate CopyButton
CopyButton->>Clipboard: writeText(text)
alt writeText success
Clipboard-->>CopyButton: Promise resolved
CopyButton->>CopyButton: setCopied(true)
CopyButton->>User: label rendered as "copied" (~1.5s)
CopyButton->>CopyButton: setCopied(false)
else writeText throws
Clipboard-->>CopyButton: error
CopyButton->>User: prompt remains selectable for manual copy
end
deactivate CopyButton
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In the install.json contract, the
manualinstall method setsclears_quarantine: falseeven though its commands includexattr -dr com.apple.quarantineon the app; consider aligning this flag with the behavior or clarifying that the clearance is manual rather than automatic. - The new CopyButton component relies directly on
navigator.clipboardwithout a feature check; adding a guard for environments where the Clipboard API is unavailable or restricted (and possibly a non-async fallback) would make the button behavior more predictable across browsers and contexts. - The install.json route mixes a fairly large static schema with dynamic release resolution logic in a single file; extracting the static contract shape and helper types/constants into a separate module could improve readability and make future schema evolution easier to manage.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the install.json contract, the `manual` install method sets `clears_quarantine: false` even though its commands include `xattr -dr com.apple.quarantine` on the app; consider aligning this flag with the behavior or clarifying that the clearance is manual rather than automatic.
- The new CopyButton component relies directly on `navigator.clipboard` without a feature check; adding a guard for environments where the Clipboard API is unavailable or restricted (and possibly a non-async fallback) would make the button behavior more predictable across browsers and contexts.
- The install.json route mixes a fairly large static schema with dynamic release resolution logic in a single file; extracting the static contract shape and helper types/constants into a separate module could improve readability and make future schema evolution easier to manage.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The "agent install" path Todd asked for on 2026-08-17 — "give an 'agent prompt' as well for claude/openclaw/hermes/etc easy install via agents" — which PR #11 (brew cask + curl installer) didn't ship. This adds the agent-facing surface: a copy-paste prompt, a machine-readable install contract, and an
llms.txtdiscovery file, so a coding agent (Claude Code, OpenClaw, Cursor, Codex, Hermes) can install and verify FunButton for its user and then hand off the macOS permission grants a human must do by hand.Changes
AGENT-INSTALL.md(repo root) — the headline artifact. A model-agnostic, copy-paste prompt: preferred order brew → curl → manual (each with exact commands + success/failure detection); a four-check VERIFY block (app present, nocom.apple.quarantine, version == latest, launch log shows Whisper + llama-server up); an explicit STOP-and-hand-off for Microphone / Accessibility / Input Monitoring with the exact System Settings panes (no agent can grant TCC permissions — the doc says so instead of faking it); and the ~1.1 GB first-run model download surfaced up front. No emoji headings, no slop, neverspctl --master-disable.apps/web/app/install.json/route.ts— machine-readable contract athttps://funbutton.ai/install.json(schema_version: "1"). Dynamic edge route: resolves the latest version + DMG SHA-256 live from the GitHub APIdigestfield (same source as/download), so it never drifts per release; falls back to a last-known-good pin if the API is down. Includes platform/arch, install methods + commands, required TCC permissions (permissions_grantable_by_agent: false), model size + location, and averifyblock.apps/web/app/llms.txt/route.ts— discovery surface athttps://funbutton.ai/llms.txt(llmstxt.org convention): terse plain-text what/how/permissions + pointers to/install.jsonand/install.sh.apps/web/app/page.tsx— a compact, deliberately secondary "installing with a coding agent?" card under the numbered install methods (copy-to-clipboard prompt + links to/install.jsonand/llms.txt). Brew stays the loud primary path for humans. Text-label copy button (terminal aesthetic, no emoji, no new dep).README.md— "Install with a coding agent" subsection cross-linkingAGENT-INSTALL.md+ the two endpoints.PROGRESS.md— new entry.End-to-end proof (followed AGENT-INSTALL.md verbatim, on the Mac Studio)
Uninstalled first, then ran my own doc's steps as if I were the agent. No faked screenshots — logs,
xattr, and exit codes only.Install (method 1, brew cask):
Verify (all four pass):
(Models were already cached from a prior run, so no 1.1 GB re-download this pass — the doc warns about that download for a genuinely first run.)
Live gotcha caught + doc confirmed correct: brew auto-updated 6.0.17 → 6.0.18 mid-run, which adds a new tap-trust gate. I tested the true fresh-user path — removed funbutton from
~/.homebrew/trust.json, uninstalled, reinstalled:So the doc's command works with no
brew truststep. trust.json restored to its original state.Endpoints serve (local prod
next start— NOT deployed to prod)Gates
cargo fmt --check: cleancargo clippy --release --all-targets -- -D warnings: cleancargo build --release: ok (Finished release in 6m 56s)cargo test --release --lib:test result: ok. 78 passed; 0 failed; 7 ignoredrdev|TSMGetInputSource|TISCopy|UCKeyTranslate): doc comments onlyapps/webnext build(TypeScript) + eslint: cleanapps/workertsc --noEmit: cleanvendor/dylibs symlinked from the main checkout for the build, sincevendor/is gitignored.)Not done (per instructions)
No release cut. Not deployed to production. No Telegram/Slack — Todd handles comms.
🤖 Generated with Claude Code
Summary by Sourcery
Enable coding agents to install and verify FunButton while clearly handing macOS security permissions back to the user.
New Features:
/install.jsonwith release metadata, installation methods, permissions, model requirements, and verification checks.llms.txtdiscovery endpoint for agent-friendly installation information.Enhancements:
Documentation:
Tests:
Chores: