{"id":73085,"plugin_id":"plugin_asdk_app_6ac7e973de8481919c3e30951be3e9d9","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-31T01:17:50.649Z","digest":"1068e7e3b90ae39e21437334ef5d2dfc41c96c606cd53b8b68eee207c02d446f","against":null,"payload":{"description":"Find an app on the App Store / Google Play and start tracking it in AppFollow, then hand structured app references to the feedback-analysis and aso-analysis skills. Read-only search + dedupe works on any plan; the add step degrades gracefully when the plan does not allow writes. Trigger on \"find app X\", \"track our app\", \"add <app> to AppFollow\".\n","included_files":[],"name":"search","skill_md_contents":"---\nname: search\ndescription: >\n  Find an app on the App Store / Google Play and start tracking it in AppFollow, then hand structured\n  app references to the feedback-analysis and aso-analysis skills. Read-only search + dedupe works on any\n  plan; the add step degrades gracefully when the plan does not allow writes. Trigger on \"find app X\",\n  \"track our app\", \"add <app> to AppFollow\".\n---\n\n# search — find + track apps\n\nRead `using-appfollow` first (session opening, write ritual, error codes).\n\n## Inputs\n\n- `query`: app name (free-text search keywords).\n- `store`: `as` (App Store), `gp` (Google Play), `ms`, `am` (Amazon).\n- `country` (default `us`), `collection` (name; created if new), `locale`.\n\n## Flow\n\n0. **Session:** `whoami` (see `using-appfollow`).\n1. **Normalize input.** Search takes free-text keywords only — the ASO search endpoints do not accept\n   a store URL or an `ext_id`. Trim the query to the app name (strip any pasted URL down to the app\n   name/title before searching).\n2. **Search (read-only, any plan).** Call `aso_search_results` (optionally `aso_search_suggestions`,\n   5 cr). Present numbered candidates. Auto-pick only a single exact-title match; otherwise the user\n   picks.\n3. **Resolve collection.** `list_collections`. If the target collection is new, run\n   `add_collection_preview` → user approval → `add_collection`.\n4. **Dedupe (read-only).** `list_apps`; if the app is already tracked, record it under\n   `skipped_existing` and skip the add.\n5. **Add (write — may be plan-gated).** `add_app_preview` → **explicit user approval** → `add_app`\n   with identical args. Valid stores: `as`, `gp`, `ms`, `am`.\n6. **Verify.** `list_apps` again; confirm the app now appears; capture its `apps_id`.\n7. **Emit** the JSON block (below).\n\n## Read-only degrade path (plan-gated writes)\n\n`add_app` and `add_collection` require an **Advanced API / Custom** plan, and those routes carry **no\nfeature gate** — so a plan block does **not** arrive as `FEATURE_DISABLED`. It can surface as\n`AUTH_REQUIRED`, `VALIDATION_ERROR`, or `UPSTREAM_ERROR`. Therefore:\n\n- Always complete search + dedupe (read-only — works on any plan).\n- Attempt the `add_*` confirm.\n- On **any** error code from the add, **do not** assert a specific code. Report the candidate refs you\n  found, state plainly that the add could not be completed (likely a plan limitation), and list the\n  found refs under `not_added` so the report skills can still target them (they may already be tracked).\n\n## Output (fenced JSON)\n\n```json\n{\n  \"added\": [{\"store\": \"as\", \"ext_id\": \"389801252\", \"apps_id\": 12345, \"collection\": \"Core apps\", \"locale\": \"en-US\", \"title\": \"Example App\"}],\n  \"skipped_existing\": [],\n  \"not_added\": [],\n  \"collection_created\": null,\n  \"credits_spent_estimate\": 2\n}\n```\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}