storemeta 0.1.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 (92) hide show
  1. package/.env.release.example +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +94 -0
  4. package/dist/auth/apple/credential-state.js +14 -0
  5. package/dist/auth/apple/jwt.js +56 -0
  6. package/dist/auth/apple/load-credentials.js +36 -0
  7. package/dist/auth/credential-state.js +6 -0
  8. package/dist/auth/google/credential-state.js +10 -0
  9. package/dist/auth/google/load-credentials.js +18 -0
  10. package/dist/auth/google/service-account-auth.js +25 -0
  11. package/dist/auth/redact.js +17 -0
  12. package/dist/cli/auth-check.js +46 -0
  13. package/dist/cli/config-doctor.js +40 -0
  14. package/dist/cli/context.js +23 -0
  15. package/dist/cli/errors.js +10 -0
  16. package/dist/cli/exit-code.js +6 -0
  17. package/dist/cli/init.js +60 -0
  18. package/dist/cli/locales-list.js +37 -0
  19. package/dist/cli/metadata-diff.js +57 -0
  20. package/dist/cli/metadata-pull.js +52 -0
  21. package/dist/cli/metadata-push.js +95 -0
  22. package/dist/cli/render.js +57 -0
  23. package/dist/cli/result-types.js +1 -0
  24. package/dist/cli/scaffold.js +76 -0
  25. package/dist/cli/screenshots-diff.js +65 -0
  26. package/dist/cli/screenshots-pull.js +72 -0
  27. package/dist/cli/screenshots-push.js +96 -0
  28. package/dist/cli/validate.js +74 -0
  29. package/dist/cli.js +222 -0
  30. package/dist/config/apps.js +21 -0
  31. package/dist/config/load-config.js +30 -0
  32. package/dist/config/schema.js +97 -0
  33. package/dist/config/select-app.js +10 -0
  34. package/dist/config/select-platforms.js +17 -0
  35. package/dist/config/single-app.js +16 -0
  36. package/dist/config/types.js +1 -0
  37. package/dist/config/validate-base-dirs.js +33 -0
  38. package/dist/config/validate-credential-env-names.js +32 -0
  39. package/dist/config/validate-platform-identifiers.js +24 -0
  40. package/dist/formats/load-metadata.js +38 -0
  41. package/dist/formats/metadata-types.js +1 -0
  42. package/dist/formats/screenshot-types.js +1 -0
  43. package/dist/formats/serialize-metadata.js +20 -0
  44. package/dist/locales/groups.js +12 -0
  45. package/dist/locales/map.js +15 -0
  46. package/dist/locales/normalize.js +22 -0
  47. package/dist/locales/types.js +1 -0
  48. package/dist/locales/validate-groups.js +14 -0
  49. package/dist/platforms/apple/client.js +109 -0
  50. package/dist/platforms/apple/metadata/pull.js +120 -0
  51. package/dist/platforms/apple/metadata/push.js +272 -0
  52. package/dist/platforms/apple/metadata/types.js +1 -0
  53. package/dist/platforms/apple/screenshots/pull.js +160 -0
  54. package/dist/platforms/apple/screenshots/push.js +418 -0
  55. package/dist/platforms/google/client.js +42 -0
  56. package/dist/platforms/google/edits.js +38 -0
  57. package/dist/platforms/google/metadata/pull.js +23 -0
  58. package/dist/platforms/google/metadata/push.js +73 -0
  59. package/dist/platforms/google/metadata/types.js +1 -0
  60. package/dist/platforms/google/screenshots/pull.js +129 -0
  61. package/dist/platforms/google/screenshots/push.js +252 -0
  62. package/dist/platforms/google/screenshots/types.js +7 -0
  63. package/dist/validation/metadata/apple.js +31 -0
  64. package/dist/validation/metadata/files.js +58 -0
  65. package/dist/validation/metadata/google.js +46 -0
  66. package/dist/validation/screenshots/extensions.js +17 -0
  67. package/dist/validation/screenshots/files.js +55 -0
  68. package/dist/validation/screenshots/folders.js +41 -0
  69. package/dist/validation/screenshots/order.js +25 -0
  70. package/dist/writers/ensure-directory.js +16 -0
  71. package/dist/writers/order-screenshots.js +19 -0
  72. package/dist/writers/resolve-screenshot-path.js +8 -0
  73. package/dist/writers/resolve-within-base-dir.js +17 -0
  74. package/dist/writers/write-metadata.js +17 -0
  75. package/docs/API_EDITABLE_METADATA_SURFACE.md +319 -0
  76. package/docs/AUTH_SETUP.md +67 -0
  77. package/docs/DOCUMENTATION.md +285 -0
  78. package/docs/PROJECT_PLAN.md +687 -0
  79. package/docs/RELEASE_VERIFICATION.md +70 -0
  80. package/docs/TODO.md +308 -0
  81. package/examples/README.md +8 -0
  82. package/examples/metadata/apple/en-US.yml +11 -0
  83. package/examples/metadata/apple/tr.yml +11 -0
  84. package/examples/metadata/google/en-US.yml +6 -0
  85. package/examples/metadata/google/tr.yml +6 -0
  86. package/examples/screenshots/apple/en-US/APP_IPHONE_65/1.png +1 -0
  87. package/examples/screenshots/apple/tr/APP_IPHONE_65/1.png +1 -0
  88. package/examples/screenshots/google/en-US/phoneScreenshots/1.png +1 -0
  89. package/examples/screenshots/google/tr/phoneScreenshots/1.png +1 -0
  90. package/examples/storemeta.yml +29 -0
  91. package/package.json +55 -0
  92. package/storemeta.release.example.yml +27 -0
