Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
7d1b236
Restructure app navigation with Dashboard and App tabs
pythonlearner1025 Mar 24, 2026
8284298
Add integrated terminal with SwiftTerm, multi-tab sessions, and split…
pythonlearner1025 Mar 24, 2026
d61b16d
Fix terminal blank on split position change with stable view hierarchy
pythonlearner1025 Mar 24, 2026
782f1f4
Improve terminal split resizing
pythonlearner1025 Mar 24, 2026
dcc179f
Unify terminal and AI launch into single toolbar button
pythonlearner1025 Mar 24, 2026
9d98790
Wire built-in terminal to onboarding and submission readiness fix but…
pythonlearner1025 Mar 24, 2026
a30563d
Add setting to whitelist all Blitz MCP tool calls for AI agents
pythonlearner1025 Mar 24, 2026
17df886
Fix terminal session tab rendering
pythonlearner1025 Mar 24, 2026
5c9dc83
Replace MCP HTTP bridge with direct stdio helper over Unix socket
pythonlearner1025 Mar 24, 2026
3658462
Fix dashboard project switching performance
pythonlearner1025 Mar 24, 2026
1fa82b1
Optimize ASC overview hydration and caching
pythonlearner1025 Mar 24, 2026
6804851
Optimize ASC tab loading and refresh flows
pythonlearner1025 Mar 24, 2026
aac0f30
fallback to term
pythonlearner1025 Mar 24, 2026
c5b1184
Replace ASC service with asc-cli go binary communicated via stdio/std…
pythonlearner1025 Mar 24, 2026
1d207a2
in auto-update skip ruby/python/idb update steps
pythonlearner1025 Mar 24, 2026
824a778
Bundle pinned ascd helper and add release smoke workflow
pythonlearner1025 Mar 24, 2026
28dcdc4
trigger on pr to master
pythonlearner1025 Mar 24, 2026
9205a86
update
pythonlearner1025 Mar 24, 2026
debe77d
Retrigger PR workflows
pythonlearner1025 Mar 24, 2026
94b25f6
Fix workflow version outputs
pythonlearner1025 Mar 25, 2026
465cea5
Fix onboarding toggle alignment and "Setup with AI" built-in terminal…
pythonlearner1025 Mar 25, 2026
85900bf
Fix ad-hoc helper signing in bundle script
pythonlearner1025 Mar 25, 2026
66606c9
Make terminal tabs horizontally scrollable
pythonlearner1025 Mar 25, 2026
eff9736
Replace DisclosureGroup with custom chevron toggle for consistent exp…
pythonlearner1025 Mar 25, 2026
6083114
Show per-app ASC status icons in dashboard instead of bundle IDs
pythonlearner1025 Mar 25, 2026
160ca7e
Handle INVALID_BINARY as submission error in ASC submission history
pythonlearner1025 Mar 25, 2026
ed02d6a
squenced pipe buffer for correctly sequencing received multi line dat…
pythonlearner1025 Mar 25, 2026
cd75878
hard fail on missing distribution signing creds
pythonlearner1025 Mar 25, 2026
becb82f
default project to swift
pythonlearner1025 Mar 25, 2026
ce3fdb4
Bundle ASC auth shims and harden release updates
pythonlearner1025 Mar 25, 2026
2e6c2bd
dashboard summary store
pythonlearner1025 Mar 25, 2026
1a3c243
minor changes and test
pythonlearner1025 Mar 25, 2026
edf2ead
update claude.md and rules
pythonlearner1025 Mar 25, 2026
7c92584
Migrate ASC web session to file and extend agent whitelists
pythonlearner1025 Mar 25, 2026
b9af023
ensure .codex/config.toml gets lines that include .claude/rule/* docs…
pythonlearner1025 Mar 25, 2026
b7f67db
Refactor domain groupings for ASC, MCP, project, database, and simulator
pythonlearner1025 Mar 26, 2026
661a05d
update
pythonlearner1025 Mar 26, 2026
7da719a
cleanup / remove debug code
pythonlearner1025 Mar 26, 2026
d381861
move overriding skills to src/resources
pythonlearner1025 Mar 26, 2026
f66fa1d
support nav back to sub app tabs
pythonlearner1025 Mar 26, 2026
cf30c86
unify how custom skills overwrite fetched ones from remote app-store-…
pythonlearner1025 Mar 26, 2026
5c13e2e
open simulator in background
pythonlearner1025 Mar 26, 2026
6be613e
rm strict codesign for now
pythonlearner1025 Mar 26, 2026
d09c1c1
fix terminal input capture bug in simulator tab
pythonlearner1025 Mar 26, 2026
591ec89
relaunch
pythonlearner1025 Mar 26, 2026
0c2bbef
prepare 1.0.30 release
pythonlearner1025 Mar 26, 2026
f33c217
Update helper submodule for session request stdout suppression
pythonlearner1025 Mar 26, 2026
200dd80
Shorten 1.0.30 changelog
pythonlearner1025 Mar 26, 2026
b37f4da
Add locale-aware ASC listing and screenshot workflows
pythonlearner1025 Mar 26, 2026
e45db79
Trim ASC locale flows and fix overview primary localization
pythonlearner1025 Mar 26, 2026
93aceff
localization
pythonlearner1025 Mar 26, 2026
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
52 changes: 20 additions & 32 deletions .claude/skills/asc-iap-attach/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This skill uses Apple's internal iris API (`/iris/v1/subscriptionSubmissions`) v

## Preconditions

- Web session cached in macOS Keychain. If no session exists or it has expired (401), call the `asc_web_auth` MCP tool first — this opens the Apple ID login window in Blitz and captures the session automatically.
- Web session file available at `~/.blitz/asc-agent/web-session.json`. If no session exists or it has expired (401), call the `asc_web_auth` MCP tool first — this opens the Apple ID login window in Blitz and captures the session automatically.
- Know your app ID.
- IAPs and/or subscriptions already exist and are in **Ready to Submit** state.
- A build is uploaded and attached to the current app version.
Expand All @@ -32,7 +32,7 @@ This skill uses Apple's internal iris API (`/iris/v1/subscriptionSubmissions`) v
### 1. Check for an existing web session

```bash
security find-generic-password -s "asc-web-session" -a "asc:web-session:store" -w > /dev/null 2>&1 && echo "SESSION_EXISTS" || echo "NO_SESSION"
test -f ~/.blitz/asc-agent/web-session.json && echo "SESSION_EXISTS" || echo "NO_SESSION"
```

- If `NO_SESSION`: call the `asc_web_auth` MCP tool first. Wait for it to complete before proceeding.
Expand All @@ -44,20 +44,16 @@ Use the iris API to list subscription groups (with subscriptions) and in-app pur

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

APP_ID = 'APP_ID_HERE'

try:
raw = subprocess.check_output([
'security', 'find-generic-password',
'-s', 'asc-web-session',
'-a', 'asc:web-session:store',
'-w'
], stderr=subprocess.DEVNULL).decode()
except subprocess.CalledProcessError:
session_path = os.path.expanduser('~/.blitz/asc-agent/web-session.json')
if not os.path.isfile(session_path):
print('ERROR: No web session found. Call asc_web_auth MCP tool first.')
sys.exit(1)
with open(session_path) as f:
raw = f.read()

store = json.loads(raw)
session = store['sessions'][store['last_key']]
Expand Down Expand Up @@ -118,18 +114,14 @@ Use the following script to attach subscriptions. **Do not print or log the cook

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

try:
raw = subprocess.check_output([
'security', 'find-generic-password',
'-s', 'asc-web-session',
'-a', 'asc:web-session:store',
'-w'
], stderr=subprocess.DEVNULL).decode()
except subprocess.CalledProcessError:
import json, os, urllib.request, sys

session_path = os.path.expanduser('~/.blitz/asc-agent/web-session.json')
if not os.path.isfile(session_path):
print('ERROR: No web session found. Call asc_web_auth MCP tool first.')
sys.exit(1)
with open(session_path) as f:
raw = f.read()

store = json.loads(raw)
session = store['sessions'][store['last_key']]
Expand Down Expand Up @@ -178,18 +170,14 @@ For in-app purchases (non-subscription), change the type and relationship:

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

try:
raw = subprocess.check_output([
'security', 'find-generic-password',
'-s', 'asc-web-session',
'-a', 'asc:web-session:store',
'-w'
], stderr=subprocess.DEVNULL).decode()
except subprocess.CalledProcessError:
import json, os, urllib.request, sys

session_path = os.path.expanduser('~/.blitz/asc-agent/web-session.json')
if not os.path.isfile(session_path):
print('ERROR: No web session found. Call asc_web_auth MCP tool first.')
sys.exit(1)
with open(session_path) as f:
raw = f.read()

store = json.loads(raw)
session = store['sessions'][store['last_key']]
Expand Down Expand Up @@ -243,7 +231,7 @@ After attachment, call `get_tab_state` for `ascOverview` to refresh the submissi
The subscription is already attached — this is safe to ignore. HTTP 409 with this message means the item was previously attached.

### 401 Not Authorized (iris API)
The web session has expired. Call the `asc_web_auth` MCP tool to open the Apple ID login window in Blitz — this captures a fresh session and saves it to the keychain automatically. The user will need to complete Apple ID login + 2FA in the popup. After the tool returns success, retry the iris API calls.
The web session has expired. Call the `asc_web_auth` MCP tool to open the Apple ID login window in Blitz — this captures a fresh session and refreshes `~/.blitz/asc-agent/web-session.json` automatically. The user will need to complete Apple ID login + 2FA in the popup. After the tool returns success, retry the iris API calls.

## Agent Behavior

Expand Down
27 changes: 11 additions & 16 deletions .claude/skills/asc-team-key-create/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ Use this skill to create a new App Store Connect API Key with Admin permissions

## Preconditions

- Web session cached in macOS Keychain. If no session exists or it has expired (401), call the `asc_web_auth` MCP tool first — this opens the Apple ID login window in Blitz and captures the session automatically.
- Web session file available at `~/.blitz/asc-agent/web-session.json`. If no session exists or it has expired (401), call the `asc_web_auth` MCP tool first — this opens the Apple ID login window in Blitz and captures the session automatically.
- The authenticated Apple ID must have Account Holder or Admin role.

## Workflow

### 1. Check for an existing web session

Before anything else, check if a web session already exists in the macOS Keychain:
Before anything else, check if a web session file already exists:

```bash
security find-generic-password -s "asc-web-session" -a "asc:web-session:store" -w > /dev/null 2>&1 && echo "SESSION_EXISTS" || echo "NO_SESSION"
test -f ~/.blitz/asc-agent/web-session.json && echo "SESSION_EXISTS" || echo "NO_SESSION"
```

- If `NO_SESSION`: call the `asc_web_auth` MCP tool first to open the Apple ID login window in Blitz. Wait for it to complete before proceeding.
Expand All @@ -41,22 +41,17 @@ Use the following self-contained script. Replace `KEY_NAME` with the user's chos

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

KEY_NAME = 'KEY_NAME_HERE'

# Extract cookies from keychain (silent — never print these)
try:
raw = subprocess.check_output([
'security', 'find-generic-password',
'-s', 'asc-web-session',
'-a', 'asc:web-session:store',
'-w'
], stderr=subprocess.DEVNULL).decode()
except subprocess.CalledProcessError:
print('ERROR: No web session found. User must authenticate first.')
print('Run: asc web auth login --apple-id EMAIL')
# Read web session file (silent — never print these)
session_path = os.path.expanduser('~/.blitz/asc-agent/web-session.json')
if not os.path.isfile(session_path):
print('ERROR: No web session found. Call asc_web_auth MCP tool first.')
sys.exit(1)
with open(session_path) as f:
raw = f.read()

store = json.loads(raw)
session = store['sessions'][store['last_key']]
Expand Down Expand Up @@ -191,7 +186,7 @@ After the script runs, report:
## Common Errors

### 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 captures the session to the macOS Keychain automatically. Then retry the key creation script.
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.

### 409 Conflict
A key with the same name may already exist, or another conflict occurred. Try a different name.
Expand Down
76 changes: 69 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ jobs:
runs-on: macos-15
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: deps/App-Store-Connect-CLI-helper/go.mod

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
Expand Down Expand Up @@ -45,6 +52,13 @@ jobs:
runs-on: macos-15-intel
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: deps/App-Store-Connect-CLI-helper/go.mod

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
Expand Down Expand Up @@ -82,6 +96,13 @@ jobs:
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: deps/App-Store-Connect-CLI-helper/go.mod

- name: Setup Node.js
uses: actions/setup-node@v4
Expand Down Expand Up @@ -119,21 +140,40 @@ jobs:
# Add to search list
security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db

- name: Validate production signing inputs
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_INSTALLER_IDENTITY: ${{ secrets.APPLE_INSTALLER_IDENTITY }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
run: |
[ -n "$APPLE_CERTIFICATE_BASE64" ] || { echo "Missing APPLE_CERTIFICATE_BASE64"; exit 1; }
[ -n "$APPLE_CERTIFICATE_PASSWORD" ] || { echo "Missing APPLE_CERTIFICATE_PASSWORD"; exit 1; }
[ -n "$APPLE_SIGNING_IDENTITY" ] || { echo "Missing APPLE_SIGNING_IDENTITY"; exit 1; }
[ -n "$APPLE_INSTALLER_IDENTITY" ] || { echo "Missing APPLE_INSTALLER_IDENTITY"; exit 1; }
[ -n "$APPLE_API_KEY" ] || { echo "Missing APPLE_API_KEY"; exit 1; }
[ -n "$APPLE_API_ISSUER" ] || { echo "Missing APPLE_API_ISSUER"; exit 1; }
[ -n "$APPLE_API_KEY_BASE64" ] || { echo "Missing APPLE_API_KEY_BASE64"; exit 1; }

- name: Build release .app
env:
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY || '-' }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
BLITZ_REQUIRE_SIGNED_RELEASE: "1"
run: |
swift build -c release
bash scripts/bundle.sh release

- name: Build .pkg
env:
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY || '-' }}
APPLE_INSTALLER_IDENTITY: ${{ secrets.APPLE_INSTALLER_IDENTITY || '' }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_INSTALLER_IDENTITY: ${{ secrets.APPLE_INSTALLER_IDENTITY }}
BLITZ_REQUIRE_SIGNED_RELEASE: "1"
run: bash scripts/build-pkg.sh

- name: Notarize .pkg
if: env.APPLE_API_KEY != ''
env:
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_PATH: ${{ runner.temp }}/AuthKey.p8
Expand Down Expand Up @@ -165,7 +205,9 @@ jobs:

- name: Get version
id: version
run: echo "version=$(node -e "process.stdout.write(require('./package.json').version)")" >> "$GITHUB_OUTPUT"
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Extract changelog notes
id: changelog
Expand Down Expand Up @@ -224,6 +266,13 @@ jobs:
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: deps/App-Store-Connect-CLI-helper/go.mod

- name: Setup Node.js
uses: actions/setup-node@v4
Expand Down Expand Up @@ -260,11 +309,24 @@ jobs:

- name: Get version
id: version
run: echo "version=$(node -e "process.stdout.write(require('./package.json').version)")" >> "$GITHUB_OUTPUT"
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Validate x86_64 signing inputs
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
run: |
[ -n "$APPLE_CERTIFICATE_BASE64" ] || { echo "Missing APPLE_CERTIFICATE_BASE64"; exit 1; }
[ -n "$APPLE_CERTIFICATE_PASSWORD" ] || { echo "Missing APPLE_CERTIFICATE_PASSWORD"; exit 1; }
[ -n "$APPLE_SIGNING_IDENTITY" ] || { echo "Missing APPLE_SIGNING_IDENTITY"; exit 1; }

- name: Build x86_64 .app artifact
env:
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY || '-' }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
BLITZ_REQUIRE_SIGNED_RELEASE: "1"
run: |
swift build -c release
bash scripts/bundle.sh release
Expand Down
Loading
Loading