@mmerterden/multi-agent-pipeline 20.9.0 → 20.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/docs/facts.json +5 -4
  3. package/install/catalog-history.json +1 -1
  4. package/manifest.json +31 -28
  5. package/package.json +1 -1
  6. package/pipeline/commands/multi-agent/SKILL.md +1 -1
  7. package/pipeline/commands/multi-agent/help/SKILL.md +2 -2
  8. package/pipeline/commands/multi-agent/setup/SKILL.md +12 -13
  9. package/pipeline/commands/multi-agent/store-ready/SKILL.md +63 -19
  10. package/pipeline/lib/credential-inventory.sh +3 -2
  11. package/pipeline/lib/repo-profile-derive.mjs +21 -12
  12. package/pipeline/multi-agent-refs/features/doctor.md +17 -0
  13. package/pipeline/multi-agent-refs/features/repo-profile.md +1 -1
  14. package/pipeline/multi-agent-refs/keychain.md +2 -0
  15. package/pipeline/multi-agent-refs/outside-the-pipeline.md +1 -0
  16. package/pipeline/multi-agent-refs/setup/app-store-connect.md +106 -20
  17. package/pipeline/multi-agent-refs/setup/google-play.md +70 -0
  18. package/pipeline/preferences-template.json +3 -1
  19. package/pipeline/schemas/prefs.schema.json +9 -1
  20. package/pipeline/schemas/repo-profile.schema.json +32 -1
  21. package/pipeline/scripts/doctor.mjs +91 -1
  22. package/pipeline/scripts/pre-commit-check.sh +11 -2
  23. package/pipeline/scripts/probe-store-key.mjs +306 -0
  24. package/pipeline/scripts/write-store-config.mjs +293 -0
  25. package/pipeline/skills/.skill-manifest.json +4 -4
  26. package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +1 -1
  27. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +58 -6
  28. package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +11 -7
@@ -76,6 +76,8 @@ These are the RECOMMENDED key names. When creating NEW keys, use these. But exis
76
76
  | `fortify` | `${USER}_Fortify_Access_Token` | `fortify` |
77
77
  | `firebase` | `${USER}_Firebase_Access_Json` | `firebase` (any variant: `sa`, `service`, `account`, `access`, `json`) |
78
78
  | `jenkins` | `${USER}_Jenkins_Access_Token` | `jenkins` |
79
+ | `appstore_connect_private_key` | `${USER}_AppStoreConnect_Private_Key` | (`appstore` or `asc` or `app_store`) + (`private` or `p8`) |
80
+ | `google_play` | `${USER}_GooglePlay_Access_Json` | (`googleplay` or `google_play` or `play_console` or `play`) + (`service` or `account` or `access` or `json` or `console`), NOT `firebase` |
79
81
 
80
82
  **1c. Resolution logic (per service):**
81
83
 
@@ -256,6 +258,8 @@ Standard key names (used when creating NEW tokens). Discovery may find existing
256
258
  | `fortify` | `${USER}_Fortify_Access_Token` | API Token | Fortify SSC -> Token Management (VPN required) |
257
259
  | `firebase` | `${USER}_Firebase_Access_Json` | Firebase service-account JSON | Firebase Console -> Project settings -> Service accounts -> Generate new private key. Store the file as issued; project id is read straight out of it. |
258
260
  | `jenkins` | `${USER}_Jenkins_Access_Token` | API Token | Jenkins -> User -> Configure -> API Token |
261
+ | `appstore_connect_private_key` | `${USER}_AppStoreConnect_Private_Key` | Full PEM text of `AuthKey_<keyId>.p8` | App Store Connect -> Users and Access -> Integrations -> App Store Connect API. Stored from the file via stdin after `probe-store-key.mjs --asc` accepts it |
262
+ | `google_play` | `${USER}_GooglePlay_Access_Json` | Service-account JSON, as issued | Play Console -> Setup -> API access. Stored from the file via stdin after `probe-store-key.mjs --play` accepts it |
259
263
  | - | Git Identities | JSON (preferences) | Stored in `$HOME/.claude/multi-agent-preferences.json` - not Keychain |
260
264
 
261
265
  ### Inline Token Save Pattern
@@ -312,16 +316,35 @@ the reason, never as a pass.
312
316
 
