Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/resources/skills/asc-app-create-ui/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ Key differences from the public REST API:

```bash
python3 -c "
import json, os, urllib.request, sys
import json, os, urllib.request, sys, gzip

def read_body(r):
# iris may gzip responses even unasked; urllib does not decompress
b = r.read()
return (gzip.decompress(b) if b[:2] == bytes([31, 139]) else b).decode()

BUNDLE_ID = 'BUNDLE_ID_HERE'
SKU = 'SKU_HERE'
Expand Down Expand Up @@ -127,15 +132,15 @@ req = urllib.request.Request(
data=create_body, method='POST', headers=headers)
try:
resp = urllib.request.urlopen(req)
result = json.loads(resp.read().decode())
result = json.loads(read_body(resp))
app_id = result['data']['id']
print(f'App created successfully!')
print(f'App ID: {app_id}')
print(f'Bundle ID: {BUNDLE_ID}')
print(f'Name: {APP_NAME}')
print(f'SKU: {SKU}')
except urllib.error.HTTPError as e:
body = e.read().decode()
body = read_body(e)
if e.code == 401:
print('ERROR: Session expired. Call asc_web_auth MCP tool to re-authenticate.')
elif e.code == 409:
Expand Down
29 changes: 22 additions & 7 deletions src/resources/skills/asc-iap-attach/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ Use the iris API to list subscription groups (with subscriptions) and in-app pur

```bash
python3 -c "
import json, os, urllib.request, sys
import json, os, urllib.request, sys, gzip

def read_body(r):
# iris may gzip responses even unasked; urllib does not decompress
b = r.read()
return (gzip.decompress(b) if b[:2] == bytes([31, 139]) else b).decode()

APP_ID = 'APP_ID_HERE'

Expand Down Expand Up @@ -76,12 +81,12 @@ def iris_get(path):
req = urllib.request.Request(url, method='GET', headers=headers)
try:
resp = urllib.request.urlopen(req)
return json.loads(resp.read().decode())
return json.loads(read_body(resp))
except urllib.error.HTTPError as e:
if e.code == 401:
print('ERROR: Session expired. Call asc_web_auth MCP tool to re-authenticate.')
sys.exit(1)
print(f'ERROR: HTTP {e.code} — {e.read().decode()[:200]}')
print(f'ERROR: HTTP {e.code} — {read_body(e)[:200]}')
sys.exit(1)

# List subscription groups with subscriptions included
Expand Down Expand Up @@ -114,7 +119,12 @@ Use the following script to attach subscriptions. **Do not print or log the cook

```bash
python3 -c "
import json, os, urllib.request, sys
import json, os, urllib.request, sys, gzip

def read_body(r):
# iris may gzip responses even unasked; urllib does not decompress
b = r.read()
return (gzip.decompress(b) if b[:2] == bytes([31, 139]) else b).decode()

session_path = os.path.expanduser('~/.blitz/asc-agent/web-session.json')
if not os.path.isfile(session_path):
Expand Down Expand Up @@ -152,7 +162,7 @@ def iris_attach_subscription(sub_id):
resp = urllib.request.urlopen(req)
print(f'Attached subscription {sub_id}: HTTP {resp.status}')
except urllib.error.HTTPError as e:
body = e.read().decode()
body = read_body(e)
if 'already set to submit' in body:
print(f'Subscription {sub_id} already attached (OK)')
elif e.code == 401:
Expand All @@ -170,7 +180,12 @@ For in-app purchases (non-subscription), change the type and relationship:

```bash
python3 -c "
import json, os, urllib.request, sys
import json, os, urllib.request, sys, gzip

def read_body(r):
# iris may gzip responses even unasked; urllib does not decompress
b = r.read()
return (gzip.decompress(b) if b[:2] == bytes([31, 139]) else b).decode()

session_path = os.path.expanduser('~/.blitz/asc-agent/web-session.json')
if not os.path.isfile(session_path):
Expand Down Expand Up @@ -208,7 +223,7 @@ def iris_attach_iap(iap_id):
resp = urllib.request.urlopen(req)
print(f'Attached IAP {iap_id}: HTTP {resp.status}')
except urllib.error.HTTPError as e:
body = e.read().decode()
body = read_body(e)
if 'already set to submit' in body:
print(f'IAP {iap_id} already attached (OK)')
elif e.code == 401:
Expand Down
22 changes: 16 additions & 6 deletions src/resources/skills/asc-team-key-create/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ Use the following self-contained script. Replace `KEY_NAME` with the user's chos

```bash
python3 -c "
import json, urllib.request, base64, os, sys, time
import json, urllib.request, base64, os, sys, time, gzip

def read_body(r):
# iris may gzip responses even unasked; urllib does not decompress
b = r.read()
return (gzip.decompress(b) if b[:2] == bytes([31, 139]) else b).decode()

KEY_NAME = 'KEY_NAME_HERE'

Expand Down Expand Up @@ -88,9 +93,9 @@ req = urllib.request.Request(
data=create_body, method='POST', headers=headers)
try:
resp = urllib.request.urlopen(req)
create_data = json.loads(resp.read().decode())
create_data = json.loads(read_body(resp))
except urllib.error.HTTPError as e:
body = e.read().decode()
body = read_body(e)
if e.code == 401:
print('ERROR: Session expired. Call asc_web_auth MCP tool to re-authenticate.')
elif e.code == 409:
Expand All @@ -116,9 +121,9 @@ req = urllib.request.Request(
method='GET', headers=dl_headers)
try:
resp = urllib.request.urlopen(req)
dl_data = json.loads(resp.read().decode())
dl_data = json.loads(read_body(resp))
except urllib.error.HTTPError as e:
print(f'ERROR downloading key: HTTP {e.code} — {e.read().decode()[:300]}')
print(f'ERROR downloading key: HTTP {e.code} — {read_body(e)[:300]}')
sys.exit(1)

pk_b64 = dl_data['data']['attributes'].get('privateKey')
Expand All @@ -135,7 +140,7 @@ req = urllib.request.Request(
method='GET', headers=dl_headers)
try:
resp = urllib.request.urlopen(req)
provider_data = json.loads(resp.read().decode())
provider_data = json.loads(read_body(resp))
issuer_id = None
for inc in provider_data.get('included', []):
if inc['type'] == 'contentProviders':
Expand Down Expand Up @@ -189,6 +194,11 @@ After the script runs, report:
### 401 Not Authorized
The web session has expired or doesn't exist. Call the `asc_web_auth` MCP tool — this opens the Apple ID login window in Blitz and refreshes `~/.blitz/asc-agent/web-session.json` automatically. Then retry the key creation script.

### Script fails after "Created API key" (or crashes with no output)
The key may already exist in ASC. Do NOT re-run the script, which creates a duplicate. List keys
(`GET /iris/v1/apiKeys?limit=200`), find the one whose `nickname` matches, and if `canDownload` is still
true, run steps 2–4 of the script against that key ID.

### 409 Conflict
A key with the same name may already exist, or another conflict occurred. Try a different name.

Expand Down