@@ -0,0 +1,687 @@
1
+ # storemeta Project Plan
2
+
3
+ `storemeta` is a TypeScript CLI for pulling, validating, and pushing App Store Connect and Google Play metadata and screenshots.
4
+
5
+ This document is the implementation plan and historical project specification for v1. For current user-facing behavior and config reference, see [`DOCUMENTATION.md`](DOCUMENTATION.md).
6
+
7
+ ## 1. Project Status
8
+
9
+ Current stage:
10
+ - core CLI implemented with automated tests passing
11
+ - remaining work is release verification against real Apple and Google test apps
12
+
13
+ Locked decisions:
14
+ - language: TypeScript
15
+ - initial distribution: npm only
16
+ - npm package name: `storemeta`
17
+ - primary CLI binary name: `storemeta`
18
+ - default config file name: `storemeta.yml`
19
+ - scope: metadata + screenshots
20
+ - sync direction: both pull and push
21
+ - command style: noun-first
22
+ - config: one root YAML file
23
+ - metadata file support: `.yml`, `.yaml`, and `.md` files whose contents are YAML
24
+ - validation: strict by default
25
+ - license: MIT
26
+
27
+ Still flexible:
28
+ - public-release hardening based on real App Store Connect and Google Play verification
29
+
30
+ Naming note:
31
+ - `sm` is intentionally not the primary command because it is too short and more likely to collide with other tools
32
+
33
+ ## 2. Why This Project Exists
34
+
35
+ Managing App Store Connect and Google Play metadata is repetitive, error-prone, and difficult to standardize across apps and locales.
36
+
37
+ What is needed is a dedicated CLI that provides:
38
+ - a stable command surface
39
+ - a documented config format
40
+ - deterministic pull and push behavior
41
+ - strong validation before writes
42
+ - a clean npm distribution story
43
+
44
+ The goal of `storemeta` is to provide that reusable open source workflow.
45
+
46
+ ## 3. Goals
47
+
48
+ V1 goals:
49
+ - pull App Store and Google Play metadata into local files
50
+ - push local metadata to App Store and Google Play
51
+ - pull store screenshots into a local directory layout
52
+ - push local screenshots from a local directory layout
53
+ - validate content before upload
54
+ - support explicit locale mapping and screenshot grouping
55
+ - keep secrets out of the repository
56
+
57
+ V1 non-goals:
58
+ - Homebrew distribution
59
+ - in-place image editing or screenshot generation
60
+ - translation workflows
61
+ - release submission automation outside metadata and screenshot management
62
+
63
+ ## 4. Platform And Product Requirements
64
+
65
+ The CLI must cover both App Store Connect and Google Play with one consistent user experience.
66
+
67
+ ### Platform Requirements
68
+
69
+ Google Play requirements:
70
+ - authenticate with a service account
71
+ - perform write operations through an edit session
72
+ - commit the edit after successful changes
73
+ - support listing metadata and screenshots
74
+
75
+ App Store Connect requirements:
76
+ - authenticate with JWT-based API credentials
77
+ - handle the split between app info localization fields and version localization fields
78
+ - support screenshot set creation and upload completion flows
79
+ - support listing metadata and screenshots
80
+
81
+ ### Product Requirements
82
+
83
+ The product must provide:
84
+ - shared config instead of inline constants
85
+ - shared auth loading instead of command-local credential logic
86
+ - shared locale normalization and grouping
87
+ - deterministic filesystem layout
88
+ - YAML parsing for metadata files
89
+ - reusable platform adapters
90
+ - strict validation before write operations
91
+
92
+ ### Required Implementation Patterns
93
+
94
+ These behaviors are part of the intended design:
95
+ - Google write operations should share one edit-session helper
96
+ - Apple metadata mapping should explicitly model separate localization resource types
97
+ - Apple screenshot uploads should use a reserve-upload-commit pipeline
98
+ - screenshot files should be processed in deterministic numeric order
99
+ - locale grouping should be config-driven
100
+ - dry-run mode should exist for destructive operations
101
+ - commands should print per-locale progress and final summaries
102
+
103
+ ### Behaviors To Avoid
104
+
105
+ The product must avoid:
106
+ - embedded secrets
107
+ - hardcoded credential paths
108
+ - regex parsing for structured metadata content
109
+ - duplicated locale logic across commands
110
+ - typo-dependent folder conventions
111
+ - hardcoded screenshot type assumptions with no override path
112
+ - mixing config parsing, API transport, validation, and output formatting in one module
113
+
114
+ ### Product Gaps To Close Before Public Release
115
+
116
+ These capabilities should be verified before the first public release:
117
+ - metadata pull and push against a real Apple test app
118
+ - metadata pull and push against a real Google Play test app
119
+ - screenshot pull and push against real Apple and Google test apps
120
+ - no secrets in logs, package contents, examples, docs, or git history
121
+ - npm package install and binary execution from the packed tarball
122
+
123
+ ## 5. Architecture Direction
124
+
125
+ The CLI is implemented as a TypeScript Node.js project.
126
+
127
+ Recommended internal modules:
128
+ - `cli`
129
+ - `config`
130
+ - `formats/yaml`
131
+ - `locales`
132
+ - `writers`
133
+ - `validation/metadata`
134
+ - `validation/screenshots`
135
+ - `auth/apple`
136
+ - `auth/google`
137
+ - `platforms/apple/metadata`
138
+ - `platforms/apple/screenshots`
139
+ - `platforms/google/metadata`
140
+ - `platforms/google/screenshots`
141
+
142
+ Tooling choices:
143
+ - CLI parser: `commander`
144
+ - HTTP client: native `fetch` from Node.js 20+
145
+ - Test runner: `vitest`
146
+ - Linting and formatting: still deferred
147
+
148
+ High-level design:
149
+ - one unified CLI surface
150
+ - one root config file
151
+ - two platform adapters: Apple and Google
152
+ - local normalized file layout
153
+ - strict validation for loaded inputs before write operations
154
+
155
+ Implementation guidance:
156
+ - Google commands should share one edit-session helper
157
+ - Apple metadata should share one mapper that understands both localization resource types
158
+ - Apple screenshots should share one upload pipeline abstraction
159
+ - all pull commands should write through one deterministic file writer layer
160
+ - all locale mapping should flow through one normalization module
161
+
162
+ ## 6. CLI Specification
163
+
164
+ The CLI follows a noun-first structure.
165
+
166
+ ### Command Tree
167
+
168
+ ```text
169
+ storemeta init
170
+ storemeta validate
171
+ storemeta metadata pull
172
+ storemeta metadata push
173
+ storemeta screenshots pull
174
+ storemeta screenshots push
175
+ ```
176
+
177
+ ### Global Options
178
+
179
+ Available to all commands unless a command narrows them:
180
+ - `--config <path>`
181
+ - `--app <id>`
182
+ - `--platform <apple|google|all>`
183
+ - `--locale <code>`
184
+ - `--dry-run`
185
+ - `--verbose`
186
+
187
+ ### `storemeta init`
188
+
189
+ Purpose:
190
+ - create a starter `storemeta.yml`
191
+ - create example metadata and screenshots directories
192
+
193
+ Behavior:
194
+ - do not overwrite existing files unless a future `--force` is added
195
+
196
+ Examples:
197
+
198
+ ```bash
199
+ storemeta init
200
+ storemeta --config ./apps/demo/storemeta.yml init
201
+ ```
202
+
203
+ ### `storemeta validate`
204
+
205
+ Purpose:
206
+ - validate local config, metadata files, screenshot layout, and platform-specific limits
207
+
208
+ Validation scope:
209
+ - config schema validity
210
+ - required credentials presence
211
+ - locale mapping consistency
212
+ - file existence
213
+ - metadata length rules
214
+ - screenshot folder and file naming rules
215
+
216
+ Exit behavior:
217
+ - exit `0` on success
218
+ - exit non-zero when blocking issues exist
219
+
220
+ Examples:
221
+
222
+ ```bash
223
+ storemeta validate
224
+ storemeta validate --platform apple
225
+ storemeta validate --app example-app --platform all
226
+ ```
227
+
228
+ ### `storemeta metadata pull`
229
+
230
+ Purpose:
231
+ - fetch metadata from stores into the local file layout
232
+
233
+ Behavior:
234
+ - fetch all target locales or requested locale subsets
235
+ - normalize platform data into local schema
236
+ - write one file per locale per platform
237
+ - preserve deterministic key ordering
238
+
239
+ Implementation status:
240
+ - implemented as a first-class CLI command for Apple and Google metadata
241
+
242
+ Examples:
243
+
244
+ ```bash
245
+ storemeta metadata pull --platform apple
246
+ storemeta metadata pull --platform google --locale en-US
247
+ ```
248
+
249
+ ### `storemeta metadata push`
250
+
251
+ Purpose:
252
+ - push local metadata files to stores
253
+
254
+ Behavior:
255
+ - validate loaded metadata documents before upload
256
+ - respect `--dry-run`
257
+ - update existing localizations when present
258
+ - create missing localizations when the platform allows it
259
+ - print per-locale results
260
+
261
+ Examples:
262
+
263
+ ```bash
264
+ storemeta metadata push --platform google --dry-run
265
+ storemeta metadata push --platform apple --locale tr
266
+ ```
267
+
268
+ ### `storemeta screenshots pull`
269
+
270
+ Purpose:
271
+ - fetch screenshots from stores into the local screenshot layout
272
+
273
+ Behavior:
274
+ - fetch by locale and display type where supported
275
+ - write deterministic file names such as `1.png`, `2.png`, `3.png`
276
+
277
+ Implementation status:
278
+ - implemented as a first-class CLI command for Apple and Google screenshots
279
+
280
+ ### `storemeta screenshots push`
281
+
282
+ Purpose:
283
+ - push local screenshots to stores
284
+
285
+ Behavior:
286
+ - validate loaded screenshot sets before upload
287
+ - respect `--dry-run`
288
+ - replace existing screenshots in target sets only when `--replace` is supplied
289
+ - print per-locale summaries
290
+
291
+ Examples:
292
+
293
+ ```bash
294
+ storemeta screenshots push --platform apple --dry-run
295
+ storemeta screenshots push --platform apple --replace
296
+ storemeta screenshots push --platform google --locale en-US
297
+ ```
298
+
299
+ ### Output Rules
300
+
301
+ Default output should be human-readable:
302
+ - command header
303
+ - selected app and platform
304
+ - validation summary
305
+ - per-locale progress
306
+ - final totals
307
+
308
+ Possible later extension:
309
+ - `--json` output for CI
310
+
311
+ ### Failure Rules
312
+
313
+ - invalid config: fail before network work
314
+ - missing credentials: fail before network work
315
+ - validation failure on push: fail before writes
316
+ - current behavior: blocking failures throw and return non-zero
317
+ - future behavior: aggregate partial failures and print a clear summary
318
+
319
+ ### Reserved Future Commands
320
+
321
+ Not in v1, but the tree should allow for:
322
+ - `storemeta auth check`
323
+ - `storemeta locales list`
324
+ - `storemeta config doctor`
325
+ - `storemeta metadata diff`
326
+ - `storemeta screenshots diff`
327
+
328
+ ## 7. Config Specification
329
+
330
+ ### Root Config File
331
+
332
+ Default file name:
333
+
334
+ ```text
335
+ storemeta.yml
336
+ ```
337
+
338
+ Override:
339
+
340
+ ```bash
341
+ storemeta --config ./path/to/storemeta.yml validate
342
+ ```
343
+
344
+ ### Root Config Format
345
+
346
+ The root config file is YAML.
347
+
348
+ Metadata content files may use:
349
+ - `.yml`
350
+ - `.yaml`
351
+ - `.md`
352
+
353
+ For `.md` files in v1, the file contents are parsed as YAML. Mixed markdown prose is out of scope for v1.
354
+
355
+ ### Implemented Root Shape
356
+
357
+ ```yaml
358
+ version: 1
359
+
360
+ project:
361
+ name: example-project
362
+ defaultApp: example-app
363
+
364
+ apps:
365
+ example-app:
366
+ metadata:
367
+ baseDir: metadata
368
+ format: yaml
369
+ screenshots:
370
+ baseDir: screenshots
371
+
372
+ apple:
373
+ appId: "0000000000"
374
+ credentials:
375
+ issuerIdEnv: STORE_APPLE_ISSUER_ID
376
+ keyIdEnv: STORE_APPLE_KEY_ID
377
+ privateKeyPathEnv: STORE_APPLE_PRIVATE_KEY_PATH
378
+ locales:
379
+ default: [en-US]
380
+ map:
381
+ zh-CN: zh-Hans
382
+ zh-TW: zh-Hant
383
+
384
+ google:
385
+ packageName: com.example.app
386
+ credentials:
387
+ serviceAccountPathEnv: STORE_GOOGLE_SERVICE_ACCOUNT_PATH
388
+ locales:
389
+ default: [en-US]
390
+ map:
391
+ en_US: en-US
392
+ iw-IL: he-IL
393
+ screenshots:
394
+ groups:
395
+ english:
396
+ locales: [en-US, en-GB, en-AU, en-CA]
397
+ spanish:
398
+ locales: [es-ES, es-419, es-US]
399
+ ```
400
+
401
+ ### App Model
402
+
403
+ The config intentionally supports both single-app and multi-app usage.
404
+
405
+ Single-app usage:
406
+ - define one entry under `apps`
407
+ - set `project.defaultApp`
408
+ - omit `--app` in normal usage
409
+
410
+ Multi-app usage:
411
+ - define multiple app entries
412
+ - use `--app <id>` when needed
413
+
414
+ This avoids blocking the implementation on a final app model decision.
415
+
416
+ ### Metadata File Layout
417
+
418
+ Recommended:
419
+
420
+ ```text
421
+ metadata/
422
+ apple/
423
+ en-US.yml
424
+ tr.yml
425
+ google/
426
+ en-US.yml
427
+ tr-TR.yml
428
+ ```
429
+
430
+ Allowed alternative:
431
+
432
+ ```text
433
+ metadata/
434
+ apple/
435
+ en-US.md
436
+ google/
437
+ en-US.md
438
+ ```
439
+
440
+ ### Metadata Schema
441
+
442
+ #### Apple
443
+
444
+ ```yaml
445
+ locale: en-US
446
+ app_name: Example App
447
+ subtitle: Short subtitle
448
+ keywords: one,two,three
449
+ promotional_text: Optional promo text
450
+ description: |
451
+ Long description text.
452
+ whats_new: |
453
+ What changed in this version.
454
+ support_url: https://example.com/support
455
+ marketing_url: https://example.com
456
+ privacy_policy_url: https://example.com/privacy
457
+ ```
458
+
459
+ #### Google
460
+
461
+ ```yaml
462
+ locale: en-US
463
+ title: Example App
464
+ short_description: Short description
465
+ full_description: |
466
+ Long description text.
467
+ video: https://example.com/video
468
+ ```
469
+
470
+ ### Screenshot Layout
471
+
472
+ Recommended:
473
+
474
+ ```text
475
+ screenshots/
476
+ apple/
477
+ en-US/
478
+ APP_IPHONE_65/
479
+ 1.png
480
+ 2.png
481
+ google/
482
+ en-US/
483
+ phoneScreenshots/
484
+ 1.png
485
+ 2.png
486
+ ```
487
+
488
+ Canonical stored values should match platform display types and image types.
489
+
490
+ The product should normalize pulled assets into locale-specific folders while still allowing config-driven grouping for push behavior.
491
+
492
+ ### Credentials
493
+
494
+ Secrets must never be committed.
495
+
496
+ Recommended environment variables:
497
+
498
+ Apple:
499
+ - `STORE_APPLE_ISSUER_ID`
500
+ - `STORE_APPLE_KEY_ID`
501
+ - `STORE_APPLE_PRIVATE_KEY_PATH`
502
+
503
+ Possible later support:
504
+ - `STORE_APPLE_PRIVATE_KEY`
505
+
506
+ Google:
507
+ - `STORE_GOOGLE_SERVICE_ACCOUNT_PATH`
508
+
509
+ Possible later support:
510
+ - `STORE_GOOGLE_SERVICE_ACCOUNT_JSON`
511
+
512
+ ### Auth Troubleshooting
513
+
514
+ Apple:
515
+ - confirm `STORE_APPLE_ISSUER_ID`, `STORE_APPLE_KEY_ID`, and `STORE_APPLE_PRIVATE_KEY_PATH` are set in the shell that runs `storemeta`
516
+ - confirm the `.p8` file exists at `STORE_APPLE_PRIVATE_KEY_PATH`
517
+ - confirm the key belongs to App Store Connect API access, not another Apple credential type
518
+ - confirm the API key has access to the target app in App Store Connect
519
+ - if the CLI reports a missing Apple credential env var, fix the env var name or shell export first before checking API behavior
520
+
521
+ Google:
522
+ - confirm `STORE_GOOGLE_SERVICE_ACCOUNT_PATH` points to a readable service account JSON file
523
+ - confirm the service account has Play Console access to the target app
524
+ - confirm the configured `packageName` matches the Play Console app exactly
525
+ - if the CLI reports a missing Google credential env var, fix the env var export first before checking API behavior
526
+
527
+ General:
528
+ - run `storemeta validate` before any push command
529
+ - keep credentials out of `storemeta.yml`
530
+ - prefer absolute credential file paths in local environment exports to avoid path confusion across shells and CI jobs
531
+
532
+ ### Validation Rules
533
+
534
+ The config validator should enforce:
535
+ - `version` exists and is supported
536
+ - `project.defaultApp` points to a real app key
537
+ - each selected platform has required identifiers
538
+ - each selected platform has credentials configured
539
+ - base directories are relative and valid
540
+ - locale overrides are explicit and deterministic
541
+
542
+ ### Backward Compatibility
543
+
544
+ The config version must be explicit. Breaking changes should bump `version`.
545
+
546
+ ## 8. Validation Requirements
547
+
548
+ Validation is a first-class feature, not an afterthought.
549
+
550
+ The validator should check:
551
+ - config schema
552
+ - credentials presence
553
+ - metadata required fields
554
+ - metadata length rules
555
+ - locale mapping consistency
556
+ - screenshot path structure
557
+ - screenshot file ordering and supported extensions
558
+
559
+ Examples of platform-specific validation:
560
+
561
+ Google Play metadata:
562
+ - title length
563
+ - short description length
564
+ - full description length
565
+
566
+ Apple metadata:
567
+ - presence and validity of locale-specific fields
568
+ - future support for field length validation where practical
569
+
570
+ Screenshot validation:
571
+ - required directories exist
572
+ - files are ordered deterministically
573
+ - extensions are supported
574
+ - display type and image type folder names are valid
575
+
576
+ Additional validation rules for v1:
577
+ - destructive screenshot replacement must require a fully valid source set
578
+ - locale groups must resolve deterministically to target locales
579
+ - excluded screenshot files, if configured, should be applied predictably before upload planning
580
+ - Apple upload plans should validate the existence of required screenshot set display types before write operations where possible
581
+
582
+ ## 9. Release Plan
583
+
584
+ ### Initial Distribution
585
+
586
+ Initial release target:
587
+ - npm only
588
+
589
+ Deferred:
590
+ - Homebrew
591
+
592
+ ### Planned Package Shape
593
+
594
+ - package name: `storemeta`
595
+ - executable name: `storemeta`
596
+ - compiled output in `dist/`
597
+ - npm package exports the CLI through the `bin` field
598
+
599
+ ### Open Source Defaults
600
+
601
+ - public GitHub repository
602
+ - MIT license
603
+ - semantic versioning
604
+ - `0.x` while config and commands are still changing
605
+ - `1.0.0` only after config and command stability
606
+
607
+ ### Minimum Release Checklist
608
+
609
+ Before the first public release:
610
+
611
+ 1. rotate and remove any preexisting development credentials before publishing
612
+ 2. remove secret-bearing files and code
613
+ 3. ensure no secrets remain in git history before publishing
614
+ 4. add `.gitignore`
615
+ 5. add `package.json`
616
+ 6. add TypeScript config and build scripts
617
+ 7. implement the documented CLI surface
618
+ 8. add smoke-level automated tests
619
+ 9. add example config and fake example metadata files
620
+ 10. verify npm install and CLI execution
621
+ 11. verify the CLI against one real Apple app and one real Google Play app using rotated credentials only
622
+
623
+ ### Suggested Repository Files
624
+
625
+ Minimum:
626
+ - `README.md`
627
+ - `docs/DOCUMENTATION.md`
628
+ - `docs/PROJECT_PLAN.md`
629
+ - `LICENSE`
630
+ - `SECURITY.md`
631
+ - `package.json`
632
+ - `tsconfig.json`
633
+ - `src/`
634
+
635
+ Likely next:
636
+ - `.gitignore`
637
+ - package `files` allowlist
638
+ - `CHANGELOG.md`
639
+ - `CONTRIBUTING.md`
640
+ - GitHub Actions workflows
641
+
642
+ ## 10. Security
643
+
644
+ Any development credentials that have ever been stored locally in this project must be treated as exposed until rotated.
645
+
646
+ Required actions before publishing:
647
+ - rotate the exposed App Store Connect keys
648
+ - remove or replace all secret-bearing code
649
+ - ensure secrets are not present in git history
650
+ - move all runtime credentials to environment variables or ignored local files
651
+
652
+ Secret handling rules for this project:
653
+ - never commit private keys
654
+ - never commit service account JSON files
655
+ - never commit real `.env` files
656
+ - use fake values in examples and tests
657
+ - prefer environment variables over inline config
658
+
659
+ ## 11. Feasibility
660
+
661
+ This project is feasible now.
662
+
663
+ The required integrations are within scope:
664
+ - App Store Connect JWT auth
665
+ - App Store metadata reads and writes
666
+ - App Store screenshot upload flow
667
+ - Google Play edits flow
668
+ - Google Play metadata reads and writes
669
+ - Google Play screenshot upload flow
670
+
671
+ The remaining work is release verification:
672
+ - run the CLI against real Apple and Google test apps
673
+ - confirm no secret material is present in docs, logs, package contents, or git history
674
+ - publish the first npm package once verification is complete
675
+
676
+ The largest residual risk is real-store API behavior that unit tests cannot fully model.
677
+
678
+ ## 12. Recommended Next Steps
679
+
680
+ Release work should continue in this order:
681
+
682
+ 1. verify Apple metadata pull and push with a real test app
683
+ 2. verify Google metadata pull and push with a real test app
684
+ 3. verify Apple screenshot pull and push with a real test app
685
+ 4. verify Google screenshot pull and push with a real test app
686
+ 5. inspect packed package contents and git history for secrets
687
+ 6. publish and tag the first release