Mac: add summarize tool

This commit is contained in:
Peter Steinberger
2025-12-19 17:46:49 +01:00
parent 2bc0c57f18
commit 47a1774dc0
2 changed files with 153 additions and 134 deletions

View File

@@ -75,139 +75,154 @@ private enum InstallState: Equatable {
// MARK: - View
struct ToolsSettings: View {
private let tools: [ToolEntry] = [
ToolEntry(
id: "mcporter",
name: "🧳 mcporter",
url: URL(string: "https://github.com/steipete/mcporter")!,
description: "MCP runtime/CLI to discover servers, run tools, and sync configs across AI clients.",
method: .node(package: "mcporter", binary: "mcporter"),
kind: .tool),
ToolEntry(
id: "peekaboo",
name: "🫣 Peekaboo",
url: URL(string: "https://github.com/steipete/Peekaboo")!,
description: "Lightning-fast macOS screenshots with AI vision helpers for step-by-step automation.",
method: .brew(formula: "steipete/tap/peekaboo", binary: "peekaboo"),
kind: .tool),
ToolEntry(
id: "camsnap",
name: "📸 camsnap",
url: URL(string: "https://github.com/steipete/camsnap")!,
description: "One command to grab frames, clips, or motion alerts from RTSP/ONVIF cameras.",
method: .brew(formula: "steipete/tap/camsnap", binary: "camsnap"),
kind: .tool),
ToolEntry(
id: "oracle",
name: "🧿 oracle",
url: URL(string: "https://github.com/steipete/oracle")!,
description: "Runs OpenAI-ready agent workflows from the CLI with session replay and browser control.",
method: .node(package: "@steipete/oracle", binary: "oracle"),
kind: .tool),
ToolEntry(
id: "qmd",
name: "🔎 qmd",
url: URL(string: "https://github.com/tobi/qmd")!,
description: "Hybrid markdown search (BM25 + vectors + rerank) with an MCP server for agents.",
method: .node(package: "https://github.com/tobi/qmd", binary: "qmd"),
kind: .tool),
ToolEntry(
id: "eightctl",
name: "🛏️ eightctl",
url: URL(string: "https://github.com/steipete/eightctl")!,
description: "Control your sleep, from the terminal.",
method: .go(module: "github.com/steipete/eightctl/cmd/eightctl@latest", binary: "eightctl"),
kind: .tool),
ToolEntry(
id: "imsg",
name: "💬 imsg",
url: URL(string: "https://github.com/steipete/imsg")!,
description: "Send, read, stream iMessage & SMS.",
method: .go(module: "github.com/steipete/imsg/cmd/imsg@latest", binary: "imsg"),
kind: .tool),
ToolEntry(
id: "wacli",
name: "🗃 wacli",
url: URL(string: "https://github.com/steipete/wacli")!,
description: "WhatsApp CLI: sync, search, send.",
method: .go(module: "github.com/steipete/wacli/cmd/wacli@latest", binary: "wacli"),
kind: .tool),
ToolEntry(
id: "spotify-player",
name: "🎵 spotify-player",
url: URL(string: "https://github.com/aome510/spotify-player")!,
description: "Terminal Spotify client to queue, search, and control playback without leaving chat.",
method: .brew(formula: "spotify_player", binary: "spotify_player"),
kind: .tool),
ToolEntry(
id: "sonoscli",
name: "🔊 sonoscli",
url: URL(string: "https://github.com/steipete/sonoscli")!,
description: "Control Sonos speakers (discover, status, play/pause, volume, grouping) from scripts.",
method: .go(module: "github.com/steipete/sonoscli/cmd/sonos@latest", binary: "sonos"),
kind: .tool),
ToolEntry(
id: "blucli",
name: "🫐 blucli",
url: URL(string: "https://github.com/steipete/blucli")!,
description: "Play, group, and automate BluOS players from scripts.",
method: .go(module: "github.com/steipete/blucli/cmd/blu@latest", binary: "blu"),
kind: .tool),
ToolEntry(
id: "sag",
name: "🗣️ sag",
url: URL(string: "https://github.com/steipete/sag")!,
description: "ElevenLabs speech with mac-style say UX; streams to speakers by default.",
method: .brew(formula: "steipete/tap/sag", binary: "sag"),
kind: .tool),
ToolEntry(
id: "openhue-cli",
name: "💡 OpenHue CLI",
url: URL(string: "https://github.com/openhue/openhue-cli")!,
description: "Control Philips Hue lights from scripts—scenes, dimming, and automations.",
method: .brew(formula: "openhue/cli/openhue-cli", binary: "openhue"),
kind: .tool),
ToolEntry(
id: "openai-whisper",
name: "🎙 OpenAI Whisper",
url: URL(string: "https://github.com/openai/whisper")!,
description: "Local speech-to-text for quick dictation and voicemail transcripts.",
method: .brew(formula: "openai-whisper", binary: "whisper"),
kind: .tool),
ToolEntry(
id: "gog",
name: "📮 gog",
url: URL(string: "https://github.com/steipete/gogcli")!,
description: "Google Suite CLI: Gmail, Calendar, Drive, Contacts.",
method: .brew(formula: "steipete/tap/gogcli", binary: "gog"),
kind: .tool),
ToolEntry(
id: "gemini-cli",
name: " Gemini CLI",
url: URL(string: "https://github.com/google-gemini/gemini-cli")!,
description: "Google Gemini models from the terminal for fast Q&A and web-grounded summaries.",
method: .brew(formula: "gemini-cli", binary: "gemini"),
kind: .tool),
ToolEntry(
id: "bird",
name: "🐦 bird",
url: URL(string: "https://github.com/steipete/bird")!,
description: "Fast X/Twitter CLI to tweet, reply, read threads, and search without a browser.",
method: .pnpm(
repoPath: "\(NSHomeDirectory())/Projects/bird",
script: "binary",
binary: "bird"),
kind: .tool),
ToolEntry(
id: "agent-tools",
name: "🧰 agent-tools",
url: URL(string: "https://github.com/badlogic/agent-tools")!,
description: "Collection of utilities and scripts tuned for autonomous agents and MCP clients.",
method: .gitClone(
url: "https://github.com/badlogic/agent-tools.git",
destination: "\(NSHomeDirectory())/agent-tools"),
kind: .tool),
]
private let tools: [ToolEntry] = Self.makeTools()
static var toolIDsForTests: [String] {
makeTools().map(\.id)
}
private static func makeTools() -> [ToolEntry] {
[
ToolEntry(
id: "mcporter",
name: "🧳 mcporter",
url: URL(string: "https://github.com/steipete/mcporter")!,
description: "MCP runtime/CLI to discover servers, run tools, and sync configs across AI clients.",
method: .node(package: "mcporter", binary: "mcporter"),
kind: .tool),
ToolEntry(
id: "peekaboo",
name: "🫣 Peekaboo",
url: URL(string: "https://github.com/steipete/Peekaboo")!,
description: "Lightning-fast macOS screenshots with AI vision helpers for step-by-step automation.",
method: .brew(formula: "steipete/tap/peekaboo", binary: "peekaboo"),
kind: .tool),
ToolEntry(
id: "camsnap",
name: "📸 camsnap",
url: URL(string: "https://github.com/steipete/camsnap")!,
description: "One command to grab frames, clips, or motion alerts from RTSP/ONVIF cameras.",
method: .brew(formula: "steipete/tap/camsnap", binary: "camsnap"),
kind: .tool),
ToolEntry(
id: "oracle",
name: "🧿 oracle",
url: URL(string: "https://github.com/steipete/oracle")!,
description: "Runs OpenAI-ready agent workflows from the CLI with session replay and browser control.",
method: .node(package: "@steipete/oracle", binary: "oracle"),
kind: .tool),
ToolEntry(
id: "summarize",
name: "🧾 summarize",
url: URL(string: "https://github.com/steipete/summarize")!,
description: "Link → clean text → summary (web pages, YouTube, and local/remote files).",
method: .brew(formula: "steipete/tap/summarize", binary: "summarize"),
kind: .tool),
ToolEntry(
id: "qmd",
name: "🔎 qmd",
url: URL(string: "https://github.com/tobi/qmd")!,
description: "Hybrid markdown search (BM25 + vectors + rerank) with an MCP server for agents.",
method: .node(package: "https://github.com/tobi/qmd", binary: "qmd"),
kind: .tool),
ToolEntry(
id: "eightctl",
name: "🛏 eightctl",
url: URL(string: "https://github.com/steipete/eightctl")!,
description: "Control your sleep, from the terminal.",
method: .go(module: "github.com/steipete/eightctl/cmd/eightctl@latest", binary: "eightctl"),
kind: .tool),
ToolEntry(
id: "imsg",
name: "💬 imsg",
url: URL(string: "https://github.com/steipete/imsg")!,
description: "Send, read, stream iMessage & SMS.",
method: .go(module: "github.com/steipete/imsg/cmd/imsg@latest", binary: "imsg"),
kind: .tool),
ToolEntry(
id: "wacli",
name: "🗃️ wacli",
url: URL(string: "https://github.com/steipete/wacli")!,
description: "WhatsApp CLI: sync, search, send.",
method: .go(module: "github.com/steipete/wacli/cmd/wacli@latest", binary: "wacli"),
kind: .tool),
ToolEntry(
id: "spotify-player",
name: "🎵 spotify-player",
url: URL(string: "https://github.com/aome510/spotify-player")!,
description: "Terminal Spotify client to queue, search, and control playback without leaving chat.",
method: .brew(formula: "spotify_player", binary: "spotify_player"),
kind: .tool),
ToolEntry(
id: "sonoscli",
name: "🔊 sonoscli",
url: URL(string: "https://github.com/steipete/sonoscli")!,
description: "Control Sonos speakers (discover, status, play/pause, volume, grouping) from scripts.",
method: .go(module: "github.com/steipete/sonoscli/cmd/sonos@latest", binary: "sonos"),
kind: .tool),
ToolEntry(
id: "blucli",
name: "🫐 blucli",
url: URL(string: "https://github.com/steipete/blucli")!,
description: "Play, group, and automate BluOS players from scripts.",
method: .go(module: "github.com/steipete/blucli/cmd/blu@latest", binary: "blu"),
kind: .tool),
ToolEntry(
id: "sag",
name: "🗣 sag",
url: URL(string: "https://github.com/steipete/sag")!,
description: "ElevenLabs speech with mac-style say UX; streams to speakers by default.",
method: .brew(formula: "steipete/tap/sag", binary: "sag"),
kind: .tool),
ToolEntry(
id: "openhue-cli",
name: "💡 OpenHue CLI",
url: URL(string: "https://github.com/openhue/openhue-cli")!,
description: "Control Philips Hue lights from scripts—scenes, dimming, and automations.",
method: .brew(formula: "openhue/cli/openhue-cli", binary: "openhue"),
kind: .tool),
ToolEntry(
id: "openai-whisper",
name: "🎙 OpenAI Whisper",
url: URL(string: "https://github.com/openai/whisper")!,
description: "Local speech-to-text for quick dictation and voicemail transcripts.",
method: .brew(formula: "openai-whisper", binary: "whisper"),
kind: .tool),
ToolEntry(
id: "gog",
name: "📮 gog",
url: URL(string: "https://github.com/steipete/gogcli")!,
description: "Google Suite CLI: Gmail, Calendar, Drive, Contacts.",
method: .brew(formula: "steipete/tap/gogcli", binary: "gog"),
kind: .tool),
ToolEntry(
id: "gemini-cli",
name: "♊️ Gemini CLI",
url: URL(string: "https://github.com/google-gemini/gemini-cli")!,
description: "Google Gemini models from the terminal for fast Q&A and web-grounded summaries.",
method: .brew(formula: "gemini-cli", binary: "gemini"),
kind: .tool),
ToolEntry(
id: "bird",
name: "🐦 bird",
url: URL(string: "https://github.com/steipete/bird")!,
description: "Fast X/Twitter CLI to tweet, reply, read threads, and search without a browser.",
method: .pnpm(
repoPath: "\(NSHomeDirectory())/Projects/bird",
script: "binary",
binary: "bird"),
kind: .tool),
ToolEntry(
id: "agent-tools",
name: "🧰 agent-tools",
url: URL(string: "https://github.com/badlogic/agent-tools")!,
description: "Collection of utilities and scripts tuned for autonomous agents and MCP clients.",
method: .gitClone(
url: "https://github.com/badlogic/agent-tools.git",
destination: "\(NSHomeDirectory())/agent-tools"),
kind: .tool),
]
}
@AppStorage("tools.packageManager") private var packageManagerRaw = NodePackageManager.npm.rawValue
@State private var installStates: [String: InstallState] = [:]

View File

@@ -35,7 +35,7 @@ struct SettingsViewSmokeTests {
enabled: false,
createdAtMs: 1_700_000_000_000,
updatedAtMs: 1_700_000_100_000,
schedule: .every(everyMs: 30_000, anchorMs: nil),
schedule: .every(everyMs: 30000, anchorMs: nil),
sessionTarget: .isolated,
wakeMode: .nextHeartbeat,
payload: .agentTurn(
@@ -148,4 +148,8 @@ struct SettingsViewSmokeTests {
let view = ToolsSettings()
_ = view.body
}
@Test func toolsSettingsIncludesSummarize() {
#expect(ToolsSettings.toolIDsForTests.contains("summarize"))
}
}