App Store Screenshot Upload (helm-asc)
Prerequisites
Load the helm-asc skill first. It resolves the CLI path, sets the --agent output
convention, and holds the general command map. This skill adds the screenshot-specific
detail that the general workflow does not cover.
Staging layout
Stage every file as <stage-root>/<locale>/<displayType>/NN_<filename>.<ext>.
- Use the display type that matches the device set, for example
APP_IPHONE_67 for the
6.9-inch set.
- The
NN_ prefix carries the display order. App Store Connect accepts up to 10
screenshots and up to 3 previews per display type.
- When you export from a design tool, take
NN from the Display - N token in the
exported filename.
Locale mapping
Map repository folder names to App Store Connect codes before you stage the files:
| Repository folder |
App Store Connect locale |
de |
de-DE |
es |
es-ES |
nl |
nl-NL |
These folder names pass through unchanged: da, el, fi, fr-CA, hi, hr, it,
pl, sv, tr, en-GB.
Sandbox paths
Helm runs in a sandbox, so the staging location decides whether the upload can read the
files at all.
- Run
helm-asc paths --agent.
- Stage the tree under the returned
uploadsInbox.
- Verify the staged tree with
find before you upload.
WARNING: writes into ~/Library/Group Containers/group.com.modumhq.Helm need escalated
sandbox permission. Without that permission, a mkdir or cp loop can report success and
leave nothing behind. The failure then surfaces later as a helm-asc FILE_ACCESS error on
the upload command. Never treat a silent cp as proof that the files exist.
When an upload command returns FILE_ACCESS, list the staged tree with find before you
change anything. An empty or partial listing confirms that the staging write failed.
Re-stage the files with the escalated permission, verify the tree with find, and repeat
the dry run. sudo and cd do not change what the Helm sandbox can read, so do not use
them and do not remove --dry-run until the dry run counts every staged file. If find
lists the full tree, the files exist and Helm cannot read that path: ask the user to grant
access in Helm for that exact location, then repeat the dry run.
Upload procedure
- Run
helm-asc version <version-id> screenshots --agent to record the current state.
- Run
helm-asc version <version-id> screenshots upload --path <stage-root> --dry-run --agent.
- Read the
perGroup entries in the dry-run output before you apply anything. Each
entry covers one locale and display-type group. Compare each group's count with the
number of files you staged for that group. If a count is lower, do not apply: with
--replace, the upload leaves that group with only the counted files. Find the
skipped files (check the NN_ prefix, the extension, and the display-type folder),
fix them, and repeat the dry run until every count matches.
- Add
--replace only when the user wants the new files to replace the existing set.
--replace deletes every existing screenshot in each matching locale and display-type
set before the upload. Without --replace, the upload adds to the existing set, up to
the per-display-type limit. Do not add --replace for an "add" or "append" request.
If the user proposes --replace for an addition, decline. State that --replace
deletes the existing files in that set, and name each file.
- Pass
--locale once per approved locale, for example --locale de-DE --locale nl-NL.
Without a locale list, the upload creates new store localisations with empty metadata
for any extra folder in the staging tree.
- Run the same command without
--dry-run to apply.
- A large upload (for example 85 screenshots, or a set of preview videos) runs for
several minutes with no interim output. Wait for the command to return through the host's normal wait mechanism. Do not send
input to the process and do not start a second upload.
- Verify with
helm-asc version <version-id> screenshots --agent.
- Read the returned
items. Each item carries locale, displayType, fileName,
and state. Count the new export stamp in the fileName values, confirm that every
state is complete, and confirm that only the locale and display-type groups you
staged, within the --locale list, changed. For a replacement, also confirm that
none of the old stamp remains. For an addition, also confirm that the existing files
remain.
- Remove the staging directory.
Previews
Previews use the same staging layout, locale mapping, and sandbox rules, with two
differences. Preview display-type folders omit the APP_ prefix: stage the 6.9-inch set
under IPHONE_67, not APP_IPHONE_67. Each display type accepts at most 3 previews, so
NN_ runs from 01 to 03. Substitute previews for screenshots in every command.
Known non-failures
A locale that has a store localisation but no screenshots of its own falls back to the
primary locale. That is existing App Store behaviour, not an upload failure. When a user
reports that a locale outside the --locale list "did not take", tell the user that the
locale shows the primary locale's screenshots because it has none of its own, and that
this is App Store behaviour, not an upload failure. Then quote the last verification
result as the evidence: the states it returned, the stamps in its fileName values, and
whether any old stamp remained. If you have no verification result for that upload, run
step 8 before you answer. Do not re-run the upload for a locale that has no staged images.
To give that locale its own screenshots: export images for it, stage them under
<locale>/<displayType>/, get the user's approval to add the locale to the --locale
list, then dry-run before apply.
1---2name: asc-screenshots3description: WHEN uploading, replacing, or updating App Store screenshots or previews for a version or locale, whether or not the user names helm-asc; NOT for generating, framing, or designing the images; encodes the staging layout, locale mapping, sandbox path rules, and dry-run-first upload procedure.4---56# App Store Screenshot Upload (helm-asc)78## Prerequisites910Load the `helm-asc` skill first. It resolves the CLI path, sets the `--agent` output11convention, and holds the general command map. This skill adds the screenshot-specific12detail that the general workflow does not cover.1314## Staging layout1516Stage every file as `<stage-root>/<locale>/<displayType>/NN_<filename>.<ext>`.1718- Use the display type that matches the device set, for example `APP_IPHONE_67` for the19 6.9-inch set.20- The `NN_` prefix carries the display order. App Store Connect accepts up to 1021 screenshots and up to 3 previews per display type.22- When you export from a design tool, take `NN` from the `Display - N` token in the23 exported filename.2425## Locale mapping2627Map repository folder names to App Store Connect codes before you stage the files:2829| Repository folder | App Store Connect locale |30| --- | --- |31| `de` | `de-DE` |32| `es` | `es-ES` |33| `nl` | `nl-NL` |3435These folder names pass through unchanged: `da`, `el`, `fi`, `fr-CA`, `hi`, `hr`, `it`,36`pl`, `sv`, `tr`, `en-GB`.3738## Sandbox paths3940Helm runs in a sandbox, so the staging location decides whether the upload can read the41files at all.42431. Run `helm-asc paths --agent`.442. Stage the tree under the returned `uploadsInbox`.453. Verify the staged tree with `find` before you upload.4647WARNING: writes into `~/Library/Group Containers/group.com.modumhq.Helm` need escalated48sandbox permission. Without that permission, a `mkdir` or `cp` loop can report success and49leave nothing behind. The failure then surfaces later as a helm-asc `FILE_ACCESS` error on50the upload command. Never treat a silent `cp` as proof that the files exist.5152When an upload command returns `FILE_ACCESS`, list the staged tree with `find` before you53change anything. An empty or partial listing confirms that the staging write failed.54Re-stage the files with the escalated permission, verify the tree with `find`, and repeat55the dry run. `sudo` and `cd` do not change what the Helm sandbox can read, so do not use56them and do not remove `--dry-run` until the dry run counts every staged file. If `find`57lists the full tree, the files exist and Helm cannot read that path: ask the user to grant58access in Helm for that exact location, then repeat the dry run.5960## Upload procedure61621. Run `helm-asc version <version-id> screenshots --agent` to record the current state.632. Run `helm-asc version <version-id> screenshots upload --path <stage-root> --dry-run --agent`.643. Read the `perGroup` entries in the dry-run output before you apply anything. Each65 entry covers one locale and display-type group. Compare each group's count with the66 number of files you staged for that group. If a count is lower, do not apply: with67 `--replace`, the upload leaves that group with only the counted files. Find the68 skipped files (check the `NN_` prefix, the extension, and the display-type folder),69 fix them, and repeat the dry run until every count matches.704. Add `--replace` only when the user wants the new files to replace the existing set.71 `--replace` deletes every existing screenshot in each matching locale and display-type72 set before the upload. Without `--replace`, the upload adds to the existing set, up to73 the per-display-type limit. Do not add `--replace` for an "add" or "append" request.74 If the user proposes `--replace` for an addition, decline. State that `--replace`75 deletes the existing files in that set, and name each file.765. Pass `--locale` once per approved locale, for example `--locale de-DE --locale nl-NL`.77 Without a locale list, the upload creates new store localisations with empty metadata78 for any extra folder in the staging tree.796. Run the same command without `--dry-run` to apply.807. A large upload (for example 85 screenshots, or a set of preview videos) runs for81 several minutes with no interim output. Wait for the command to return through the host's normal wait mechanism. Do not send82 input to the process and do not start a second upload.838. Verify with `helm-asc version <version-id> screenshots --agent`.849. Read the returned `items`. Each item carries `locale`, `displayType`, `fileName`,85 and `state`. Count the new export stamp in the `fileName` values, confirm that every86 `state` is `complete`, and confirm that only the locale and display-type groups you87 staged, within the `--locale` list, changed. For a replacement, also confirm that88 none of the old stamp remains. For an addition, also confirm that the existing files89 remain.9010. Remove the staging directory.9192## Previews9394Previews use the same staging layout, locale mapping, and sandbox rules, with two95differences. Preview display-type folders omit the `APP_` prefix: stage the 6.9-inch set96under `IPHONE_67`, not `APP_IPHONE_67`. Each display type accepts at most 3 previews, so97`NN_` runs from `01` to `03`. Substitute `previews` for `screenshots` in every command.9899## Known non-failures100101A locale that has a store localisation but no screenshots of its own falls back to the102primary locale. That is existing App Store behaviour, not an upload failure. When a user103reports that a locale outside the `--locale` list "did not take", tell the user that the104locale shows the primary locale's screenshots because it has none of its own, and that105this is App Store behaviour, not an upload failure. Then quote the last verification106result as the evidence: the states it returned, the stamps in its `fileName` values, and107whether any old stamp remained. If you have no verification result for that upload, run108step 8 before you answer. Do not re-run the upload for a locale that has no staged images.109To give that locale its own screenshots: export images for it, stage them under110`<locale>/<displayType>/`, get the user's approval to add the locale to the `--locale`111list, then dry-run before apply.