313
317
  Ask (picker): **API key** / **Apple ID + app-specific password** / **Skip**.
314
318
 
315
- **API key** - needs an Admin or App Manager role in App Store Connect. Map the key
316
- id and issuer id as `appstore_connect_key_id` / `appstore_connect_issuer_id`. The
317
- private key is a FILE and never enters the credential store; it goes to one of the
318
- directories altool searches:
319
+ **API key** - needs an Admin or App Manager role in App Store Connect. Every part
320
+ lives in the Keychain, the `.p8` included. Map the key id and issuer id as
321
+ `appstore_connect_key_id` / `appstore_connect_issuer_id` (identifiers, stored as
322
+ plain values). Ask for the `.p8` as a path, never its contents, and validate it
323
+ BEFORE saving:
319
324
 
320
325
  ```bash
321
- ls ~/.appstoreconnect/private_keys/AuthKey_*.p8 2>/dev/null \
322
- || echo "MISSING: put AuthKey_<keyId>.p8 in ~/.appstoreconnect/private_keys/"
326
+ node "$HOME/.copilot/scripts/probe-store-key.mjs" --asc \
327
+ --key-id "<key id>" --issuer-id "<issuer id>" --p8 "<path to AuthKey_<keyId>.p8>"
323
328
  ```
324
329
 
