diff --git a/catalogue/apps/io.pilot.bowmark/metadata.json b/catalogue/apps/io.pilot.bowmark/metadata.json index 0d53cf54..9c76a118 100644 --- a/catalogue/apps/io.pilot.bowmark/metadata.json +++ b/catalogue/apps/io.pilot.bowmark/metadata.json @@ -2,8 +2,8 @@ "schema_version": 1, "id": "io.pilot.bowmark", "display_name": "Bowmark", - "tagline": "Navigation cheatsheets for public websites, so agents run cheaper, faster, and more accurately.", - "description_md": "Bowmark gives agents a **pre-computed cheatsheet** for the task at hand. A cheatsheet is a compact, ready-to-run answer for one task on one site: a parameterized URL `shortcut` and/or a short `ui_procedure` of UI steps. Instead of burning tokens re-reading a site's DOM and guessing its way through the page, your agent calls `ask({ site, task })` and gets the exact path back. It spends less, finishes sooner, and lands on the right action the first time.\n\nBowmark is **free to use** — no signup and no API key to manage. It's plain request/response REST — no websockets, no server-side browser, no async jobs. Your agent runs the cheatsheet in its own browser; Bowmark only supplies the path.\n\n## Methods\n\n- **bowmark.ask** `{ site, task }` — give it a site and a plain-English task (e.g. \"find Apple's latest 10-K\") and it returns the cheatsheet: a URL `shortcut` (a `template` with `{name}` slots you fill from your task, then navigate) and/or a `ui_procedure.steps` list to follow in order, plus an `id`. Call it before any browser action, in place of exploring the page yourself; execute the cheatsheet open-loop rather than re-reading the DOM.\n- **bowmark.report_outcome** `{ envelope_id, success }` — after running a cheatsheet, report whether every step ran exactly as written. Honest results keep the cheatsheets fresh: a failure triggers a re-crawl that repairs the path for the next agent, so report `success: false` on any deviation (a retry, a raw-JS fallback, an extra click) even if you still got the answer.\n\n## Syntax & edge cases\n\n- `site` is a registrable domain, optionally with a product surface: `google.com`, `docs.stripe.com`, `google.com/maps` — a matching path acts as an implicit scope hint.\n- `task` is plain-English **intent**, never a URL.\n- Request the signed-in surface with `variants: { auth_state: \"logged_in\", role: \"owner\" }` (also `locale` / `region` / `currency`); the assumed facets come back on `variants_assumed`.\n- A `ui_procedure` step may be flagged `irreversible` (confirm with the user first) or `requires_user_input` (stop and ask the user — a password, payment, or personal detail).\n- Non-`ok` statuses: `no_useful_data` / `site_not_supported` / `synth_invalid` → browse manually; `ambiguous_scope` → retry with `scopeHint` = one of `error.scope_options[].pattern`; `rate_limited` → back off until `error.retry_after` (only NEW cheatsheet synthesis is capped — known ones still answer). On a `503`, retry once after `Retry-After`.\n- Skip Bowmark for localhost, RFC1918 IPs, and open-ended search with no destination.", + "tagline": "Live data from real websites: prices, stock, fares and quotes, including what only appears after you operate the page.", + "description_md": "Bowmark gives agents a **typed function library for the live web**, and runs the script they write against it on the real sites. `get_library({ query })` returns the vocabulary: namespaces, TypeScript types, function signatures and worked examples. `run({ script })` executes a short JavaScript body against them and hands back the result. Ask it for flights and it searches several aggregators at once, dedupes the same physical flight, sorts by price, and returns one normalized list.\n\n**The data it reaches is the kind an index cannot hold.** A fare that only exists after the site's own live poll completes. A price that appears once dates are entered. Stock for one postcode. A quote behind a form. These are not values sitting in the HTML waiting to be fetched, and they change while you read them, so the only way to have them is to operate the page at the moment you are asked. Bowmark does that and hands back structured JSON. It reads ordinary pages too, taking a browser only when one proves necessary.\n\nIt's plain request/response REST: no websockets, no async jobs, and no browser on your side. The script runs server side, in Bowmark's own process with its own browser, so your agent never opens a tab, holds a session, or parses a DOM. A capability like `bowmark.flights.search` fans out across the sites behind it, dedupes, ranks and routes around one that fails, and that whole fan-out is a single call.\n\n**Methods.** `bowmark.get_library` gives it what you want to DO, in the user's own words, or a company if they named one, and it returns the callable functions for that with their types and worked examples. It is read-only and touches no website, so call it first; an unrecognized query returns a one-line index rather than an error. `bowmark.run` takes a plain async JavaScript body written against those signatures. `bowmark` is the only I/O available inside it: no `fetch`, no `import`, no filesystem, no `process`.\n\n**What it covers today.** Flights (search, plus every seller for one itinerary with fare family and bag policy), hotels, car hire, PC parts across several retailers, music catalogue search, insurance carriers in the regulators' own register, work-email domains, and `read.page` / `read.pages` for any page as markdown, text or HTML. Individual sites are callable directly at `bowmark.providers.*` when you want one specific site rather than the fan-out.\n\n**Syntax & edge cases.** Check `status` before `ok`. `partial` means the script ran and the result is real and usable but narrower than you asked; `ok` stays true, and `incomplete.summary` names what never answered. `needs_user` is a pause, not a failure: a site wants a signed-in session, so hand `meta.handoff.url` to the user, wait, then re-send the identical script. A `get_library` answer can be a slice and says so when it is, so never conclude a task is uncovered from a list that announced it was partial; re-query one task, or one company by name. Prefer a capability over `bowmark.providers.*` unless you want one specific site. Skip Bowmark for localhost, RFC1918 addresses, and any page whose answer is already in the text of the page.", "vendor": { "name": "Bowmark AI", "url": "https://bowmark.ai", @@ -20,19 +20,20 @@ "automation" ], "keywords": [ + "live-data", + "prices", + "availability", + "stock", + "fares", + "quotes", + "web", "browser", - "navigation", - "cheatsheets", - "recipes", - "websites", - "playwright", - "puppeteer", - "computer-use", - "scraping" + "booking", + "computer-use" ], "size": { - "bundle_bytes": 5070050, - "installed_bytes": 9105408 + "bundle_bytes": 5072418, + "installed_bytes": 9113971 }, "compat": { "min_pilot_version": "1.10.0", @@ -42,19 +43,38 @@ }, "methods": [ { - "name": "bowmark.ask", - "summary": "Give it a site and a plain-English task (e.g. 'find Apple's latest 10-K') and it returns a ready-to-run cheatsheet — a URL shortcut to fill and navigate and/or a short ui_procedure of steps. Call it before any browser action, in place of exploring the page yourself, and execute the cheatsheet open-loop. status=ok returns an id; no_useful_data/site_not_supported → browse manually; ambiguous_scope → retry with scopeHint; rate_limited → back off. Pass variants:{auth_state:'logged_in'} for signed-in surfaces. Intent, not a URL." + "name": "bowmark.get_library", + "summary": "START HERE. Read-only, and it touches no website. Returns the callable function library you write scripts against: the runtime globals plus, for each capability your query matches, its namespace, TypeScript types, function signatures and worked examples. Pass `query` as what you want to DO ('flights', 'price a GPU', 'check stock') or the company or site if the user named one ('Kayak', 'newegg.com'); a phrase in the user's own words is fine. You get what you asked about and nothing else. An unrecognized query, or no query at all, returns a one-line index of every capability instead of an error, so this check never dead ends. Responses are bounded and SAY SO when they are a slice: read that line before concluding anything, because absence from a sliced list means nothing, and the fix is one narrower query, which always returns that entry in full. Two tiers come back: capabilities like `bowmark.flights.search` fan out across several sites, dedupe and rank, so prefer those; `bowmark.providers.kayak.search` is one named site in its native shape." }, { - "name": "bowmark.report_outcome", - "summary": "After running a cheatsheet from ask, report whether every step ran exactly as written (envelope_id + success, optional evidence). success=true only if it ran clean — no retries, no raw-JS fallback, no extra clicks; false on any deviation, even if you still got the answer. Honest results trigger a re-crawl that keeps the cheatsheet fresh for the next agent." + "name": "bowmark.run", + "summary": "Executes your script on the real websites and returns what came back. Call bowmark.get_library FIRST: it gives the exact function names, argument shapes and return types. The language is plain async JavaScript. `bowmark` is a ready global with no import, every call is awaited, and you get real control flow: if, loops, array methods, and Promise.all for fan-out. `return` a value to get it back, `log(...)` for progress lines. `bowmark` is the ONLY I/O: no fetch, no process, no filesystem, no import or require. Write a plain async body, not a wrapping function, and keep it small and deterministic, because it runs in a hard sandbox with CPU, memory and wall-clock ceilings. `script` is the only argument; there is no site argument. Returns {ok, status, result, logs, error, ms}. CHECK `status` BEFORE `ok`: ok | partial (the script ran and the result is real and usable but narrower than asked, ok stays true, and incomplete.summary names what never answered; this is not a failure and re-running usually returns the same thing) | error | needs_user (a site wants a signed-in session, so the run PAUSED: hand meta.handoff.url to the user, wait, then re-send the identical script). Bowmark drives the sites server side, so your agent never opens a browser." }, { "name": "bowmark.help", "summary": "Discovery: every method with params, latency, and description." } ], + "links": [ + { + "label": "Source", + "url": "https://github.com/bowmark-ai/plugin" + }, + { + "label": "Website", + "url": "https://bowmark.ai" + } + ], "changelog": [ + { + "version": "1.0.0", + "date": "2026-08-03", + "notes": [ + "Replaces bowmark.ask and bowmark.report_outcome with bowmark.get_library and bowmark.run. Bowmark no longer returns a navigation recipe for the caller to execute; it returns a typed function library and runs the caller's script on the real sites.", + "Execution moved server side. The calling agent no longer needs a browser of its own.", + "product_demo and next_steps rebuilt for the new methods and statuses, including needs_user, where a run that meets a site login pauses and returns a single-use handoff link for the human rather than failing." + ] + }, { "version": "0.1.0", "date": "2026-07-06", @@ -64,66 +84,60 @@ ] } ], - "links": [ - { "label": "Source", "url": "https://github.com/bowmark-ai/plugin" }, - { "label": "Website", "url": "https://bowmark.ai" } - ], - "published_at": "2026-07-06", - "updated_at": "2026-07-06", "product_demo": { "skill": "io.pilot.bowmark", "title": "Full usage demo", - "when_to_use": "When your agent is about to act on a known public website — call bowmark.ask({site, task}) first to get a ready-to-run URL shortcut or UI procedure instead of exploring the DOM.", - "metered": true, + "when_to_use": "When your agent needs a value that only exists on a live site right now, and only after somebody operates it: a current price, stock for one location, a fare, a quote, or anything behind a form, a filter or a login.", + "metered": false, "quickstart": { - "goal": "Get a navigation cheatsheet for a site + task", - "command": "pilotctl appstore call io.pilot.bowmark bowmark.ask '{\"site\":\"sec.gov\",\"task\":\"find Apple's latest 10-K filing\"}'", - "expect": "{\"status\":\"ok\",\"id\":\"...\",\"shortcut\":{\"template\":\"https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany\u0026CIK={ticker}\u0026type=10-K\"}}" + "goal": "See whether a function already covers the task", + "command": "pilotctl appstore call io.pilot.bowmark bowmark.get_library '{\"query\":\"flights\"}'", + "expect": "markdown: the bowmark.flights capability, with its TypeScript types, search/getBookingOptions signatures, and worked script examples", + "note": "Always call this first. An unrecognized query returns a one-line index instead of an error, so the check never dead ends." }, "examples": [ { - "title": "Ask for a UI procedure on a product surface", - "goal": "Scope with a path to skip the ambiguous_scope round-trip", - "command": "pilotctl appstore call io.pilot.bowmark bowmark.ask '{\"site\":\"google.com/maps\",\"task\":\"get directions from SFO to downtown\"}'", - "expect": "{\"status\":\"ok\",\"id\":\"...\",\"ui_procedure\":{\"steps\":[...]}}" + "title": "Search flights across several aggregators with one call", + "goal": "One capability fans out across sites, dedupes the same physical flight, and sorts by price", + "command": "pilotctl appstore call io.pilot.bowmark bowmark.run '{\"script\":\"const { flights, warnings } = await bowmark.flights.search({ from: \\\"YYZ\\\", to: \\\"LHR\\\", depart: \\\"2026-09-14\\\" }); return { cheapest: flights[0], warnings };\"}'", + "expect": "{\"ok\":true,\"status\":\"ok\",\"result\":{\"cheapest\":{\"price\":412,\"site\":\"google_flights\"},\"warnings\":[]}}", + "note": "These prices only exist after each site's own live poll completes, so they are not fetchable as static HTML. `warnings` names any site dropped from the fan-out, so a degraded search cannot read as a complete one." + }, + { + "title": "Price one part across three retailers", + "goal": "Newegg, Micro Center and B&H in parallel, cheapest first", + "command": "pilotctl appstore call io.pilot.bowmark bowmark.run '{\"script\":\"const { offers, warnings } = await bowmark.pcparts.search(\\\"GeForce RTX 4070\\\"); return { cheapest: offers[0], stores: offers.length, warnings };\"}'", + "expect": "{\"ok\":true,\"status\":\"ok\",\"result\":{\"cheapest\":{\"store\":\"microcenter\",\"price\":539.99},\"warnings\":[]}}", + "note": "A store named in `warnings` priced nothing, so \"cheapest of three\" was really the cheapest of two." + }, + { + "title": "Read any page as markdown", + "goal": "Cheap GET first, a browser only if the page proves it needs one", + "command": "pilotctl appstore call io.pilot.bowmark bowmark.run '{\"script\":\"const p = await bowmark.read.page(\\\"https://example.com/pricing\\\"); return { title: p.title, servedBy: p.servedBy, content: p.content };\"}'", + "expect": "{\"ok\":true,\"status\":\"ok\",\"result\":{\"title\":\"Pricing\",\"servedBy\":\"fetch\",\"content\":\"# Pricing\\n...\"}}", + "note": "`servedBy` says which rung paid for it, and `wall` names the bot wall when a rendered look finds one, so a block is a named fact rather than an empty page." }, { - "title": "Request the signed-in surface", - "command": "pilotctl appstore call io.pilot.bowmark bowmark.ask '{\"site\":\"github.com\",\"task\":\"create a new private repo\",\"variants\":{\"auth_state\":\"logged_in\",\"role\":\"owner\"}}'", - "expect": "{\"status\":\"ok\",\"id\":\"...\",\"ui_procedure\":{\"steps\":[...]},\"variants_assumed\":{...}}" + "title": "Do several lookups in one script", + "goal": "Real control flow, so many searches happen in one call instead of one each", + "command": "pilotctl appstore call io.pilot.bowmark bowmark.run '{\"script\":\"const cities = [\\\"LHR\\\",\\\"CDG\\\",\\\"AMS\\\"]; const all = await Promise.all(cities.map(to => bowmark.flights.search({ from: \\\"YYZ\\\", to, depart: \\\"2026-09-14\\\" }))); return cities.map((to, i) => ({ to, best: all[i].flights[0]?.price ?? null }));\"}'", + "expect": "{\"ok\":true,\"status\":\"ok\",\"result\":[{\"to\":\"LHR\",\"best\":412},{\"to\":\"CDG\",\"best\":389},{\"to\":\"AMS\",\"best\":401}]}" }, { - "title": "Report the outcome to keep cheatsheets fresh", - "goal": "success=true only if every step ran clean — no retries or extra clicks", - "command": "pilotctl appstore call io.pilot.bowmark bowmark.report_outcome '{\"envelope_id\":\"\u003cid-from-ask\u003e\",\"success\":true}'", - "expect": "{\"id\":\"...\"}" + "title": "Drill into one site when the fan-out is not what you want", + "goal": "The headline fare is one seller's price for one fare class, so ask who else sells it and what the cheap one leaves out", + "command": "pilotctl appstore call io.pilot.bowmark bowmark.run '{\"script\":\"const rows = await bowmark.providers.kayak.search({ from: \\\"SFO\\\", to: \\\"JFK\\\", depart: \\\"2026-09-15\\\" }); const cheapest = rows.filter(r => r.price != null).sort((a,b) => a.price - b.price)[0]; const sellers = await bowmark.providers.kayak.getBookingOptions(cheapest); return { headline: cheapest.price, sellers: sellers.length, withCheckedBag: sellers.filter(s => s.checkedBagIncluded === true).length };\"}'", + "expect": "{\"ok\":true,\"status\":\"ok\",\"result\":{\"headline\":198,\"sellers\":7,\"withCheckedBag\":3}}", + "note": "Two dependent calls, still one script. Providers return that site's native shape, so you give up the cross-site dedupe and the routing around a failing site." } ], - "cost": { - "unit": "requests (managed key, currently unmetered)", - "free_budget": "managed — no per-user charge today", - "hard_cap_usd": 0, - "operations": [ - { - "op": "bowmark.ask", - "price": "free", - "note": "the nav-recipe call (POST /v1/ask); managed key, no per-op meter currently" - }, - { - "op": "bowmark.report_outcome", - "price": "free", - "note": "feedback that triggers a re-crawl; no charge" - } - ], - "worked_total": "Managed key with quota 0 — there is no per-user dollar charge today; both methods are free to call." - }, "gotchas": [ - "Put intent in `task`, never a URL — 'find Apple's latest 10-K', not a link.", - "Execute the cheatsheet open-loop — don't re-snapshot the DOM to verify what it already documents.", - "A step flagged `irreversible` needs user confirmation; `requires_user_input` means stop and ask.", - "report_outcome success=false on ANY deviation (a retry, raw-JS fallback, extra click) even if you got the answer.", - "Non-ok statuses (no_useful_data / site_not_supported / ambiguous_scope / rate_limited) → browse manually or retry with scopeHint.", - "Skip Bowmark for localhost, RFC1918 IPs, and open-ended search with no destination." + "Call `get_library` before `run`, always. The script has to be written against names only `get_library` supplies, and it is read-only and touches no website.", + "Check `status` before `ok`. `partial` means the script ran and the result is real but narrower than you asked; `ok` stays true, and `incomplete.summary` names what never answered.", + "`needs_user` is a login pause, not a failure: give the user `meta.handoff.url`, wait, then re-send the identical script. Bowmark holds no site credentials of yours.", + "`bowmark` is the only I/O available inside a script. No `fetch`, no `import`, no filesystem, no `process`. Write a plain async body, `return` a value, `log()` for progress.", + "A `get_library` answer can be a slice and says so when it is. Never conclude a task is uncovered from a list that announced it was partial; re-query one task, or one company by name.", + "Skip Bowmark for localhost, RFC1918 addresses, and any page whose answer is already in the text of the page." ], "next": [ "io.pilot.bowmark bowmark.help '{}'" @@ -134,57 +148,58 @@ "app": "io.pilot.bowmark", "edges": [ { - "from": "bowmark.ask", + "from": "bowmark.get_library", "on": "ok", - "match": "\"status\"\\s*:\\s*\"ok\"", - "why": "cheatsheet in hand — run it open-loop, then report back: the report is what keeps this path working for the next agent", + "why": "you now have the exact function names, argument shapes and return types, so write a short script against them and run it", "then": [ { - "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.report_outcome '{\"envelope_id\":\"\",\"success\":true}'", - "why": "pass the id from this ask; success=true ONLY if every step ran clean — false triggers a re-crawl that repairs the path", + "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.run '{\"script\":\"const { flights } = await bowmark.flights.search({ from: \\\"YYZ\\\", to: \\\"LHR\\\", depart: \\\"2026-09-14\\\" }); return flights[0];\"}'", + "why": "the library is the vocabulary; run is where the task actually happens on the live sites", "kind": "flow" } ] }, { - "from": "bowmark.ask", + "from": "bowmark.run", "on": "ok", - "match": "\"status\"\\s*:\\s*\"ambiguous_scope\"", - "why": "the site has several product surfaces and bowmark needs to know which one you mean", + "match": "\"status\"\\s*:\\s*\"needs_user\"", + "why": "a site wants a signed-in session, so the run paused rather than failed", "then": [ { - "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.ask '{\"site\":\"google.com\",\"task\":\"get directions from SFO to downtown\",\"scopeHint\":\"/maps\"}'", - "why": "re-ask with one of error.scope_options[].pattern verbatim as scopeHint (or fold it into site, e.g. google.com/maps)", + "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.run '{\"script\":\"\"}'", + "why": "hand meta.handoff.url to the user, wait until they have signed in, then re-send the same script unchanged", "kind": "recovery" } ] }, { - "from": "bowmark.ask", - "on": "err", - "code": 400, - "why": "ask rejected the body — site and task are both required", + "from": "bowmark.run", + "on": "ok", + "match": "\"status\"\\s*:\\s*\"partial\"", + "why": "the result is real and usable but narrower than asked, because some site never answered", "then": [ { - "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.ask '{\"site\":\"sec.gov\",\"task\":\"find the latest 10-K filing for Apple\"}'", - "why": "site is a bare registrable domain (no scheme); task is plain-English intent, never a URL", + "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.get_library '{\"query\":\"\"}'", + "why": "read incomplete.summary first; re-running usually returns the same thing, so check whether another capability or provider covers the gap", "kind": "recovery" } ] }, { - "from": "bowmark.report_outcome", + "from": "bowmark.run", "on": "err", "code": 400, - "why": "report_outcome rejected the body — envelope_id and success are both required", + "why": "run rejected the body: script is the only argument, and it must be a plain async body rather than a wrapping function", "then": [ { - "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.report_outcome '{\"envelope_id\":\"\",\"success\":true}'", - "why": "envelope_id is the id from a status:ok ask (a miss has no id — don't report those); success is a bool", + "cmd": "pilotctl appstore call io.pilot.bowmark bowmark.get_library '{\"query\":\"flights\"}'", + "why": "re-read the worked examples for the exact call shape, then send the script text as the single script argument", "kind": "recovery" } ] } ] - } + }, + "published_at": "2026-07-06", + "updated_at": "2026-08-03" } diff --git a/catalogue/catalogue.json b/catalogue/catalogue.json index af337879..637b0a66 100644 --- a/catalogue/catalogue.json +++ b/catalogue/catalogue.json @@ -5,7 +5,7 @@ { "id": "io.pilot.wallet", "version": "0.3.3", - "description": "On-overlay USDC payments \u2014 multichain (Base + Ethereum + Polygon).", + "description": "On-overlay USDC payments — multichain (Base + Ethereum + Polygon).", "bundle_url": "https://github.com/pilot-protocol/pilotprotocol/releases/download/wallet-v0.3.3/io.pilot.wallet-0.3.3.tar.gz", "bundle_sha256": "8d30b4331bc025c327dd2d8610362984cc9365843176e21b96a2637d8e18ff54", "display_name": "Wallet", @@ -84,14 +84,14 @@ "id": "io.pilot.smolmachines", "renamed_to": "io.pilot.smol", "hidden": true, - "display_name": "Smol Machines (renamed \u2192 io.pilot.smol)", - "description": "Renamed to io.pilot.smol. Install io.pilot.smol \u2014 it is the same app plus a cloud plane. This tombstone entry is retained only to keep already-installed copies running and to redirect the old id; it is not listed and is not installable.", + "display_name": "Smol Machines (renamed → io.pilot.smol)", + "description": "Renamed to io.pilot.smol. Install io.pilot.smol — it is the same app plus a cloud plane. This tombstone entry is retained only to keep already-installed copies running and to redirect the old id; it is not listed and is not installable.", "publisher": "ed25519:3QJm6H6OdjtfrF+Es1lrRjfFmdtq2tGvVSWxia63vcI=" }, { "id": "io.telepat.ideon-free", "version": "0.3.1", - "description": "Free article generation for agents: ideon-free.generate(idea) returns a jobId; ideon-free.poll(jobId) returns the finished markdown article. Thin adapter over Ideon's ideon_write \u2014 no payment.", + "description": "Free article generation for agents: ideon-free.generate(idea) returns a jobId; ideon-free.poll(jobId) returns the finished markdown article. Thin adapter over Ideon's ideon_write — no payment.", "bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/ideon-free-v0.3.1/io.telepat.ideon-free-0.3.1.tar.gz", "bundle_sha256": "dd8e37057f33eadefff6b7ff5fc99130667076ea398c10a154c345fd87dd1ad6", "publisher": "ed25519:5cqj+zTVecj8r0YRUShpgFi/g7TxDg1lkDKQzfNyDyc=", @@ -101,7 +101,7 @@ { "id": "io.pilot.slipstream", "version": "1.0.0", - "description": "SLIPSTREAM \u2014 Polymarket smart-money leaderboard, signals, tape & opportunities (Ed25519-signed API).", + "description": "SLIPSTREAM — Polymarket smart-money leaderboard, signals, tape & opportunities (Ed25519-signed API).", "bundle_url": "https://github.com/pilot-protocol/catalog/releases/download/slipstream-v1.0.0/io.pilot.slipstream-1.0.0.tar.gz", "bundle_sha256": "8f19c06c886b97abb1272e8f657773950bee747c58dab8493d454742313ef2f5", "display_name": "Slipstream", @@ -131,7 +131,7 @@ { "id": "io.pilot.miren", "version": "0.1.0", - "description": "Operate the Miren PaaS from an agent: deploy and roll back apps; inspect status, logs, and history; run the server; and diagnose connectivity \u2014 plus a passthrough exec for any miren subcommand.", + "description": "Operate the Miren PaaS from an agent: deploy and roll back apps; inspect status, logs, and history; run the server; and diagnose connectivity — plus a passthrough exec for any miren subcommand.", "display_name": "Miren", "vendor": "Miren", "license": "Proprietary", @@ -163,7 +163,7 @@ { "id": "io.pilot.otto", "version": "0.20.0", - "description": "Drive real Chrome tabs from an agent: extract page content as markdown or HTML, run site commands (Reddit, LinkedIn, Hacker News, Google), screenshot pages, and inspect relay and node status \u2014 over a relay to a browser extension, no headless farm. Plus a passthrough exec for any otto subcommand.", + "description": "Drive real Chrome tabs from an agent: extract page content as markdown or HTML, run site commands (Reddit, LinkedIn, Hacker News, Google), screenshot pages, and inspect relay and node status — over a relay to a browser extension, no headless farm. Plus a passthrough exec for any otto subcommand.", "display_name": "Otto", "vendor": "Telepat", "license": "MIT", @@ -227,7 +227,7 @@ { "id": "io.pilot.postgres", "version": "17.5.0", - "description": "PostgreSQL 17.5.0 as a native CLI for agents: stand up and manage a local Postgres server (initdb / start / stop / createdb) and run SQL with psql \u2014 aligned-table or CSV results, backslash schema introspection, database listing, and the full client/server toolchain (pg_dump, pg_restore, pg_isready, ...) via a verbatim-argv passthrough. Connects to a local or remote server via a libpq connection string or PG* env.", + "description": "PostgreSQL 17.5.0 as a native CLI for agents: stand up and manage a local Postgres server (initdb / start / stop / createdb) and run SQL with psql — aligned-table or CSV results, backslash schema introspection, database listing, and the full client/server toolchain (pg_dump, pg_restore, pg_isready, ...) via a verbatim-argv passthrough. Connects to a local or remote server via a libpq connection string or PG* env.", "display_name": "PostgreSQL", "vendor": "Pilot Protocol", "license": "PostgreSQL", @@ -259,7 +259,7 @@ { "id": "io.pilot.duckdb", "version": "1.5.4", - "description": "DuckDB 1.5.4 as a native CLI for agents: an in-process analytical SQL database (think \"SQLite for analytics\") with zero server and zero provisioning. Run SQL in-memory or against a DuckDB file and query CSV, Parquet, and JSON files directly with no import step \u2014 results as an aligned table, CSV, JSON, or Markdown. Schema/table introspection, run a .sql script, and the full CLI surface (every flag + dot-command) via a verbatim-argv passthrough. Ideal for sandboxed agents that need real SQL locally without an AWS/GCP account.", + "description": "DuckDB 1.5.4 as a native CLI for agents: an in-process analytical SQL database (think \"SQLite for analytics\") with zero server and zero provisioning. Run SQL in-memory or against a DuckDB file and query CSV, Parquet, and JSON files directly with no import step — results as an aligned table, CSV, JSON, or Markdown. Schema/table introspection, run a .sql script, and the full CLI surface (every flag + dot-command) via a verbatim-argv passthrough. Ideal for sandboxed agents that need real SQL locally without an AWS/GCP account.", "display_name": "DuckDB", "vendor": "Pilot Protocol", "license": "MIT", @@ -298,7 +298,7 @@ { "id": "io.pilot.docker", "version": "29.6.1", - "description": "Docker 29.6.1 as a native CLI for agents (Linux): delivers the Docker Engine (dockerd + containerd + runc) and the docker CLI, sha-pinned. Start a local engine (docker.engine_start), then pull images and run containers \u2014 run/ps/images/pull/logs, plus build, exec, networks, volumes, and any docker command via a verbatim-argv passthrough. Real containers on a real Linux host, no Docker Desktop.", + "description": "Docker 29.6.1 as a native CLI for agents (Linux): delivers the Docker Engine (dockerd + containerd + runc) and the docker CLI, sha-pinned. Start a local engine (docker.engine_start), then pull images and run containers — run/ps/images/pull/logs, plus build, exec, networks, volumes, and any docker command via a verbatim-argv passthrough. Real containers on a real Linux host, no Docker Desktop.", "display_name": "Docker", "vendor": "Pilot Protocol", "license": "Apache-2.0", @@ -329,7 +329,7 @@ { "id": "io.pilot.redis", "version": "8.6.2", - "description": "Redis 8.6.2 as a native CLI for agents: stand up a local in-memory data store (redis.start) and talk to it with redis-cli \u2014 SET/GET, PING, INFO, DBSIZE, and ANY Redis command (lists, hashes, sets, sorted sets, streams, pub/sub, transactions) via a verbatim-argv passthrough. Server lifecycle (start/stop), health checks, and the full redis-cli/redis-server toolchain (redis-benchmark, redis-check-rdb, ...). No server to provision \u2014 runs locally on this host.", + "description": "Redis 8.6.2 as a native CLI for agents: stand up a local in-memory data store (redis.start) and talk to it with redis-cli — SET/GET, PING, INFO, DBSIZE, and ANY Redis command (lists, hashes, sets, sorted sets, streams, pub/sub, transactions) via a verbatim-argv passthrough. Server lifecycle (start/stop), health checks, and the full redis-cli/redis-server toolchain (redis-benchmark, redis-check-rdb, ...). No server to provision — runs locally on this host.", "display_name": "Redis", "vendor": "Pilot Protocol", "license": "AGPL-3.0", @@ -368,7 +368,7 @@ { "id": "io.pilot.aegis", "version": "0.1.3", - "description": "AEGIS 0.1.3 \u2014 a runtime firewall for AI agents (native CLI): scan files, commands, and tool results for prompt injection, jailbreaks, homoglyph/leetspeak obfuscation, and impersonation before your agent acts on them. L1 Aho-Corasick patterns plus an optional local Qwen3-1.7B judge, fully offline; an 880 KB binary. The scan-cmd/scan-result blocking gates run via aegis.exec (allow 0 / block 2); plus aegis.scan / status / targets / config.", + "description": "AEGIS 0.1.3 — a runtime firewall for AI agents (native CLI): scan files, commands, and tool results for prompt injection, jailbreaks, homoglyph/leetspeak obfuscation, and impersonation before your agent acts on them. L1 Aho-Corasick patterns plus an optional local Qwen3-1.7B judge, fully offline; an 880 KB binary. The scan-cmd/scan-result blocking gates run via aegis.exec (allow 0 / block 2); plus aegis.scan / status / targets / config.", "display_name": "AEGIS", "vendor": "Pilot Protocol", "license": "MIT", @@ -402,7 +402,7 @@ { "id": "io.pilot.smol", "version": "1.2.0", - "description": "Smol Machines \u2014 fast, hardware-isolated Linux microVMs, now local AND cloud. Create/run sub-second microVMs locally with the smolvm CLI, then push a VM to the smol cloud with smol.push. Pilot provisions a per-user cloud key automatically; cloud VMs are isolated per user and billed by real usage against $5 free credit.", + "description": "Smol Machines — fast, hardware-isolated Linux microVMs, now local AND cloud. Create/run sub-second microVMs locally with the smolvm CLI, then push a VM to the smol cloud with smol.push. Pilot provisions a per-user cloud key automatically; cloud VMs are isolated per user and billed by real usage against $5 free credit.", "display_name": "Smol Machines", "vendor": "smol machines", "license": "Apache-2.0", @@ -444,10 +444,10 @@ }, { "id": "io.pilot.bowmark", - "version": "0.1.0", - "description": "Navigation cheatsheets for public websites, so agents run cheaper, faster, and more accurately. Call ask({site, task}) before any browser action to get a ready-to-run cheatsheet \u2014 a parameterized URL shortcut and/or a short UI procedure to execute open-loop \u2014 instead of exploring the DOM; then report_outcome to keep them fresh. Free to use \u2014 no signup, no API key.", - "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/0.1.0/io.pilot.bowmark-0.1.0-linux-amd64.tar.gz", - "bundle_sha256": "af6f94bd8dd1ec2143d6d791205539f3b8ebeab94585d6f29552747de32cf997", + "version": "1.0.0", + "description": "Live data from real websites, including the values that only appear after somebody operates the page: prices, stock, fares, quotes, and anything behind a form or a login. Call bowmark.get_library({query}) for the typed function library, then send a short JavaScript script to bowmark.run({script}) and Bowmark executes it on the real sites.", + "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/1.0.0/io.pilot.bowmark-1.0.0-linux-amd64.tar.gz", + "bundle_sha256": "3b4800e811bb684f29b1b9a7ff76d72b364655bc3d2ca0744f50f77331256d04", "display_name": "Bowmark", "vendor": "Bowmark AI", "categories": [ @@ -456,27 +456,27 @@ "agents", "automation" ], - "bundle_size": 5070051, + "bundle_size": 5072418, "source_url": "https://github.com/bowmark-ai/plugin", "license": "Proprietary", "metadata_url": "https://raw.githubusercontent.com/pilot-protocol/pilotprotocol/main/catalogue/apps/io.pilot.bowmark/metadata.json", - "metadata_sha256": "88baa37ef7213eac493a1197b1578f495c30d613951f16a87b67e5d1322c9a30", + "metadata_sha256": "ce82188936ec3eae513fdd1b0a929d3528a0618fcf3861906e3c28376f140845", "bundles": { "linux/amd64": { - "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/0.1.0/io.pilot.bowmark-0.1.0-linux-amd64.tar.gz", - "bundle_sha256": "af6f94bd8dd1ec2143d6d791205539f3b8ebeab94585d6f29552747de32cf997" + "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/1.0.0/io.pilot.bowmark-1.0.0-linux-amd64.tar.gz", + "bundle_sha256": "3b4800e811bb684f29b1b9a7ff76d72b364655bc3d2ca0744f50f77331256d04" }, "linux/arm64": { - "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/0.1.0/io.pilot.bowmark-0.1.0-linux-arm64.tar.gz", - "bundle_sha256": "aeb587e89701bdc121717893562bfe50578a9b7235373fa93fd4c868ddacb928" + "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/1.0.0/io.pilot.bowmark-1.0.0-linux-arm64.tar.gz", + "bundle_sha256": "d5fb05bb39cbe727de7733c18ac4619de93c48771de9e0a8a2e7068d3ecb322e" }, "darwin/arm64": { - "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/0.1.0/io.pilot.bowmark-0.1.0-darwin-arm64.tar.gz", - "bundle_sha256": "c30336813659d2647164b519cd987a0a2b4d362bc985a30e3842903ab5fdb7e7" + "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/1.0.0/io.pilot.bowmark-1.0.0-darwin-arm64.tar.gz", + "bundle_sha256": "be84e356e53bbabd920b0f9e276718faf6259ad932e09d8b0c56a8b66f3129d2" }, "darwin/amd64": { - "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/0.1.0/io.pilot.bowmark-0.1.0-darwin-amd64.tar.gz", - "bundle_sha256": "ac71dfcbf72966eec95e3f8b6e4577c10a7fef62952b771e9dc765080613a23b" + "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.bowmark/1.0.0/io.pilot.bowmark-1.0.0-darwin-amd64.tar.gz", + "bundle_sha256": "325c554e66fbf0fb97ecf7d2d0a8e445dd6ae6198cc03f4ea6921ceefa21e447" } }, "publisher": "ed25519:Lmf0vzz0CNPu94pbqsbD/ueSuOaKsGc0xU/DoL+Yu7c=" @@ -484,7 +484,7 @@ { "id": "io.pilot.sqlite", "version": "3.45.2", - "description": "SQLite 3.45.2 as a native SQL database for agents: a zero-server, single-file, transactional (OLTP) SQL engine delivered to the host and fronted as typed methods. Run SQL against a .db file or an in-memory database and get rows back as JSON, run a multi-statement script, introspect the schema and table list, and reach the full sqlite3 CLI (every dot-command and flag \u2014 .dump, .import, .backup, CSV/table/markdown output, \u2026) via a verbatim-argv passthrough. The durable, on-disk complement to DuckDB's in-memory analytics \u2014 real transactional SQL locally with no server, no provisioning, and no cloud account.", + "description": "SQLite 3.45.2 as a native SQL database for agents: a zero-server, single-file, transactional (OLTP) SQL engine delivered to the host and fronted as typed methods. Run SQL against a .db file or an in-memory database and get rows back as JSON, run a multi-statement script, introspect the schema and table list, and reach the full sqlite3 CLI (every dot-command and flag — .dump, .import, .backup, CSV/table/markdown output, …) via a verbatim-argv passthrough. The durable, on-disk complement to DuckDB's in-memory analytics — real transactional SQL locally with no server, no provisioning, and no cloud account.", "display_name": "SQLite", "vendor": "Pilot Protocol", "license": "blessing", @@ -522,7 +522,7 @@ { "id": "io.pilot.agentphone", "version": "0.3.1", - "description": "Give your AI agent a real US/Canada phone number: place and receive voice calls, send and receive SMS/iMessage, and hold threaded conversations \u2014 all over REST, metered per user against a $5 budget.", + "description": "Give your AI agent a real US/Canada phone number: place and receive voice calls, send and receive SMS/iMessage, and hold threaded conversations — all over REST, metered per user against a $5 budget.", "display_name": "AgentPhone", "vendor": "AgentPhone", "license": "Apache-2.0", @@ -554,7 +554,7 @@ { "id": "io.pilot.insforge", "version": "1.0.0", - "description": "The agent-native cloud (an AWS for agents) as ONE Pilot app. insforge.signup provisions your OWN isolated InsForge backend in one call \u2014 no email, no browser: a dedicated Postgres database, authentication, S3-style storage, Deno edge functions, and a Model Gateway OpenRouter key seeded with $1 of AI credits. Pilot's broker mints and manages the account; every method then talks directly to your backend, authenticated as you. Free to provision \u2014 pay only for what your backend uses.", + "description": "The agent-native cloud (an AWS for agents) as ONE Pilot app. insforge.signup provisions your OWN isolated InsForge backend in one call — no email, no browser: a dedicated Postgres database, authentication, S3-style storage, Deno edge functions, and a Model Gateway OpenRouter key seeded with $1 of AI credits. Pilot's broker mints and manages the account; every method then talks directly to your backend, authenticated as you. Free to provision — pay only for what your backend uses.", "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.insforge/1.0.0/io.pilot.insforge-1.0.0-linux-amd64.tar.gz", "bundle_sha256": "9e1d05248b99dd66e1482aeda23ece61b2b110601c7848e3fb716f4a79ba47b6", "display_name": "Insforge", @@ -588,7 +588,7 @@ { "id": "io.pilot.orthogonal", "version": "0.1.1", - "description": "Connect your agent to Orthogonal \u2014 one key fronting 58 paid APIs / 851 endpoints (lead & contact enrichment, email & phone finding, web & social scraping, AI search, company/people/jobs data, weather, voice). Describe a task in plain English and Orthogonal's router returns the exact APIs to call; execute any of them through a single run, billed at the real per-call price and metered against a per-user $5 budget. Discovery, pricing and balance calls are free.", + "description": "Connect your agent to Orthogonal — one key fronting 58 paid APIs / 851 endpoints (lead & contact enrichment, email & phone finding, web & social scraping, AI search, company/people/jobs data, weather, voice). Describe a task in plain English and Orthogonal's router returns the exact APIs to call; execute any of them through a single run, billed at the real per-call price and metered against a per-user $5 budget. Discovery, pricing and balance calls are free.", "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.orthogonal/0.1.1/io.pilot.orthogonal-0.1.1-linux-amd64.tar.gz", "bundle_sha256": "3f2c9bfc009e41898b36ff2e88a313c0c3bc8bb39500f9673572a1d40b84fac7", "display_name": "Orthogonal", @@ -622,7 +622,7 @@ { "id": "io.pilot.mysql", "version": "9.7.1", - "description": "MySQL 9.7.1 server + client as a native CLI for agents: a full, real client/server SQL database that runs entirely locally with no cloud account and no provisioning. Initialize a data directory, start a server on 127.0.0.1, create databases, and run SQL \u2014 results as an aligned table or TSV \u2014 with the actual InnoDB engine (transactions, foreign keys, triggers, JSON, window functions). Lifecycle (initialize/start/stop/ping), createdb, query/query_tsv, databases/tables listing, mysqldump, and the full tool surface via a verbatim-argv passthrough. The transactional server-grade sibling of io.pilot.sqlite and io.pilot.postgres.", + "description": "MySQL 9.7.1 server + client as a native CLI for agents: a full, real client/server SQL database that runs entirely locally with no cloud account and no provisioning. Initialize a data directory, start a server on 127.0.0.1, create databases, and run SQL — results as an aligned table or TSV — with the actual InnoDB engine (transactions, foreign keys, triggers, JSON, window functions). Lifecycle (initialize/start/stop/ping), createdb, query/query_tsv, databases/tables listing, mysqldump, and the full tool surface via a verbatim-argv passthrough. The transactional server-grade sibling of io.pilot.sqlite and io.pilot.postgres.", "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.mysql/9.7.1/io.pilot.mysql-9.7.1-linux-amd64.tar.gz", "bundle_sha256": "74e57bee2b99cbef1cc10a1120894c6872027766509f0d8d4b252b93d1d0a9e1", "display_name": "Mysql", @@ -656,7 +656,7 @@ { "id": "io.pilot.didit", "version": "1.0.0", - "description": "Full Didit identity-verification platform over one HTTPS app \u2014 KYC/ID, liveness, face match, AML, proof-of-address, database validation, email/phone OTP, plus hosted sessions, workflows, users, billing, blocklists, questionnaires and webhooks. didit.signup mints your own Didit API key in ONE call with no email and no code (Pilot's broker handles the whole signup), caches it locally, and then every method authenticates as you and bills to your own Didit balance (500 free full-KYC checks/month).", + "description": "Full Didit identity-verification platform over one HTTPS app — KYC/ID, liveness, face match, AML, proof-of-address, database validation, email/phone OTP, plus hosted sessions, workflows, users, billing, blocklists, questionnaires and webhooks. didit.signup mints your own Didit API key in ONE call with no email and no code (Pilot's broker handles the whole signup), caches it locally, and then every method authenticates as you and bills to your own Didit balance (500 free full-KYC checks/month).", "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.didit/1.0.0/io.pilot.didit-1.0.0-linux-amd64.tar.gz", "bundle_sha256": "57c63cf5c51c10871273126b408dae17e2c4cffc5330342d96c648ca95aa29d5", "display_name": "Didit", @@ -690,7 +690,7 @@ { "id": "io.pilot.tldr", "version": "1.13.1", - "description": "tldr (tlrc 1.13.1) as native, example-first documentation for agents: simplified, community-driven man pages for ~7,350+ command-line tools, delivered to the host and fronted as typed methods. Look up a command's cheat-sheet as clean text or raw Markdown, search the whole catalog by keyword, list the directory of documented tools, refresh or inspect the local cache, render a local page, and reach every client flag (--platform, --language, --list-all, --offline, \u2026) via a verbatim-argv passthrough. Open source \u2014 MIT client, CC-BY-4.0 pages \u2014 self-contained and offline after the first fetch, on macOS and Linux.", + "description": "tldr (tlrc 1.13.1) as native, example-first documentation for agents: simplified, community-driven man pages for ~7,350+ command-line tools, delivered to the host and fronted as typed methods. Look up a command's cheat-sheet as clean text or raw Markdown, search the whole catalog by keyword, list the directory of documented tools, refresh or inspect the local cache, render a local page, and reach every client flag (--platform, --language, --list-all, --offline, …) via a verbatim-argv passthrough. Open source — MIT client, CC-BY-4.0 pages — self-contained and offline after the first fetch, on macOS and Linux.", "bundle_url": "https://pub-f09f9a4ea848491198d48e329ba030e3.r2.dev/bundles/io.pilot.tldr/1.13.1/io.pilot.tldr-1.13.1-linux-amd64.tar.gz", "bundle_sha256": "0e73bc90fcf6fd62972cf08171b2c8e56cd2adf43b42e01afdb529f084bc1407", "display_name": "Tldr", @@ -758,4 +758,4 @@ "publisher": "ed25519:BAsg7bdd2t0V9tFCkXRCWRgIdEuuWtJVEjjZp8HBgEg=" } ] -} \ No newline at end of file +} diff --git a/catalogue/catalogue.json.sig b/catalogue/catalogue.json.sig index 040c545e..f894b154 100644 --- a/catalogue/catalogue.json.sig +++ b/catalogue/catalogue.json.sig @@ -1 +1 @@ -syvhIseWmgaUmh1xuEXDOuH7T8FX0JwUE9j86UwpAWqZwQlpT0G5OazwshuePurdqNQfG7/109f++kIWc3hoDQ== \ No newline at end of file +9Qp6aYLiBA5JRGEc0a2ivunUVBc0bN4BSJptK6wKJJqVkjhWbJEqNQelOjIPnLyfaTblcR5OZNstUWi0Rt6fCw==