以下为本文档的中文说明该技能是统一的餐厅预订CLI工具同时支持OpenTable、Tock和Resy三大主流预订平台。它提供一次搜索多个预订网络的功能监控目标餐厅的可预约时段变化并在出现取消释出的名额时自动捕获预订。适用于美食爱好者和频繁外出就餐的用户需要在热门餐厅获得预订位置的场景。该技能整合了多个预订平台的查询接口避免了在多个网站间反复切换的低效操作通过自动化监控和预订功能帮助用户提高在热门餐厅获取预订的成功率。该技能提供了详细的操作指南和最佳实践帮助用户快速上手并深入掌握。通过系统的功能模块划分和丰富的应用场景说明用户可以在实际项目中有效运用该技能提升工作效率。该技能注重实用性和可操作性涵盖从基础配置到高级功能的完整知识体系满足不同层次用户的学习需求。持续更新和优化的内容确保用户始终能够接触到最新的技术发展和行业实践。通过此技能的学习和应用用户可以减少摸索时间快速获得可用的解决方案将精力集中在核心业务逻辑和创新工作上从而在技术快速迭代的环境中保持竞争力。该技能的模块化设计使其易于扩展和定制用户可以根据自身需求灵活调整应用方式实现最大化的价值产出。该技能整合了常见的设计模式和最佳实践提供了清晰的学习路径和参考资料帮助用户在短时间内建立起完整的知识框架并有能力在实际项目中灵活运用所学内容解决问题。Table Reservation GOAT — Printing Press CLIPrerequisites: Install the CLIThis skill drives thetable-reservation-goat-pp-clibinary.You must verify the CLI is installed before invoking any command from this skill.If it is missing, install it first:Install via the Printing Press installer. It defaults binaries to$HOME/.local/binon macOS/Linux and%LOCALAPPDATA%\\Programs\\PrintingPress\\binon Windows:npx-ymvanhorn/printing-press-libraryinstalltable-reservation-goat --cli-onlyVerify:table-reservation-goat-pp-cli --versionEnsure the reported install directory is on$PATHfor the agent/runtime that will invoke this skill.If thenpxinstall fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.3 or newer):goinstallgithub.com/mvanhorn/printing-press-library/library/food-and-dining/table-reservation-goat/cmd/table-reservation-goat-pp-clilatestIf--versionreports “command not found” after install, the runtime cannot see the binary directory on$PATH. Do not proceed with skill commands until verification succeeds.When to Use This CLIUse this CLI any time a user or agent needs to search, compare, watch, or book across OpenTable, Tock, and Resy together — and especially for multi-venue questions (‘soonest table at any of these’), cancellation hunting, or tracking changes at a specific venue. For single-network simple lookups, the official site UI is faster.Unique CapabilitiesThese capabilities aren’t available in any other tool for this API.Cross-network ground truthgoat— One query across OpenTable, Tock, and Resy simultaneously, ranked by relevance, earliest availability, and price band.When a user asks an agent to find a table, this is the single command that searches both reservation networks and returns structured ranked results — agents do not need to know which network covers which restaurant.table-reservation-goat-pp-cli goattasting menu chicago--party2--whenthis weekend--agent--selectresults.name,results.network,results.earliest_slot,results.price_bandearliest— Across a list of restaurants from either network, return the earliest open slot per venue within a time horizon.When a user gives an agent a shortlist of venues and wants the soonest opportunity, this is the right shape — one structured response with one row per venue across all three networks.table-reservation-goat-pp-cli earliestalinea,le-bernardin,smyth,atomix--party4--within21d--agent--selectearliest.venue,earliest.network,earliest.slot_at,earliest.attributesLocal state that compoundswatch— Persistent local watcher that polls each network for openings on your target venues and party size, with notifications and optional auto-book.Resy’s Notify covers Resy only; tockstalk covers Tock only; restaurant-mcp’s snipe covers ResyOT only. None covers each network; none persists state. Use this when an agent or user needs a hot reservation that isn’t currently available.table-reservation-goat-pp-cliwatchaddle-bernardin--party2--windowFri 7-9pm--notifyslackdrift— Show what changed at a specific venue since the last sync — new experiences, slot price moves, hours changes.Hot-target deep-watch: when an agent or user is hunting one venue, drift surfaces every meaningful change since the last look.table-reservation-goat-pp-cli drift alinea--since2026-04-01--agentCommand Referenceavailability— Check open reservation slots across OpenTable, Tock, and Resytable-reservation-goat-pp-cli availability check— Check open slots for a restaurant on a specific date and party sizetable-reservation-goat-pp-cli availability multi-day— Multi-day availability for a single restaurant — Mon-Sun matrixrestaurants— Search and inspect restaurants across OpenTable, Tock, and Resytable-reservation-goat-pp-cl i restaurants get— Get a restaurant’s full detail — hours, address, cuisine, price band, photos, accoladestable-reservation-goat-pp-cli restaurants list— List restaurants across OpenTable, Tock, and Resy; filter by location, cuisine, price band, accolades, and party sizewatch— Persistent local cancellation watcher across all three networkstable-reservation-goat-pp-cli watch add— Register a watch for a venue, party size, and time windowtable-reservation-goat-pp-cli watch list— List active watchestable-reservation-goat-pp-cli watch cancel— Cancel a watch by idtable-reservation-goat-pp-cli watch tick— Run one polling tick across all active watches (for cron / agents)Finding the right commandWhen you know what you want to do but not which command does it, ask the CLI directly:table-reservation-goat-pp-cliwhichcapability in your own wordswhichresolves a natural-language capability query to the best matching command from this CLI’s curated feature index. Exit code0means at least one match; exit code2means no confident match — fall back to--helpor use a narrower query.Location Handling (Agent Playbook)Every read command (restaurants list,availability check,availability multi-day,earliest,goat,watch) accepts a free-form--locationflag that parses bare city, citystate, metro qualifier, or coordinates.Accepted--locationshapes:--locationbellevue# bare city (ambiguous — see below)--locationbellevue, wa# city state (unambiguous)--locationseattle metro# metro qualifier--location47.6101,-122.2015# coordinates (lat,lng)The resolver returns one of three response shapes, classified by the categoricaltierfield:tier: high(one match, or specific input): response includeslocation_resolvedfield with the canonical name, centroid, reason, and any alternates considered. Results are filtered to that region.tier: medium(multiple candidates but one dominates): response includes bothlocation_resolvedandlocation_warning. The warning lists the alternates so the agent can sanity-check against conversation context.tier: low(genuinely ambiguous, e.g., bare “bellevue” matches WA/NE/KY): the command refuses to return results. Instead it emits a typedneeds_clarificationenvelope with ranked candidates, each carryingstate,context_hints,tock_business_count, andscore_if_picked. The agent disambiguates and re-runs.Note:location_resolved.scoreis the popularity prior (a mechanical [0,1] number derived from population provider coverage). Do not branch on this number — Bellevue WA at citystate specificity is HIGH-certain but its absolute score is modest (~0.42), and Seattle at HIGH tier reads ~0.6. The categoricaltierfield is what agents branch on;scoreis informational.Three agent rules (load-bearing contract)1. Always checklocation_resolved.tierin successful responses.Thetierstring is the agent-facing categorical classification — branch on it, not on the numericscore.tier high— the pick is reliable; proceed.tier medium— alternates exist and the response includes alocation_warninglisting them. Sanity-check the pick against conversation context (e.g., did you pick Portland OR but the user clearly meant Maine?). Surface the pick to the user.tier low— you’ll receive aneeds_clarificationenvelope instead of results; rule 2 applies.2. Onneeds_clarification: true, do NOT retry blindly.First, look back in the conversation for geographic clues (state mentions, nearby cities, prior locations, time-zone hints). If you find any, re-run with that location. If you don’t, use theagent_guidance.fallback_clarificationtext (or your own phrasing) to ask the user. Concrete shape:{needs_clarification:true,error_kind:location_ambiguous,what_was_asked:bellevue,candidates:[{name:Bellevue, WA,state:WA,context_hints:[Seattle metro,Eastside],tock_business_count:28,score_if_picked:0.78,centroid:[47.6101,-122.2015]},{name:Bellevue, NE,state:NE,context_hints:[Omaha metro],tock_business_count:0,score_if_picked:0.18,centroid:[41.1370,-95.9145]},{name:Bellevue, KY,state:KY,context_hints:[Cincinnati metro],tock_business_count:0,score_if_picked:0.04,centroid:[39.1067,-84.4744]}],agent_guidance:{preferred_recovery:Check conversation context for geographic clues. If the user mentioned a state or nearby city, re-run with that.,rerun_pattern:command --location chosen-name}}3. Never silently accept a MEDIUM-tier resolution.Whenlocation_warningis present on a successful response (tier medium, or atier lowforced pick from a batch caller), surface the pick to the user in your reply (e.g., “I’m searching in Bellevue, WA — let me know if you meant a different one”). The warning is the CLI’s signal thatyoushould hand the user a hand-off point. Do NOT reach for--batch-accept-ambiguousto silence the warning — that flag is for batch jobs only; in interactive use it defeats the disambiguation contract entirely.--batch-accept-ambiguousis a batch-only escape hatchEvery read command exposes--batch-accept-ambiguous(default false). When true, a LOW-tier resolution returns a forced pick (top candidate by popularity prior) withlocation_warningflagging the bypass, rather than theneeds_clarificationenvelope.Interactive agents must never use this flag — it defeats the disambiguation contract entirely.The verbosebatch-prefix is intentional: it exists exclusively for batch jobs, scheduled runs, and test fixtures where any-pick-is-fine semantics are correct. If you’re answering a user in real time and you reach for this flag, stop — re-read rule 2 and disambiguate from conversation context or ask the user.--metrois a deprecated alias--metro slugcontinues to work for back-compat, but the implicit--batch-accept-ambiguousiscanonical-only— it is set automatically only when the value resolves to a single, unambiguous metro via the registry (slug lookup, alias chain, or a singleLookupByNamehit). Three cases:Canonical slug(seattle,nyc,chicago,sf,san-francisco, etc.) — single registry hit. The resolver silent-picks with the legacy result-shape preserved (no envelope). This is the back-compat path.Ambiguous value(e.g.,--metro bellevuematches WA/NE/KY by display name) —--batch-accept-ambiguousisnotimplied. The resolver returns the sameneeds_clarificationenvelope--location bellevuewould.Legacy callers must handle the envelope path— treat the response exactly like a--locationenvelope and disambiguate (Codex P1-D fix; silently picking the wrong city is worse than asking).Unknown slug— returns alocation_unknownenvelope, same as--location unknown.A one-line stderr deprecation warning (warning: --metro is deprecated; use --location city.) fires once-per-process on first use regardless of the canonical-vs-ambiguous outcome. New code should use--location.Slug suffixes still work inearliestandwatchWhen you compose a venue slug with a city suffix (joey-bellevue,13-coins-bellevue) and don’t pass--location, the CLI detects the city hint, anchors the Autocomplete search at the inferred metro’s centroid, and tags the resultinglocation_resolved.sourceasextracted_from_query(signaling soft-demote post-filter). Explicit--locationalways wins over slug-suffix inference.location resolveis a primitiveWhen you need to verify a location is well-formed before running a search, use:table-reservation-goat-pp-cli location resolvebellevue, wa--agentEmits the typedGeoContextJSON (HIGH/MEDIUM) or the disambiguation envelope (LOW). Useful for up-front verification before fanning out reads.Numeric IDs bypass location resolutionWhen you have an OpenTable numeric ID (fromrestaurants list --json), pass it directly toavailability check/availability multi-day/earliest. The numeric-ID short-circuit skips the slug resolver entirely:table-reservation-goat-pp-cli availability check3688--party6--date2026-12-25--agentIf you also pass--locationwith a numeric ID and the venue is outside the stated radius, the response will include alocation_warning(not a hard-reject) — the numeric ID is treated as authoritative; the warning is informational.Error Recovery for AgentsThe CLI surfaces a typederror_kindfield on availability rows so agentscan branch on the recovery strategy without parsing free-textreasonstrings. Three cases the agent should handle distinctly:error_kind: session_blockedThe entire OpenTable session is shadow-banned (Akamai sees the cookies asexpired/invalid).AllOT operations will fail until cookies are refreshed.Recovery:ask the user to runauth login --chrome(interactive). TheCLI’s in-memory cooldown will clear once the new cookies pass throughBootstrap. The disk-persisted cooldown auto-expires (5min → 60min exponentialbackoff per consecutive 403).error_kind: operation_blockedA specific GraphQL opname (typicallyRestaurantsAvailabilityorAutocomplete) is on a WAF blocklist.Sibling operations on the samesession still work.Recovery paths, in order of preference:Pivot to a numeric OpenTable ID.restaurants listreturns ids like3688. Passingavailability check 3688bypasses the Autocomplete-basedresolver entirely, so anAutocomplete-specific WAF rule doesn’t apply:table-reservation-goat-pp-cli availability check3688--party6--agentUse the chromedp escape hatch.When Chrome is running with remote-debugging enabled, the CLI routes blocked requests through the realbrowser’s TLS stack:# Launch Chrome with debugging once per sessionopen-aGoogle Chrome--args--remote-debugging-port9222# Or point at a custom port via env varexportTABLE_RESERVATION_GOAT_OT_CHROME_DEBUG_URLhttp://localhost:9222The CLI auto-falls-back to chromedp onBotDetectionErrors in theavailability path.Surface the venue URL to the user.Every row carriesurl(e.g.,https://www.opentable.com/restaurant/profile/3688). When both codepaths are blocked, the agent should hand the user the URL so they canclick through to OpenTable directly.Noerror_kindfield (Tock errors, non-WAF errors)Tock doesn’t have a Kind discriminator yet — its errors arrive as plaintext inreason. The reason strings name the upstream condition(venue not found,calendar empty, etc.); agents should surface themto the user without retry.RecipesHeadline omakase search across all three networks (agent-shaped)table-reservation-goat-pp-cli goatomakase manhattan--party2--whenthis fri 7-9pm--agent--selectresults.name,results.network,results.earliest_slot,results.price_band,results.attributesSingle command, ranked merged output with the deeply-nested fields agents actually need — narrows a multi-KB response to five columns.Watch one Tock-only and one OT-only venue at the same party sizetable-reservation-goat-pp-cliwatchaddalinea--party2--windowsat 7-9pm--notifylocaltable-reservation-goat-pp-cliwatchaddle-bernardin--party2--windowsat 7-9pm--notifylocalTwo watches, one local store, one polling daemon — the printer handles each network via per-source adaptive limiters.Soonest table among my shortlisttable-reservation-goat-pp-cli earliestnarisawa,sushi-saito,den,florilege--party2--within14d--agent--selectearliest.venue,earliest.network,earliest.slot_atOne row per venue with the soonest slot, sortable by slot time. Agents pipe into a planner without re-querying.Watched venue: what changed in the last weektable-reservation-goat-pp-cli drift alinea--since7d--agentSnapshot diff at a single venue — new experiences, slot price moves, hours changes — exactly what hot-target hunters need.Headline search, then check live availability for the top hittable-reservation-goat-pp-cli goatle bernardin--party2--json|jq-r.results[0] | (.network : .slug)|xargs-I{}table-reservation-goat-pp-cli availability check{}--party2--date$(date%Y-%m-%d)Compose the cross-network search with a follow-up live availability check —goatreturns the best matched venue,availability checkthen queries OpenTable or Tock directly for open slots on that venue and date.Auth SetupNo authentication required.Runtable-reservation-goat-pp-cli doctorto verify setup.Agent ModeAdd--agentto any command. Expands to:--json --compact --no-input --no-color --yes.Pipeable— JSON on stdout, errors on stderrFilterable—--selectkeeps a subset of fields. Dotted paths descend into nested structures; arrays traverse element-wise. Critical for keeping context small on verbose APIs:table-reservation-goat-pp-cli restaurants list--agent--selectid,name,neighborhood,price_bandPreviewable—--dry-runshows the request without sendingOffline-friendly— sync/search commands can use the local SQLite store when availableNon-interactive— never prompts, every input is a flagExplicit retries— use--idempotentonly when an already-existing create should count as success, and--ignore-missingonly when a missing delete target should count as successResponse envelopeCommands that read from the local store or the API wrap output in a provenance envelope:{meta:{source:live|local,synced_at:...,reason:...},results:data}Parse.resultsfor data and.meta.sourceto know whether it’s live or local. A human-readableN results (live)summary is printed to stderr only when stdout is a terminal — piped/agent consumers get pure JSON on stdout.Agent FeedbackWhen you (or the agent) notice something off about this CLI, record it:table-reservation-goat-pp-cli feedback the --since flag is inclusive but docs say exclusive table-reservation-goat-pp-cli feedback --stdin notes.txt table-reservation-goat-pp-cli feedback list --json --limit 10Entries are stored locally at~/.table-reservation-goat-pp-cli/feedback.jsonl. They are never POSTed unlessTABLE_RESERVATION_GOAT_FEEDBACK_ENDPOINTis set AND either--sendis passed orTABLE_RESERVATION_GOAT_FEEDBACK_AUTO_SENDtrue. Default behavior is local-only.Write whatsurprisedyou, not a bug report. Short, specific, one line: that is the part that compounds.Output DeliveryEvery command accepts--deliver sink. The output goes to the named sink in addition to (or instead of) stdout, so agents can route command results without hand-piping. Three sinks are supported:SinkEffectstdoutDefault; write to stdout onlyfile:pathAtomically write output topath(tmp rename)webhook:urlPOST the output body to the URL (application/jsonorapplication/x-ndjsonwhen--compact)Unknown schemes are refused with a structured error naming the supported set. Webhook failures return non-zero and log the URL HTTP status on stderr.Named ProfilesA profile is a saved set of flag values, reused across invocations. Use it when a scheduled agent calls the same command every run with the same configuration - HeyGen’s “Beacon” pattern.table-reservation-goat-pp-cli profile save briefing --json table-reservation-goat-pp-cli --profile briefing restaurants list table-reservation-goat-pp-cli profile list --json table-reservation-goat-pp-cli profile show briefing table-reservation-goat-pp-cli profile delete briefing --yesExplicit flags always win over profile values; profile values win over defaults.agent-contextlists all available profiles underavailable_profilesso introspecting agents discover them at runtime.Exit CodesCodeMeaning0Success2Usage error (wrong arguments)3Resource not found5API error (upstream issue)7Rate limited (wait and retry)10Config errorArgument ParsingParse$ARGUMENTS:Empty,help, or--help→ showtable-reservation-goat-pp-cli --helpoutputStarts withinstall→ ends withmcp→ MCP installation; otherwise → see Prerequisites aboveAnything else→ Direct Use (execute as CLI command with--agent)MCP Server InstallationInstall the MCP binary from this CLI’s published public-library entry or pre-built release, then register it:claude mcpaddtable-reservation-goat-pp-mcp -- table-reservation-goat-pp-mcpVerify:claude mcp listDirect UseCheck if installed:which table-reservation-goat-pp-cliIf not found, offer to install (see Prerequisites at the top of this skill).Match the user query to the best command from the Unique Capabilities and Command Reference above.Execute with the--agentflag:table-reservation-goat-pp-clicommand[subcommand][args]--agentIf ambiguous, drill into subcommand help:table-reservation-goat-pp-cli command --help.