330
+ It prints `{ok, store, status, hint}` and no key material. On exit 1 show the
331
+ `hint` (`401`: key id / issuer id do not match this `.p8`, the key was revoked, or
332
+ the clock is off; `403`: the key's role cannot read apps) and save nothing. On
333
+ exit 0, map `appstore_connect_private_key` first (`set` resolves the logical key
334
+ through the mapping), then store the file through stdin and write the toolkit's
335
+ store reference file:
336
+
337
+ ```bash
338
+ ~/.copilot/lib/credential-store.sh set appstore_connect_private_key - < "<path to AuthKey_<keyId>.p8>"
339
+ node "$HOME/.copilot/scripts/write-store-config.mjs"
340
+ ```
341
+
342
+ Then offer (picker, default **Keep file**) to delete the `.p8` from disk; Apple
343
+ does not let it be downloaded again, so the choice is the user's. The toolkit's
344
+ `store_asc_*` tools and `ios_testflight_validate` (called with neither
345
+ `api_key_id` nor `apple_id`) read the key from the Keychain through that
346
+ reference file.
347
+
325
348
  **Apple ID + app-specific password** - usable by **any Apple ID holder, no elevated
326
349
  role**, which is the realistic path when API-key creation is not permitted on the
327
350
  account. Lead with this option when the user says they cannot create an API key.
@@ -348,6 +371,35 @@ A credential that resolves but is rejected (401/403) follows the Expired-token
348
371
  decision (Regenerate / Use a different token / Skip and continue) rather than
349
372
  being silently dropped.
350
373
 
374
+ ### Google Play Credentials (optional, Android only)
375
+
376
+ Asked only when the target repo is Android, as the App Store Connect block is asked
377
+ only for iOS. One entry, `google_play`: the service-account JSON the toolkit's
378
+ `store_play_*` tools authenticate with. With it, `multi-agent-store-ready` hands
379
+ Android Gate 2 to Google instead of reporting it `SKIPPED`.
380
+
381
+ Ask (picker): **Add Google Play** / **Skip**. Before asking for the file, say what
382
+ the account needs: Play Console -> Setup -> API access (link a Cloud project,
383
+ create the service account, download its JSON key); Play Console -> Users and
384
+ permissions (invite the account's `client_email` with app permissions); and the
385
+ **Google Play Android Developer API** plus the **Google Play Developer Reporting
386
+ API** enabled in that Cloud project.
387
+
388
+ Ask for the JSON's path, never its contents. Validate BEFORE saving:
389
+
390
+ ```bash
391
+ node "$HOME/.copilot/scripts/probe-store-key.mjs" --play --service-account "<path to service-account.json>"
392
+ ```
393
+
394
+ On exit 1 show the `hint` and save nothing: `403` with `SERVICE_DISABLED` means an
395
+ API is off in the Cloud project; any other `403` means the account is not invited
396
+ in Play Console. On exit 0, map `google_play` first, then:
397
+
398
+ ```bash
399
+ ~/.copilot/lib/credential-store.sh set google_play - < "<path to service-account.json>"
400
+ node "$HOME/.copilot/scripts/write-store-config.mjs"
401
+ ```
402
+
351
403
  ### Firebase / Crashlytics Access (optional, any platform)
352
404
 
353
405
  Discovery maps a stored service-account JSON like any other credential, but it
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: multi-agent-store-ready
3
- description: "Pre-submission store readiness for a built package, iOS and Android, local-only. Three symmetric gates per platform: a static package audit, the store's own authoritative validation, and a policy review against repo source. Separate verdict per gate, a skipped gate never counted as a pass. Validates only, never uploads. Use when a build is about to go to TestFlight or a Play track, or when a submission was rejected and the reason is not obvious."
3
+ description: "Pre-submission store readiness for a built package, iOS and Android, local-only. Three symmetric gates per platform: a static package audit, the store's own authoritative validation, and a policy review against repo source. Separate verdict per gate, a skipped gate never counted as a pass. Validates only, never ships a build. Use when a build is about to go to TestFlight or a Play track, or when a submission was rejected and the reason is not obvious."
4
4
  user-invocable: true
5
5
  argument-hint: "[repo] - empty = pick; repo name or path; --ipa= | --archive= | --aab= | --apk=; --skip-sweep; --resume"
6
6
  metadata:
@@ -12,8 +12,10 @@ metadata:
12
12
  Catch, before you upload, what App Store Connect or the Play Console would send
13
13
  back after you do.
14
14
 
15
- **Local-only.** No commits, no push, no PR. **It never uploads**: iOS runs
16
- `--validate-app`, never `--upload-app`; Android never commits a Play edit.
15
+ **Local-only.** No commits, no push, no PR. **It never ships**: iOS runs
16
+ `--validate-app`, never `--upload-app`; Android never commits a Play edit, and
17
+ uploads into a throwaway edit only with Google Play onboarded and the user's
18
+ approval.
17
19
 
18
20
  **Input**: $ARGUMENTS
19
21
 
@@ -37,7 +39,7 @@ doc is the contract.
37
39
  | Gate | iOS | Android |
38
40
  |---|---|---|
39
41
  | 1 Static | `ios_app_store_audit` 18 rules, needs an `.xcarchive` | `android_apk_audit` + `google-play-compliance` 21 rules, needs an `.aab` |
40
- | 2 Authoritative | `ios_testflight_validate` → `altool --validate-app`, needs credentials | `SKIPPED` - Play's authoritative check is server-side only and no client ships here |
42
+ | 2 Authoritative | `ios_testflight_validate` → `altool --validate-app`, needs credentials; `store_asc_next_build_number` says whether the build number is already used | With `google_play` onboarded: `store_play_validate_bundle` validates the `.aab` in a throwaway edit that is deleted, never committed, after the user approves the upload. Otherwise `SKIPPED (no local Play validator)`, reason `Google Play not onboarded` |
41
43
  | 3 Policy | `ai-ios-toolkit:app-store-review` skill vs repo source | `ai-android-toolkit:play-store-review` skill vs repo source |
42
44
 
43
45
  Gate 1 also fails the package on its own, without the MCP tool, when the archive
@@ -45,9 +47,11 @@ carries no dSYM (iOS) or a `minifyEnabled true` module produced no `mapping.txt`
45
47
  (Android). Gate 3 carries a `Crash symbolication` row on both platforms: a dSYM
46
48
  upload step for iOS, a `mapping.txt` upload for Android.
47
49
 
48
- Gate 2's asymmetry is reported as an asymmetry. An Android run clears at most 2 of 3
49
- gates and must never print `passed`. A skipped gate is never folded into the pass
50
- count on either platform.
50
+ Gate 2's asymmetry is reported as an asymmetry. An Android run whose Gate 2 did not
51
+ run clears at most 2 of 3 gates and must never print `passed`. A skipped gate is
52
+ never folded into the pass count on either platform. The `store_*` tools need
53
+ `@mmerterden/multi-agent-toolkit-mcp` ≥ v3.17.0; the Android upload is refused
54
+ when `MULTI_AGENT_UNATTENDED=1`, and Gate 2 then reports `SKIPPED` with that reason.
51
55
 
52
56
  ## Related surfaces
53
57