diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 5ec0b67..dcea0fc 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -14,13 +14,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: '16.x' - - run: npm install - - run: npx prettier . --check --config .prettierrc.json + node-version: '20.x' + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + - run: pnpm install + - run: pnpm prettier . --check --config .prettierrc.json process: name: Process @@ -28,15 +32,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 + with: + node-version: '20.x' + - name: Setup pnpm + uses: pnpm/action-setup@v4 with: - node-version: '16.x' - - run: npm install + version: 9 + - run: pnpm install - run: node process.mjs - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: generated-lookups path: output @@ -49,9 +57,10 @@ jobs: steps: - name: Set current date as env variable run: echo "NOW=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: generated-lookups + path: . - uses: 'marvinpinto/action-automatic-releases@latest' with: repo_token: '${{ secrets.GITHUB_TOKEN }}' diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2b0d251 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,127 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This repository maintains a comprehensive dataset of Apple device model identifiers mapped to human-readable names and metadata. It serves as the data source for TelemetryDeck's device detection system. + +## Core Architecture + +### Data Structure + +- **Source Data**: Individual JSON files in `dataset/` directory organized by device type: + - `iphones.json` - iPhone models + - `ipads.json` - iPad models + - `macs.json` - Mac models + - `appletvs.json` - Apple TV models + - `wearables.json` - Apple Watch and AirPods + - `other.json` - Other Apple devices + +- **Data Schema**: Each device entry contains: + ```json + { + "ModelIdentifier": { + "deviceType": "Desktop|Laptop|Phone|Tablet|Set-Top Box|Wearable|Headset", + "processorFamily": "Apple M1|Intel Core i5|A15|etc", + "processorType": "Apple Silicon|Intel", + "readableName": "Human readable device name", + "systemFirstRelease": "First OS release version", + "systemLastRelease": "Last supported OS version" + } + } + ``` + +### Processing Pipeline + +- **Input**: Multiple JSON files in `dataset/` +- **Processor**: `process.mjs` script that merges all datasets and extracts individual lookup tables +- **Output**: Generated files in `output/` directory for each metadata field: + - `readableName.json` - Model ID → readable name mapping + - `deviceType.json` - Model ID → device type mapping + - `processorType.json` - Model ID → processor type mapping + - `processorFamily.json` - Model ID → processor family mapping + - `systemFirstRelease.json` - Model ID → first release mapping + - `systemLastRelease.json` - Model ID → last release mapping + +## Development Commands + +### Code Formatting + +```bash +pnpm prettier . --check --config .prettierrc.json # Check formatting +pnpm prettier . --write --config .prettierrc.json # Fix formatting +``` + +### Data Processing + +```bash +node process.mjs # Generate lookup tables from dataset files +``` + +### Package Management + +```bash +pnpm install # Install dependencies (uses pnpm) +``` + +## CI/CD Pipeline + +The GitHub Actions workflow (`build-pr.yml`) automatically: + +1. **Lint**: Runs Prettier formatting checks +2. **Process**: Executes `process.mjs` to generate output files +3. **Release**: Creates automatic releases with generated JSON files (main branch only) + +## Code Style + +- Uses Prettier with custom configuration (`.prettierrc.json`) +- JSON files are automatically sorted recursively +- 4-space indentation, single quotes, no semicolons +- ES modules (`.mjs` extension for Node.js scripts) + +## Data Sources for Updates + +**Primary Sources:** + +- **Apple Newsroom** - https://www.apple.com/newsroom/ (official announcements and device names) +- **adamawolf GitHub gist** - https://gist.github.com/adamawolf/3048717 (most up-to-date model identifiers like iPhone18,1) +- **AppleDB** - https://appledb.dev/ (comprehensive device database with SoC info) +- **EveryMac.com** - https://everymac.com/ (detailed technical specifications and processor families) + +**Data Update Process:** +When asked to update data or check for updates: + +1. **Cross-reference sources** - Check adamawolf GitHub gist and AppleDB for new model identifiers +2. **Verify official names** - Confirm device names and specs with Apple Newsroom +3. **Get technical details** - Use EveryMac.com for processor families and device classifications +4. **Update dataset files** in priority order: + - `dataset/iphones.json` (highest priority) + - `dataset/ipads.json` + - `dataset/macs.json` + - `dataset/wearables.json` + - `dataset/appletvs.json` + - `dataset/other.json` +5. **Process and format**: + + ```bash + node process.mjs + pnpm prettier . --write --config .prettierrc.json + ``` + +6. **Verify changes and quality control**: + + ```bash + git status # Check which files were modified + git diff --name-status # See summary of all changes + git diff dataset/ # Review all dataset changes in detail + git diff --stat # Get statistical summary of changes + ``` + + - **Review all changes carefully** - Ensure only intended additions/modifications were made + - **Verify no devices were accidentally removed** - Check that existing entries are preserved + - **Double-check technical accuracy** - Confirm processor families, device types, and naming conventions + - **Cross-reference with 3rd source** - Optionally verify new entries with EveryMac.com or Apple Support docs + - **Validate data consistency** - Ensure new entries follow the same schema and naming patterns as existing data + +Always confirm at least 2 sources agree on device information before adding entries. diff --git a/dataset/appletvs.json b/dataset/appletvs.json index e0da134..4cd058f 100644 --- a/dataset/appletvs.json +++ b/dataset/appletvs.json @@ -1,4 +1,14 @@ { + "AppleTV11,1": { + "deviceType": "Set-Top Box", + "processorFamily": "A12", + "readableName": "Apple TV 4K (2nd generation)" + }, + "AppleTV14,1": { + "deviceType": "Set-Top Box", + "processorFamily": "A15", + "readableName": "Apple TV 4K (3rd generation)" + }, "AppleTV2,1": { "deviceType": "Set-Top Box", "processorFamily": "S5L8930", @@ -22,6 +32,6 @@ "AppleTV6,2": { "deviceType": "Set-Top Box", "processorFamily": "A10X", - "readableName": "Apple TV 4K" + "readableName": "Apple TV 4K (1st generation)" } } diff --git a/dataset/ipads.json b/dataset/ipads.json index fbcc76c..ae9e2a1 100644 --- a/dataset/ipads.json +++ b/dataset/ipads.json @@ -119,6 +119,31 @@ "processorFamily": "A15 Bionic", "readableName": "iPad mini (6th generation) (WiFi)" }, + "iPad14,10": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi+Cellular)" + }, + "iPad14,11": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi)" + }, + "iPad14,12": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi+Cellular)" + }, + "iPad14,13": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi)" + }, + "iPad14,14": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi+Cellular)" + }, "iPad14,2": { "deviceType": "Tablet", "processorFamily": "A15 Bionic", @@ -141,9 +166,44 @@ }, "iPad14,6": { "deviceType": "Tablet", - "processorFamily": "", + "processorFamily": "M2", "readableName": "iPad Pro 12.9-inch (6th generation) (WiFi+Cellular)" }, + "iPad14,7": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi)" + }, + "iPad14,8": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi+Cellular)" + }, + "iPad14,9": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi)" + }, + "iPad16,3": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 11-inch (5th generation) (WiFi)" + }, + "iPad16,4": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 11-inch (5th generation) (WiFi+Cellular)" + }, + "iPad16,5": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 13-inch (5th generation) (WiFi)" + }, + "iPad16,6": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 13-inch (5th generation) (WiFi+Cellular)" + }, "iPad2,1": { "deviceType": "Tablet", "processorFamily": "A5", diff --git a/dataset/iphones.json b/dataset/iphones.json index 2a99256..2a5200b 100644 --- a/dataset/iphones.json +++ b/dataset/iphones.json @@ -149,6 +149,11 @@ "processorFamily": "A16", "readableName": "iPhone 15" }, + "iPhone15,5": { + "deviceType": "Phone", + "processorFamily": "A16", + "readableName": "iPhone 15 Plus" + }, "iPhone16,1": { "deviceType": "Phone", "processorFamily": "A17 Pro", diff --git a/dataset/macs.json b/dataset/macs.json index 5031365..6d1e666 100644 --- a/dataset/macs.json +++ b/dataset/macs.json @@ -157,6 +157,90 @@ "readableName": "MacBook Pro (16-inch, Nov 2023)", "systemFirstRelease": "12.2" }, + "Mac16,1": { + "deviceType": "Laptop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (14-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,10": { + "deviceType": "Desktop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "Mac mini (2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,11": { + "deviceType": "Desktop", + "processorFamily": "M4 Pro", + "processorType": "Apple Silicon", + "readableName": "Mac mini (2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,12": { + "deviceType": "Laptop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "MacBook Air (13-inch, M4, 2025)", + "systemFirstRelease": "15.0" + }, + "Mac16,13": { + "deviceType": "Laptop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "MacBook Air (15-inch, M4, 2025)", + "systemFirstRelease": "15.0" + }, + "Mac16,2": { + "deviceType": "Desktop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "iMac (24-inch, 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,3": { + "deviceType": "Desktop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "iMac (24-inch, 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,5": { + "deviceType": "Laptop", + "processorFamily": "M4 Max", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (16-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,6": { + "deviceType": "Laptop", + "processorFamily": "M4 Pro", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (14-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,7": { + "deviceType": "Laptop", + "processorFamily": "M4 Pro", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (16-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,8": { + "deviceType": "Laptop", + "processorFamily": "M4 Max", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (14-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,9": { + "deviceType": "Desktop", + "processorFamily": "M4 Max", + "processorType": "Apple Silicon", + "readableName": "Mac Studio (2025)", + "systemFirstRelease": "15.0" + }, "MacBook10,1": { "deviceType": "Laptop", "processorType": "Intel", diff --git a/package.json b/package.json index 588a530..ed9544f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "prettier": "^3.1.0", + "prettier": "^3.6.2", "prettier-plugin-sort-json": "^3.1.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aaa5a82..ef136e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,19 +1,21 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -devDependencies: - prettier: - specifier: ^3.1.0 - version: 3.1.0 - prettier-plugin-sort-json: - specifier: ^3.1.0 - version: 3.1.0(prettier@3.1.0) +importers: + .: + devDependencies: + prettier: + specifier: ^3.6.2 + version: 3.6.2 + prettier-plugin-sort-json: + specifier: ^3.1.0 + version: 3.1.0(prettier@3.6.2) packages: - /prettier-plugin-sort-json@3.1.0(prettier@3.1.0): + prettier-plugin-sort-json@3.1.0: resolution: { integrity: sha512-eIDEUjwzekiVd+oKrpd0aoACBTp5zOW71wDTNy+qQ5C9Q8oqt9n9wCm4F+SeRZbXfgblh/WYIguJynImlBXrvQ==, @@ -21,15 +23,18 @@ packages: engines: { node: '>=16.0.0' } peerDependencies: prettier: ^3.0.0 - dependencies: - prettier: 3.1.0 - dev: true - /prettier@3.1.0: + prettier@3.6.2: resolution: { - integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==, + integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==, } engines: { node: '>=14' } hasBin: true - dev: true + +snapshots: + prettier-plugin-sort-json@3.1.0(prettier@3.6.2): + dependencies: + prettier: 3.6.2 + + prettier@3.6.2: {}