ワンクリックで
aso-worker
Autonomous App Store keyword optimizer — researches, audits, and updates metadata to improve organic search rankings.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Autonomous App Store keyword optimizer — researches, audits, and updates metadata to improve organic search rankings.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Phase 2 - Clarify technical requirements from product specs. Requires product-adr.md as input. Outputs tech-adr.md. Use when running /technical-requirements, clarifying technical ADRs, or moving from product requirements to a fully-specified technical specification via research, approach selection, and 15 sequential categories.
Use when finding validated tiny iOS app ideas or explicitly validating a wedge for one opportunity from an existing App Tiny Bets report. Phase 1 performs keyword-first discovery with Astro and competitor evidence. Phase 2 runs only when explicitly requested with a report and one selected opportunity, then mines competitor reviews and creates a wedge brief.
Drive a native GUI app (macOS, Windows, Linux) via the cua-driver CLI (default) or MCP server — snapshot its accessibility tree, click/type/scroll by element_index or pixel coords, verify via re-snapshot, all without bringing the target to the foreground. Use when the user asks you to operate, drive, automate, or perform a GUI task in a real application on the host.
Orchestrate and judge an issue-to-PR pipeline without editing artifacts directly. Use when the user wants an issue-to-PR workflow, task-to-PR pipeline, or structured path from request to PR readiness. Routes each stage to the owning skill or subagent, checks gate outputs, asks for revisions when the pipeline drifts, and keeps PR as a placeholder.
Review agentic system quality with a lean heuristic gate. Use when auditing, approving, improving, or quality-checking skills, agents, prompts, or agentic workflows and a verdict is needed.
Reusable verification gate for completed work before commit or merge. Use when implementation is done and Claude must prove the task works, verify the main user flow, route verification by platform, and return a PASS/FAIL/BLOCKED verdict with evidence. Web and mobile-web verification uses agent-browser. iOS and macOS verification uses xcodebuildmcp-cli.
| name | aso-worker |
| description | Autonomous App Store keyword optimizer — researches, audits, and updates metadata to improve organic search rankings. |
| version | 1 |
sum(position × popularity) / sum(popularity) for all tracked keywords where the app ranksconfig.cadence.act_days days (default 14). Agent self-adjusts based on signal quality.asc analytics)asc analytics)| What to check | How to check | Good looks like | Cadence |
|---|---|---|---|
| Keyword rankings | Astro: search_rankings, app_keywords | weighted avg position trending down | daily |
| Ranking anomalies | Astro: ranking_anomalies | no unexplained significant drops | daily |
| Keyword portfolio health | Astro: analyze_aso_health | no keywords far outside Golden Ratio thresholds | per cycle |
| Install volume | asc analytics | weekly installs trending up | weekly |
| Conversion funnel | asc analytics | impressions → page views → installs improving | per cycle |
| Keywords field utilization | asc metadata keywords diff | >90% of 100 chars used | per cycle |
| Metadata waste | Check title/subtitle tokens not duplicated in keywords | 0 wasted tokens | per cycle |
| App review status | asc status --app "$APP_ID" | submission approved, not rejected | after submission |
| Revenue (north star) | RevenueCat API or App Store analytics | trending toward $10k/month | monthly |
| Action | Tool / API | Access | Checkpoint | Verification |
|---|---|---|---|---|
| List tracked apps | Astro MCP: list_apps | ready | autonomous | app list returned |
| Get current keywords + rankings | Astro MCP: get_app_keywords, search_rankings | ready | autonomous | rankings data |
| Get keyword suggestions | Astro MCP: get_keyword_suggestions | ready | autonomous | suggestions list |
| Search App Store for competitors | Astro MCP: search_app_store | ready | autonomous | search results |
| Extract competitor keywords | Astro MCP: extract_competitors_keywords | ready | autonomous | keyword list (Pop >5) |
| Add keywords to tracking | Astro MCP: add_keywords | ready | autonomous | keywords tracked |
| Tag keywords | Astro MCP: set_keyword_tag, manage_tag | ready | autonomous | tags applied |
| Annotate keywords | Astro MCP: set_keyword_note | ready | autonomous | notes saved |
| Detect ranking anomalies | Astro local DB: ranking_anomalies | ready | autonomous | anomaly report |
| Analyze keyword trends | Astro local DB: keyword_trends, historical_rankings | ready | autonomous | trend data |
| Find low-competition keywords | Astro local DB: low_competition_keywords, keyword_opportunities | ready | autonomous | opportunity list |
| Analyze competitive landscape | Astro local DB: competitive_landscape | ready | autonomous | competitor map |
| Pull current metadata | asc metadata pull --app "$APP_ID" --version "$VERSION" | ready | autonomous | local metadata files |
| Diff metadata changes | asc metadata keywords diff | ready | autonomous | diff output |
| Apply keyword changes | asc metadata keywords apply --confirm | ready | semi-auto | keywords updated |
| Update title/subtitle | asc localizations upload --type app-info | ready | semi-auto | metadata updated |
| Validate before submission | asc validate --app "$APP_ID" --version "$VERSION" | ready | autonomous | validation passes |
| Submit for review | asc submit create --confirm | ready | semi-auto | submission created |
| Create new App Store version | asc versions create --app "$APP_ID" --platform $PLATFORM_FLAG --version "$NEXT_VERSION" --copy-metadata-from "$CURRENT_VERSION" | ready | semi-auto | version in PREPARE_FOR_SUBMISSION |
| Get latest build | asc builds latest --app "$APP_ID" | ready | autonomous | build number returned |
| Attach build to version | asc versions attach-build --app "$APP_ID" --version "$NEXT_VERSION" --build "$BUILD_NUMBER" | ready | semi-auto | build attached to version |
| Check submission status | asc status --app "$APP_ID" | ready | autonomous | status returned |
| Get app ratings | Astro MCP: get_app_ratings | ready | autonomous | ratings data |
| Pull install/conversion analytics | asc analytics --app "$APP_ID" | ready | autonomous | analytics report (installs, impressions, page views) |
| Generate weekly insights | asc insights --app "$APP_ID" | ready | autonomous | weekly trend summary |
| Read/write experiment log | filesystem: results.jsonl | ready | autonomous | file read/written |
| Read/write playbook | filesystem: playbook.json | ready | autonomous | file read/written |
http://127.0.0.1:8089/mcp (60 req/min rate limit)asc auth loginconfig.cadence.act_days)| Input | Source | Quota / Limit | Constraint | If exhausted |
|---|---|---|---|---|
| Keyword rankings data | Astro (Apple Search Ads data) | 60 req/min | updates every 24h | wait for next daily update |
| Keyword suggestions | Astro MCP: get_keyword_suggestions | 60 req/min | AI-generated, may include noise | filter with Golden Ratio |
| Competitor keywords | Astro MCP: extract_competitors_keywords | keyword must be tracked first | only returns Pop >5 | track keyword first, then extract |
| App Store search results | Astro MCP: search_app_store | max 100 results per query | live search | use different seed terms |
| App Store Connect metadata | asc CLI | Apple API rate limits | review takes ~1 day | wait for approval |
| Install/conversion analytics | asc analytics | Apple API rate limits | data available ~24h delayed | use last available data |
| Weekly insights | asc insights | Apple API rate limits | generated from analytics data | use analytics directly |
This worker is self-contained. All files live within the skill directory:
aso-worker/
SKILL.md # instructions (human-owned)
soul.md # judgment principles (human-owned)
references/ # schemas and examples (human-owned)
config.schema.json
results.jsonl # example entries
playbook.json # example structure
data/ # runtime artifacts (agent writes here)
config.json # app config (shared)
results.jsonl # experiment log (agent-owned)
playbook.json # strategy (agent-owned)
proposals/ # cycle proposals for human review (agent-owned)
Before running, create data/config.json in the skill directory.
Schema: See references/config.schema.json for full field definitions, types, defaults, and constraints.
Example (Streaks: Zero Proof):
{
"app_name": "Streaks: Zero Proof",
"app_id": "6746278101",
"store": "us",
"platform": "ios",
"seed_keywords": ["sobriety tracker", "quit drinking", "alcohol free", "sober"],
"problem_domain": "alcohol-free living, sobriety tracking, habit tracking for quitting drinking",
"current_metadata": {
"title": "Streaks: Zero Proof",
"subtitle": "Alcohol-free sobriety tracker",
"keywords": ""
},
"golden_ratio": {
"min_popularity": 20,
"max_difficulty": 50,
"target_difficulty": 30
},
"cadence": {
"observe_hours": 24,
"act_days": 14,
"verify_preliminary_day": 5,
"verify_final_day": 10,
"preferred_submit_days": ["tuesday", "wednesday"]
},
"autonomy": "semi-autonomous",
}
Key fields:
seed_keywords: starting points for keyword discovery. The worker expands from here.problem_domain: plain English description of what the app solves. Used to judge keyword relevance.golden_ratio: thresholds for keyword filtering. Start conservative (max_difficulty: 50 for new apps with no ratings), loosen as app gains authority.current_metadata: snapshot of what's live. The worker updates this after each successful submission.platform: "ios" or "mac" — works for both iPhone and Mac apps. CLI platform flag mapping: When config.platform is "ios", use --platform IOS in all asc commands that accept a platform flag. When config.platform is "mac", use --platform MAC_OS. This affects asc versions create, asc metadata pull, asc metadata keywords apply, asc submit create, and other platform-scoped commands.data/config.json — load app identity, thresholds, cadence, current metadatadata/results.jsonl entries — understand what keywords have been tested and their outcomes. Pay attention to per_keyword outcomes and learnings_extracted from recent verifications.data/playbook.json — current best-known keyword strategy. Key fields: failed_keywords (never re-propose), winning_keywords (protect), learnings (apply as filters in research).asc analytics (if data is stale)config.cadence.act_days days since last submission)problem_domain. A high-Pop, low-Diff keyword that doesn't match what the app does will get rejected by Apple or disappoint users. Both are worse than not ranking.playbook.json.learnings, and design the next cycle to avoid the same pattern. Reverting to the previous metadata wastes an entire cycle re-proving what you already knew.extract_competitors_keywords and competitor eye-icon research to find keywords that are already working for similar apps, then filter through Golden Ratio.golden_ratio range and only loosen max_difficulty as the app gains authority (ratings, downloads). Re-evaluate thresholds when the app reaches meaningful rating milestones.playbook.json.learnings before every research phase. Each cycle should produce at least one new learning. Over time, the playbook becomes the accumulated intelligence — more valuable than any single cycle's keyword list.asc metadata keywords diff before apply. Always run asc validate before submit.asc CLI error → retry once. If it fails again, defer the submission to next cycle. The research and audit work is still valid — save it.anomaly in Astro, add note with datealgorithm_alert. Pause metadata changes until daily rankings stabilize — when day-over-day variance returns to normal levels.asc analytics periodically (weekly is sufficient — skip if data is recent)results.jsonl (one JSON line with type observation, date, weighted_avg_position, keywords_tracked, keywords_ranked, top10_count, anomalies array)config.cadence.act_days days)B1. Audit current portfolio
B2. Research new keywords
failed_keywords (never re-propose these), winning_keywords (protect these), learnings (apply as filters), and keyword_angles_untried (explore these).neutral — they almost worked, try them in stronger positions). Mine fresh competitors — search for new apps that appeared recently in your space. Flip the angle entirely (e.g., if targeting the problem "sobriety tracker", try the aspiration "healthy living" or the trigger "quit drinking"). Re-read ALL learnings as a batch looking for meta-patterns across failures.extract_competitors_keywordsfailed_keywordsproblem_domainplaybook.json.learnings (e.g., if "keywords containing 'free' attract wrong audience" is a learning, filter those out)add_keywordscandidate in AstroB3. Optimize metadata
action entry.popularity / (difficulty + 1)data unavailable and explain why.asc metadata keywords diff to preview the changeresults.jsonl (one JSON line with type action, status proposed, before/after keywords, hypothesis, variable_changed, measurement_plan, rationale, score_before, installs_before)B4. Submit (semi-autonomous checkpoint)
Prerequisites — Version creation (required before keywords can be applied): Keywords in the App Store are locked to a specific version. You cannot update keywords on a live version — you must create a new version first. This applies to BOTH iOS and Mac apps.
config.platform is "mac", set $PLATFORM_FLAG to MAC_OS. If "ios", set it to IOS. Use this flag in all asc commands below.asc status --app "$APP_ID" to see if there's already a version in PREPARE_FOR_SUBMISSION state. If yes, skip to step 5.asc versions create --app "$APP_ID" --platform $PLATFORM_FLAG --version "$NEXT_VERSION" --copy-metadata-from "$CURRENT_VERSION". The --copy-metadata-from flag carries over description, screenshots, and other metadata so you only need to change keywords. Use a minor version bump (e.g., 1.1 → 1.2) for metadata-only updates.asc builds latest --app "$APP_ID"asc versions attach-build --app "$APP_ID" --version "$NEXT_VERSION" --build "$BUILD_NUMBER"asc validate --app "$APP_ID" --version "$NEXT_VERSION"faildata/proposals/cycle-NNN-proposal.md containing: hypothesis, before/after keywords diff, rationale, current score, expected outcome, the full proposal evidence table, and any required Difficulty > 50 justifications. Also output the same report in chat.asc metadata keywords apply. Wait for human approval before proceeding.asc metadata keywords apply --confirm --platform $PLATFORM_FLAG, then asc submit create --confirm --platform $PLATFORM_FLAGresults.jsonl status from proposed to submitted, add submission timestampEvery proposal markdown file (data/proposals/<app>-cycle-NNN-proposal.md) is a validation target. A valid proposal MUST contain all of the following:
100/100 chars) MUST be stated inline. Total length MUST be ≤ 100 characters.Pop) and Difficulty (Diff) values sourced from Astro MCP. No blanks, no dashes. If Astro is unavailable, write data unavailable and explain why.config.golden_ratio.max_difficulty must appear in a dedicated justification section with a written rationale for why it is still worth targeting given the app's current authority.scripts/validate-aso-proposal.py samples 5 deterministic keywords from the proposed set and requires Astro Pop/Diff values to match the proposal within ±3.B5. Verify (preliminary + final checkpoints after submission)
config.cadence.verify_preliminary_day after submission): check if new keywords are appearing in rankings at all. If completely absent, suspect metadata issue.config.cadence.verify_final_day after submission): compute weighted avg position delta vs pre-submission baselinekeep (clearly improved), neutral (negligible change), fail (clearly worsened or still unranked after multiple cycles). Use judgment — a 1-position change is noise, a 10-position change is signal.asc analytics for the verification window. Compare weekly installs and conversion rate (impressions → page views → installs) before vs after the metadata change.hypothesis and measurement_plan from this cycle's action entry. Compare actual outcomes against predicted outcomes. Grade the hypothesis: confirmed (prediction matched within reasonable margin), partially_confirmed (directionally correct but magnitude was off), or refuted (prediction was wrong). Record the grade, the expected vs actual delta, and a one-sentence explanation of why the prediction was right or wrong. Feed the explanation into learnings — a refuted hypothesis is the most valuable data point.results.jsonl (one JSON line with type verification, score_after, score_delta, per_keyword array, installs_after, installs_delta, conversion_after, hypothesis_grade, hypothesis_expected, hypothesis_actual, hypothesis_explanation, learnings_extracted)keep keywords to winning_keywordsfail keywords to failed_keywordslearnings arraykeyword_angles_untried to keyword_angles_triedcurrent_metadata.keywords (and title/subtitle if changed) to reflect what's now live. Write the updated config.json file to disk.golden_ratio.max_difficulty. Log the recommendation — don't auto-change config.Creative exploration happens every cycle via B2 Research (exploit/explore mode). The stall rule handles deeper problems:
The default act_days is a starting point, not a permanent setting. After each verification, assess whether the cadence fits the observed reality:
verify_preliminary_day — the cycle has dead time. E.g., if the last 2-3 verify windows showed rankings settled days early, reduce act_days and verify days proportionally.verify_final_day — the measurement is unreliable. E.g., if the last verification showed significant position movement between preliminary and final check, the cycle is too short.verify_final_day — the cadence fits.Log cadence changes to results.jsonl. Update config.json when adjusting.
| Rankings | Installs | Revenue | Diagnosis | Action |
|---|---|---|---|---|
| Improving | Improving | Improving | Working — full funnel healthy | Exploit: refine winning keywords, target slightly harder ones |
| Improving | Improving | Flat | Rankings drive traffic but monetization is weak | Escalate: problem is paywall, pricing, or onboarding |
| Improving | Flat | Flat | Rankings help but impressions aren't converting to page views | Escalate: problem is app icon, screenshots, or title/subtitle appeal |
| Flat | Flat | Flat | Keywords aren't moving the needle | Explore: try different keyword angles, different competitor clusters |
| Worsening (broad, many keywords) | Dropping | Any | Suspected algorithm change | Freeze metadata changes. Wait for stabilization. Log algorithm_alert. Compare against ASO community reports. |
| Worsening (narrow, few keywords) | Stable | Any | Competitor surge on specific keywords | Research who's now outranking you. Consider pivoting those keywords to lower-diff alternatives. |
| Any | Any | Improving without ranking/install change | External factor (press, word of mouth, seasonal) | Record the external event. Don't attribute to keyword changes. |
| File | Owner | Agent may |
|---|---|---|
SKILL.md | Human | Read only. Never modify. |
soul.md | Human | Read only. Never modify. |
references/config.schema.json | Human | Read only. Never modify. |
data/config.json | Shared | Read always. Write only to current_metadata and cadence fields after submissions or cadence tuning. Never change app_name, app_id, store, platform, seed_keywords, problem_domain, or autonomy. |
data/results.jsonl | Agent | Append entries. Archive when large. |
data/playbook.json | Agent | Read and rewrite after each verification. |
The human programs the worker by editing SKILL.md and soul.md. The agent programs itself by evolving playbook.json and tuning config.json cadence. These boundaries are strict.
config.json → results.jsonl (tail) → playbook.jsonresults.jsonl (enough to understand the last few cycles). For deeper analysis (stall rule), read further back. When the file gets large, archive older entries to results-archive.jsonl to keep the active file manageable.All runtime files live in data/ within the skill directory.
Each line is one JSON object. Entry types: baseline, observation, algorithm_alert, action, verification.
See references/results.jsonl for annotated examples of each entry type.
Accumulated keyword intelligence. Updated after each verification.
See references/playbook.json for a complete example with all fields.
SKILL.md, soul.md, or references/config.schema.json — these are human-owned instructionsconfig.cadence.act_days)asc CLI)algorithm_alert, wait for stabilization before resumingasc CLI: update keywords, title, subtitle, submit for review)The first cycle folds baseline gathering into its research phase, then immediately proposes a metadata change.
Research phase (baseline):
config.json to load app identity and seed keywordsadd_app (if not already tracked)add_keywords (store: "us")asc metadata pullbaseline entry to results.jsonl (snapshot of initial state)Action phase (proposal):
9. Run keyword audit: filter tracked keywords through Golden Ratio
10. Formulate hypothesis for first metadata change
11. Rank candidates by popularity / (difficulty + 1)
12. Draft optimized keywords field (100 chars, no waste, no duplication with title/subtitle)
13. Run asc metadata keywords diff to preview
14. Write proposal to data/proposals/cycle-001-proposal.md and output in chat
15. Log action entry to results.jsonl with status proposed
16. If semi-autonomous: STOP. Wait for human approval before applying.
Expected output: baseline entry + action entry in results.jsonl, 20-50 keywords tracked in Astro, one metadata proposal with hypothesis and before/after diff