iOS App Store Submit
ZestfulPulse/ios-app-store-submit
Build, sign, and submit a Flutter/iOS app to the App Store Connect — covers Xcode archive/export, code signing (including headless-Mac keychain workarounds), the asc CLI for App Store Connect…
Take a Flutter project to an iPhone or the App Store with Odevio - build, sign and publish iOS apps from Windows, Linux or macOS with no Mac and no Xcode.
$ npx skills add Odevio/Odevio-CLI --skill odevio -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Odevio/Odevio-CLI odevio --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/Odevio/Odevio-CLI.git skills-src && mkdir -p .claude/skills && cp -r skills-src/src/odevio/skill .claude/skills/odevio && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "odevio" agent skill from https://github.com/Odevio/Odevio-CLI/tree/master/src/odevio/skill into .claude/skills/odevio/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "odevio", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Odevio/Odevio-CLI/tree/master/src/odevio/skillType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Odevio/Odevio-CLI --skill odevio -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Odevio/Odevio-CLI odevio --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Odevio/Odevio-CLI.git skills-src && mkdir -p .agents/skills && cp -r skills-src/src/odevio/skill .agents/skills/odevio && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "odevio" agent skill from https://github.com/Odevio/Odevio-CLI/tree/master/src/odevio/skill into .agents/skills/odevio/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "odevio", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Odevio/Odevio-CLI --skill odevio -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Odevio/Odevio-CLI odevio --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Odevio/Odevio-CLI.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/src/odevio/skill .cursor/skills/odevio && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "odevio" agent skill from https://github.com/Odevio/Odevio-CLI/tree/master/src/odevio/skill into .cursor/skills/odevio/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "odevio", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Odevio/Odevio-CLI.git --path src/odevio/skill--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Odevio/Odevio-CLI --skill odevio -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Odevio/Odevio-CLI odevio --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Odevio/Odevio-CLI.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/src/odevio/skill .gemini/skills/odevio && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "odevio" agent skill from https://github.com/Odevio/Odevio-CLI/tree/master/src/odevio/skill into .gemini/skills/odevio/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "odevio", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Odevio/Odevio-CLI odevioInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Odevio/Odevio-CLI --skill odevio -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Odevio/Odevio-CLI.git skills-src && mkdir -p .github/skills && cp -r skills-src/src/odevio/skill .github/skills/odevio && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "odevio" agent skill from https://github.com/Odevio/Odevio-CLI/tree/master/src/odevio/skill into .github/skills/odevio/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "odevio", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Odevio/Odevio-CLI --skill odevio -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Odevio/Odevio-CLI odevio --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Odevio/Odevio-CLI.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/src/odevio/skill .opencode/skills/odevio && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "odevio" agent skill from https://github.com/Odevio/Odevio-CLI/tree/master/src/odevio/skill into .opencode/skills/odevio/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "odevio", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
odevioTake a Flutter project to an iPhone or the App Store with Odevio - build, sign and publish iOS apps from Windows, Linux or macOS with no Mac and no Xcode.
Odevio is an agent skill from Odevio/Odevio-CLI. Take a Flutter project to an iPhone or the App Store with Odevio - build, sign and publish iOS apps from Windows, Linux or macOS with no Mac and no Xcode. Handles Apple setup, certificates, provisioning profiles, code signing, the .ipa, TestFlight and App Store submission, and fixes build failures automatically. Use for: publish my app, build for iOS without a Mac, get my app on my iPhone or in TestFlight, sign my app, App Store submission, build failed.
Its SKILL.md is about 7.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 7 other files, including reference files (for example `references/app-store-listing.md`, `references/cli-contract.md` and `references/delivery.md`).
It sits in Mobile, covering App store release, iOS development and Cross-platform mobile apps. It works with Flutter, iOS, App Store Connect and Xcode. The repository describes itself as: Build, sign and publish iOS apps from any OS - no Mac, no Xcode. Driven by your AI agent. The licence is MIT.
5 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit f54272e. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
Bash(odevio --version:*)Bash(odevio --version)Bash(COLUMNS=200 odevio --version:*)Bash(COLUMNS=200 odevio --version)Bash(odevio --help:*)Bash(odevio --help)Bash(COLUMNS=200 odevio --help:*)Bash(COLUMNS=200 odevio --help)Bash(odevio profile:*)Bash(odevio profile)…and 134 more on the same allowed-tools line.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
flutterpippipxdartFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use pip and pipx, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Odevio loads about 7.6k tokens when it runs, and up to ~27k if it reads all its reference files. Until then it costs about 116 tokens; SKILL.md has 3,491 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from Odevio/Odevio-CLI at commit f54272e, republished under its MIT licence (© Odevio). 3,491 words, ~7,631 tokens.
.claude/skills/odevio/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.Odevio builds and signs iOS apps on remote Macs. The user needs no Mac and no iOS knowledge: certificates, provisioning profiles and app identifiers are already automated. This skill drives the whole path and asks as little as possible.
Read this file fully before acting. Then read a reference only when its situation arises:
| Reference | Read it when |
|---|---|
references/first-time-setup.md | no Apple developer account registered, or no Odevio app for this project |
references/when-a-build-fails.md | a build failed |
references/delivery.md | a build succeeded |
references/app-store-listing.md | the goal is the App Store — read it before building, not after |
references/cli-contract.md | you are unsure how a command behaves — it records what was learned by getting it wrong |
references/voice.md | always, before acting - how to speak; the words never to use |
This skill drives the odevio command; it does nothing without it. If you reached this skill through
discovery rather than odevio skill install, the CLI may not be present yet. Check once, install if missing:
odevio --version || pip install odevioUse pipx install odevio instead if this machine's Python is externally managed. Then, so the commands
below run without a permission prompt each time, register the skill for your agent once:
odevio skill installNeither step re-does anything already done — both are safe to run when Odevio is already set up.
This matters as much as the mechanics. The words never to use, when to stay silent, and how to ask a
question live in references/voice.md. Read it before you act - it is not optional.
Their goal decides the kind of build, whether Apple's side needs setting up at all, and what "done" means. It is the one thing you cannot read from the project.
If the way they asked already says it — "get my app on my phone", "publish it", "does this even build" — take it and never ask again.
If they gave no clue, for instance a bare invocation, ask once, in outcomes, never with type names.
Offer these five, and all five, whatever form the question takes:
| Offer it as | Never as |
|---|---|
| See it running on a Mac we provide | a configuration build, a remote desktop |
| Try it on your own iPhone | ad-hoc |
| Share it with a few testers, through TestFlight | publication |
| Put it on the App Store | publication |
| Just check that it compiles | distribution |
Publishing to the App Store is its own answer, and the one most easily lost. It shares a build with the testers option, which makes it tempting to fold the two together — do not. They lead to entirely different work: testers means the app is with Apple and you are finished, while the App Store means a page has to be written, pictures provided and a questionnaire answered. Someone who meant to publish and was offered only "send to testers" has no way of knowing the rest exists.
The wording of each option is what the user reads, so no build type ever appears in it — not in the heading, not in the explanatory line underneath. "Sends it to Apple and puts it in front of your testers" says what happens. "Build publication — envoi chez Apple" leaks the machinery and tells them nothing they can act on.
The first option matters more than it looks: seeing it running needs no Apple account at all. Everything else on that list requires a paid Apple developer account, so for someone who has not paid yet, that is the only thing you can offer today — and it is a real one, not a consolation prize.
Do not skip this and default to compiling. A silent assumption is worse than a question here: it spends a quarter of an hour producing something they did not ask for, and the App Store route needs a manual step that the others do not.
If they said the App Store, read the page before doing anything else. Not after building — before. Go to
references/app-store-listing.md now and run odevio app store-status.
The reason is concrete: Apple may already hold a build. Building takes a quarter of an hour and occupies a machine someone else is waiting for, and there is no point spending either if what is needed is a description and three pictures. Only the page can say which of the two it is.
Then say what the whole thing involves, and what you are about to do first. Sending the app is the easy half; the page has to be filled in too, and two parts of it can only be done on Apple's own website:
Right — the App Store. Two things there that only you can do, about ten minutes in total: creating the app's page, and answering Apple's questions about data. I will tell you exactly what to click.
Let me look at where your page stands before anything else — if your app is already with Apple there is no need to build it again.
Only once the page has been read does building become a question, and then it is one to put to them rather
than assume. references/app-store-listing.md covers the three cases.
Read the state before asking anything. Stop at the first blocking check.
Run as few commands as will do. Every one appears in front of the user as a block of shell and output, and a screenful of it before the first sentence makes a tool that promised to handle things look like it is rummaging. Two rules keep it short:
odevio profile proves the CLI is
installed and that there is a session, so odevio --version on top of it earns nothing. Their version
is worth having only when something has already gone wrong.| # | Check | If missing |
|---|---|---|
| 1 | odevio profile — is the CLI there, and is there a session? | blocking — if the command is not found, offer pip install odevio and stop; do not install it yourself, as the wrong Python environment is worse than none. If it asks for credentials, see below |
| 2 | odevio app ls — an app matching this project? | references/first-time-setup.md |
| 3 | odevio apple ls — any Apple account registered? Only needed when step 2 found nothing, since an app already carries its account | references/first-time-setup.md |
| 4 | pubspec.yaml and lib/ present? | blocking — say they are not in a Flutter project and stop, rather than uploading an unrelated directory |
From pubspec.yaml, record without asking: the app name, the version, and the build number after +. Note
any .odevio file, and the identifier already configured in the project.
Match step 2 against that identifier. A match settles both the app and the Apple account, so neither is asked. Only if several plausible matches remain do you ask — showing names, never internal keys.
If step 1 asks for credentials, this is one of the hand-overs. You cannot sign in for them: these commands prompt, and a prompt without a terminal dies on an error rather than working.
You need to sign in to Odevio first — run
odevio signinin your terminal, it'll ask for your e-mail and password. Tell me when it's done and I'll carry on from there.
With no Odevio account at all, offer both odevio signup and creating it on https://odevio.com, usually
gentler the first time. When they say they are done, verify with odevio profile rather than taking their
word.
What the user sees from this step: almost nothing. These checks are your bookkeeping. When everything is in place, that is one warm sentence and you carry on.
Before spending a remote build, run what costs nothing:
flutter pub get — failures here are a typo in pubspec.yaml, or a package that does not existdart analyze — catches most beginner mistakesflutter test — skip silently when there is no test directory; a fresh project with no tests is normalFix what they report locally, in a loop, without touching Odevio.
Do not run flutter build apk. It needs the whole Android toolchain, which the user may not have, and an
Android failure says nothing about an iOS build — a pass gives false confidence, a failure sends you chasing
an irrelevant problem.
Do not attempt an iOS build locally. Not having a Mac is the whole reason Odevio exists.
Be honest about what this proves: nothing about iOS. Native plugins, CocoaPods, Xcode configuration and the deployment target can only surface on the remote build. A project can pass all three checks and still fail on iOS — that is the normal case this skill exists to handle.
The goal came from Step 0. Translate it here, and never discuss type names with the user — they do not know them and explaining them is not a service.
Everything in this table is for you. None of its wording belongs in a message or in a list of choices,
and the right-hand column least of all. Copying a row into an option is how publication and ad-hoc end up
in front of someone who came here to avoid exactly that.
| What they said they want | Type |
|---|---|
| see it running, without paying Apple anything | configuration — a Mac desktop with their project and the iOS simulator. No Apple account, no certificate, no app needed |
| try it on their own phone, nothing shared | ad-hoc — installs straight from a link or QR code, needs the device registered first |
| share it with a few testers | publication — uploads to Apple, feeds TestFlight |
| put it on the App Store | do not come here first — references/app-store-listing.md decides whether a build is needed at all, since Apple may already hold one. When one is needed it is publication, the same as the testers option, with entirely different work afterwards |
| just check that it builds | distribution — builds and signs, uploads nothing |
A configuration build is the only type that survives without Apple credentials: the server tolerates the
failure to send them for this type alone. See references/delivery.md for what to tell them about it.
If you reach this point still not knowing, go back to Step 0 and ask. Do not pick one on their behalf.
Do not run a verification build first. It costs a full fifteen minutes and a slot on a shared Mac to produce something that cannot be installed, and then the real build has to run anyway. For a project that compiles — the common case — the whole job should be one build.
What the server actually meters, checked in its code, makes this safe:
validation and publication count towards it. distribution and ad-hoc count for nothingFAIL and STOP are excluded from the statuses consideredSo retrying a failed publication is free of quota consequences, and there is no reason to detour through a
throwaway build.
Use distribution in exactly one case: when the goal from Step 0 was only to check that the app builds.
One thing to watch, for a free account only: a publication that is queued or running does count while it is in flight. So never launch a second one alongside it — which the rule against two concurrent builds already covers.
COLUMNS=200 odevio build start <app-key> <project-dir> \
--build-type <type> --no-progress --flutter <version> --build-number <n>COLUMNS=200 in front of the command itself, as above — never export COLUMNS=200; followed by
the command. The default 80-column formatting wraps long values onto continuation lines and silently
breaks parsing, but a chained command also loses the permissions this skill was granted, so the user is
asked to approve something that should have been silent. See the rule on running one command at a time--build-number on every attempt, or a reused number triggers an interactive confirmationTake the key from the output, between the quotes:
Build #8 has been registered. It has key "K7B3Q" and will be started as soon as possible.No key means stop. Never continue without knowing which build to follow.
Watch it without blocking yourself. Start the watcher in the background, so you stay able to answer while
it runs, and let it tell you when something changes. Never sit in a foreground loop of sleep calls: it locks
you up for minutes at a time, and you have just promised the user they can ask you anything — a promise you
cannot keep while blocked. If the host offers no way to watch in the background, say honestly that you will
check back rather than claiming to be reachable.
Warn them that starting the watcher asks for approval. Whatever runs a background task is not among the commands this skill was granted in advance, and deliberately so: it can carry any shell command inside it, so pre-approving it would quietly undo the care taken to have anything touching Apple confirmed. The user therefore sees a prompt full of shell they have no way to judge, at the exact moment you told them to relax.
Put the loop in the command itself, never in a script file you then run. Approving zsh /tmp/…/watch.sh
asks someone to trust a path they cannot read; approving the loop shows them a poll of odevio build detail
and a sleep, which is at least judgeable. Same prompt either way — one of them treats them as an adult.
Say what it is before it appears, in the same message as the waiting one:
Your app is building. Your tool will ask you to approve one thing — it is just how I keep an eye on the build without blocking this conversation. Allow it and there is nothing else to do.
What to watch: COLUMNS=200 odevio build detail <key>, roughly every 20 seconds, reading the Status : line.
Stop on any end state — Succeeded, Failed, Stopped, or Configuration for remote desktop — not only
on the first two:
Waiting for available instance → In progress - Starting instance
→ In progress - Preparing build → In progress - Building app → Failed or SucceededA configuration build never reaches Succeeded. Its finish line is a different status,
Configuration for remote desktop, because the Mac is now waiting for the user rather than having produced
something. Watch for that one, and treat it exactly as success — the moment it appears, fetch the connection
details and hand them over without being asked. Waiting for Succeeded on this type means waiting for ever
while the user sits in front of a ready machine.
Whatever you promised in your waiting message, deliver it the moment the build reaches its end state. If you said "I'll give you the connection details as soon as it's ready", that is a commitment to act on the transition, not something to produce when prodded.
Translate for the user, never quote: waiting for a free Mac; the Mac is starting up; getting your project
ready; compiling, which is the long part; and for a configuration build, your Mac is ready.
Three things to handle:
If they ask where it's at, answer from a fresh build detail, in plain words, then say again there is
nothing to do and go back to watching. Being interrupted must never start a second build — resume
following the one already running. If they ask you to stop: odevio build stop <key>.
Measured on an empty project, so a floor rather than an average:
| Queueing | VM start and preparation | Xcode archive | Whole build |
|---|---|---|---|
| 8 min 30 s | ~8 min | 8 min 51 s | 15 min 9 s |
The same compile takes 30 seconds on a developer's own machine — the VM is about seventeen times slower. Tell them an attempt takes roughly fifteen minutes, and never suggest it will be quick.
Never run two builds at once for the same project: there are two slots on one Mac for every Odevio user, and two builds slow each other down.
Failed → references/when-a-build-fails.md. Classify before touching anything: changing their code
because of an infrastructure problem is the worst thing this skill can do, and they will not notice.
Succeeded → references/delivery.md. What they actually get depends on the type, and a distribution
build produces nothing installable.
Never fabricate a value the user must own. Identifier, app name, Apple credentials: derive or propose, then let them confirm. Never invent an Apple ID, a team, or a key.
Stop cleanly rather than continue blind. If a command fails in a way this skill does not cover, or output cannot be parsed, report exactly what happened and stop. A wrong guess costs a fifteen-minute slot, or a broken project.
Never print secrets. The .p8 key is referenced by path only.
Every Odevio command must be non-interactive. Pass every argument explicitly. If a command opens a menu or asks for confirmation, you omitted an argument — supply it rather than answering the prompt.
Run one command per call. No ;, no &&, no pipes into head, no export on a line of its own. The
harmless-looking read commands are pre-approved so the user is never interrupted by them, and that only works
when the command runs on its own: chain two together and the whole thing stops being recognised, so someone
who asked for their app to be published is instead asked to approve a shell command they cannot judge.
Read the whole output rather than piping it through head. It is short, and truncating it is how the wrong
value gets parsed.
Some commands are deliberately not pre-approved, and the line is not "does it change anything on Apple". Filling in a description changes something on Apple, and interrupting someone to confirm it would be absurd. The three things that earn a question are:
odevio app check-submittable opens a review submission Apple never lets you
delete, and submitting for review is finalodevio build start, and the simulator commands, take a Mac for up to an hour
that someone else is waiting forodevio screenshot push clears the pictures already
on a slot before sending, and pictures uploaded directly to Apple exist nowhere elseEverything else is fair to run unannounced: writing the page's text, attaching a build, reading anything. All of it is reversible, none of it is visible outside their own account, and stopping to ask turns a tool that was supposed to handle the tedium into a series of dialogues.
Never invent a command, and never invent an option either. If you find yourself reaching for one that is
not written in these files, it almost certainly does not exist — odevio device does not, for instance, and
odevio build ls --app-key does not either. Check with odevio --help or odevio <group> --help before
running anything you have not seen here, and if the thing you need has no command, it is because a human has
to do it somewhere else. Say that instead of guessing.
Options are the easier mistake of the two, because a plausible flag reads like something that must be there.
build ls filtering by app is the obvious example: it sounds inevitable, and it does not exist. Filter the
output yourself rather than inventing the argument that would have done it for you.
The full surface, so there is no need to guess: top-level signup, signin, signout, profile, apikey,
skill; and the groups build (start, ls, detail, logs, ipa, download, patch, connect,
tunnel, stop, rm, flutter-versions), apple (ls, detail, add, edit, rm, link, unlink,
refresh-devices), app (ls, mk, rm, link, unlink, import, screenshots, store-status,
set-metadata, categories, attach-build, check-submittable), privacy (scan), screenshot (devices, start, capture, push) and team.
One of those is not like the others. odevio app check-submittable opens a submission on Apple that
cannot afterwards be deleted. It gives Apple's own verdict, which is worth having, but only run it when the
user means to finish — never to check on progress. odevio app store-status answers that, and changes
nothing.
© Odevio, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 6 other files (references) in src/odevio/skill of Odevio/Odevio-CLI.
Open the folder on GitHubat commit f54272e
Odevio next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Odevio this skillOdevio/Odevio-CLI | 423 | — | ~7.6k | Automated safety check: Pass | MIT | |
| iOS App Store SubmitZestfulPulse/ios-app-store-submit | 142 | — | ~4.7k | Automated safety check: Pass | MIT | |
| Asc Xcode Buildrorkai/app-store-connect-cli-skills | 1.1k | 2 repos | ~2.1k | Automated safety check: Pass | MIT | |
| Limrun Xcodesuperset-sh/superset | 15k | — | ~6.5k | Automated safety check: Notes | Custom licence | |
| Eas Simulatorexpo/skills | 2.7k | — | ~6.6k | Automated safety check: Notes | MIT | |
| App Releaseglebis/claude-skills | 388 | — | ~1.4k | Automated safety check: Pass | MIT |
ZestfulPulse/ios-app-store-submit
Build, sign, and submit a Flutter/iOS app to the App Store Connect — covers Xcode archive/export, code signing (including headless-Mac keychain workarounds), the asc CLI for App Store Connect…
rorkai/app-store-connect-cli-skills
Build, archive, generate export options, export, upload, and manage Xcode version/build numbers with the current asc xcode helpers.
superset-sh/superset
Build an iOS / Apple app on remote Xcode with lim xcode build instead of local xcodebuild, run project commands with lim xcode run, or run its XCTest suites with lim xcode test, from any environment…
expo/skills
Run and control a user's app on a remote iOS/Android simulator hosted on EAS cloud.
glebis/claude-skills
End-to-end pipeline for releasing an iOS / watchOS app to TestFlight and the App Store.
revfactory/harness-100
Full mobile app development pipeline. An agent skill from revfactory/harness-100.
Categories
Take a Flutter project to an iPhone or the App Store with Odevio - build, sign and publish iOS apps from Windows, Linux or macOS with no Mac and no Xcode. Odevio is an agent skill from Odevio/Odevio-CLI. Take a Flutter project to an iPhone or the App Store with Odevio - build, sign and publish iOS apps from Windows, Linux or macOS with no Mac and no Xcode.
Odevio fits situations like: : publish my app; build for iOS without a Mac; get my app on my iPhone; app Store submission.
Run `npx skills add Odevio/Odevio-CLI --skill odevio -a claude-code`. Or copy the skill folder (src/odevio/skill in Odevio/Odevio-CLI) into .claude/skills/odevio in your project. Claude Code loads it when a task matches its description.
Run `npx skills add Odevio/Odevio-CLI --skill odevio -a codex`. Or copy the skill folder (src/odevio/skill in Odevio/Odevio-CLI) into .agents/skills/odevio in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Odevio/Odevio-CLI --skill odevio -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/odevio, .gemini/skills/odevio, .github/skills/odevio and .opencode/skills/odevio in your project.
Going by SKILL.md and its folder, Odevio needs the command-line tools its instructions call (flutter, pip, pipx and dart). Our summary lists: Python 3. Its frontmatter pre-approves these tools: Bash(odevio --version:*), Bash(odevio --version), Bash(COLUMNS=200 odevio --version:*), Bash(COLUMNS=200 odevio --version), Bash(odevio --help:*), Bash(odevio --help), Bash(COLUMNS=200 odevio --help:*), Bash(COLUMNS=200 odevio --help), Bash(odevio profile:*), Bash(odevio profile), Bash(COLUMNS=200 odevio profile:*), Bash(COLUMNS=200 odevio profile), Bash(odevio app --help:*), Bash(odevio app --help), Bash(COLUMNS=200 odevio app --help:*), Bash(COLUMNS=200 odevio app --help), Bash(odevio app ls:*), Bash(odevio app ls), Bash(COLUMNS=200 odevio app ls:*), Bash(COLUMNS=200 odevio app ls), Bash(odevio app screenshots:*), Bash(odevio app screenshots), Bash(COLUMNS=200 odevio app screenshots:*), Bash(COLUMNS=200 odevio app screenshots), Bash(odevio app store-status:*), Bash(odevio app store-status), Bash(COLUMNS=200 odevio app store-status:*), Bash(COLUMNS=200 odevio app store-status), Bash(odevio apple --help:*), Bash(odevio apple --help), Bash(COLUMNS=200 odevio apple --help:*), Bash(COLUMNS=200 odevio apple --help), Bash(odevio apple ls:*), Bash(odevio apple ls), Bash(COLUMNS=200 odevio apple ls:*), Bash(COLUMNS=200 odevio apple ls), Bash(odevio apple detail:*), Bash(odevio apple detail), Bash(COLUMNS=200 odevio apple detail:*), Bash(COLUMNS=200 odevio apple detail), Bash(odevio build --help:*), Bash(odevio build --help), Bash(COLUMNS=200 odevio build --help:*), Bash(COLUMNS=200 odevio build --help), Bash(odevio build ls:*), Bash(odevio build ls), Bash(COLUMNS=200 odevio build ls:*), Bash(COLUMNS=200 odevio build ls), Bash(odevio build detail:*), Bash(odevio build detail), Bash(COLUMNS=200 odevio build detail:*), Bash(COLUMNS=200 odevio build detail), Bash(odevio build logs:*), Bash(odevio build logs), Bash(COLUMNS=200 odevio build logs:*), Bash(COLUMNS=200 odevio build logs), Bash(odevio build ipa:*), Bash(odevio build ipa), Bash(COLUMNS=200 odevio build ipa:*), Bash(COLUMNS=200 odevio build ipa), Bash(odevio build flutter-versions:*), Bash(odevio build flutter-versions), Bash(COLUMNS=200 odevio build flutter-versions:*), Bash(COLUMNS=200 odevio build flutter-versions), Bash(odevio privacy --help:*), Bash(odevio privacy --help), Bash(COLUMNS=200 odevio privacy --help:*), Bash(COLUMNS=200 odevio privacy --help), Bash(odevio privacy scan:*), Bash(odevio privacy scan), Bash(COLUMNS=200 odevio privacy scan:*), Bash(COLUMNS=200 odevio privacy scan), Bash(odevio screenshot --help:*), Bash(odevio screenshot --help), Bash(COLUMNS=200 odevio screenshot --help:*), Bash(COLUMNS=200 odevio screenshot --help), Bash(odevio screenshot devices:*), Bash(odevio screenshot devices), Bash(COLUMNS=200 odevio screenshot devices:*), Bash(COLUMNS=200 odevio screenshot devices), Bash(odevio team --help:*), Bash(odevio team --help), Bash(COLUMNS=200 odevio team --help:*), Bash(COLUMNS=200 odevio team --help), Bash(odevio team ls:*), Bash(odevio team ls), Bash(COLUMNS=200 odevio team ls:*), Bash(COLUMNS=200 odevio team ls), Bash(odevio app categories:*), Bash(odevio app categories), Bash(COLUMNS=200 odevio app categories:*), Bash(COLUMNS=200 odevio app categories), Bash(odevio app attach-build:*), Bash(odevio app attach-build), Bash(COLUMNS=200 odevio app attach-build:*), Bash(COLUMNS=200 odevio app attach-build), Bash(odevio app set-metadata:*), Bash(odevio app set-metadata), Bash(COLUMNS=200 odevio app set-metadata:*), Bash(COLUMNS=200 odevio app set-metadata), Bash(odevio build start --help), Bash(COLUMNS=200 odevio build start --help), Bash(odevio screenshot push --help), Bash(COLUMNS=200 odevio screenshot push --help), Bash(odevio screenshot start --help), Bash(COLUMNS=200 odevio screenshot start --help), Bash(odevio screenshot capture --help), Bash(COLUMNS=200 odevio screenshot capture --help), Bash(odevio app check-submittable --help), Bash(COLUMNS=200 odevio app check-submittable --help), Bash(odevio app mk --help), Bash(COLUMNS=200 odevio app mk --help), Bash(odevio app import --help), Bash(COLUMNS=200 odevio app import --help), Bash(odevio build connect --help), Bash(COLUMNS=200 odevio build connect --help), Bash(odevio build download --help), Bash(COLUMNS=200 odevio build download --help), Bash(odevio build patch --help), Bash(COLUMNS=200 odevio build patch --help), Bash(odevio build stop --help), Bash(COLUMNS=200 odevio build stop --help), Bash(odevio apple add --help), Bash(COLUMNS=200 odevio apple add --help), Bash(flutter pub get:*), Bash(flutter pub get), Bash(dart analyze:*), Bash(dart analyze), Bash(flutter test:*), Bash(flutter test), Bash(flutter --version:*), Bash(flutter --version), Bash(dart --version:*), Bash(dart --version), Bash(git diff), Bash(git diff:*), Bash(git log), Bash(git log:*), Bash(git status), Bash(git status:*), Bash(git show), Bash(git show:*), Bash(odevio app submit --help), Bash(COLUMNS=200 odevio app submit --help).
SKILL.md contains no URLs. Its commands use pip, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Odevio is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.6k tokens (SKILL.md is roughly 31k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 19k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Odevio: iOS App Store Submit (ZestfulPulse/ios-app-store-submit, 142 stars), Asc Xcode Build (rorkai/app-store-connect-cli-skills, 1.1k stars), Limrun Xcode (superset-sh/superset, 15k stars) and Eas Simulator (expo/skills, 2.7k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Odevio (a GitHub organization) maintains it in Odevio/Odevio-CLI, which has 423 GitHub stars. The repository was last updated on September 24, 2026.
Source: Odevio/Odevio-CLI on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.