@mpgd/cli 0.14.0 → 0.15.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 (26) hide show
  1. package/dist/index.js +137 -8
  2. package/dist/microsoft-store-starter.d.ts +28 -0
  3. package/dist/microsoft-store-starter.js +655 -0
  4. package/dist/production-target-readiness.js +3 -1
  5. package/package.json +7 -7
  6. package/templates/phaser-game/.agents/skills/release-microsoft-store/SKILL.md +60 -0
  7. package/templates/phaser-game/.agents/skills/release-microsoft-store/agents/openai.yaml +4 -0
  8. package/templates/phaser-game/.agents/skills/use-mpgd-kit/SKILL.md +45 -0
  9. package/templates/phaser-game/.agents/skills/use-mpgd-kit/agents/openai.yaml +4 -0
  10. package/templates/phaser-game/AGENTS.md +34 -0
  11. package/templates/phaser-game/README.md +50 -25
  12. package/templates/phaser-game/agent/acceptance.md +8 -0
  13. package/templates/phaser-game/agent/brief.md +13 -1
  14. package/templates/phaser-game/agent/game-manifest.json +7 -0
  15. package/templates/phaser-game/apps/target-ait/granite.config.ts +35 -0
  16. package/templates/phaser-game/apps/target-ait/index.html +15 -0
  17. package/templates/phaser-game/apps/target-ait/package.json +33 -0
  18. package/templates/phaser-game/apps/target-ait/src/main.ts +34 -0
  19. package/templates/phaser-game/apps/target-ait/src/styles.css +33 -0
  20. package/templates/phaser-game/apps/target-ait/tsconfig.json +8 -0
  21. package/templates/phaser-game/apps/target-ait/vite.config.ts +53 -0
  22. package/templates/phaser-game/docs/MPGD_KIT_WORKFLOWS.md +128 -0
  23. package/templates/phaser-game/gitignore +6 -0
  24. package/templates/phaser-game/mpgd.targets.json +9 -2
  25. package/templates/phaser-game/package.json +10 -10
  26. package/templates/phaser-game/vite.shared.ts +13 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpgd/cli",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Gunshi CLI for mpgd-kit starter generation and target workflow orchestration.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -50,18 +50,18 @@
50
50
  "@types/node": "^24.0.0",
51
51
  "ttsc": "0.18.4",
52
52
  "typescript": "7.0.2",
53
- "@mpgd/adapter-ait": "0.4.4",
54
- "@mpgd/adapter-browser": "0.5.0",
55
53
  "@mpgd/adapter-capacitor": "0.4.4",
54
+ "@mpgd/adapter-browser": "0.5.0",
56
55
  "@mpgd/adapter-devvit": "0.8.4",
57
- "@mpgd/analytics": "0.3.7",
58
56
  "@mpgd/adapter-verse8": "0.2.1",
57
+ "@mpgd/adapter-ait": "0.5.0",
58
+ "@mpgd/analytics": "0.3.7",
59
59
  "@mpgd/bridge": "0.6.1",
60
- "@mpgd/catalog": "0.5.0",
61
- "@mpgd/game-services": "0.10.0",
62
60
  "@mpgd/i18n": "0.5.3",
61
+ "@mpgd/game-services": "0.10.0",
62
+ "@mpgd/catalog": "0.5.0",
63
63
  "@mpgd/phaser-assets": "0.4.1",
64
- "@mpgd/target-config": "0.8.0",
64
+ "@mpgd/target-config": "0.9.0",
65
65
  "@mpgd/platform": "0.7.0"
66
66
  },
67
67
  "main": "./dist/index.js",
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: release-microsoft-store
3
+ description: Prepare, package, and verify this game's Microsoft Store PWA release. Use when configuring Store identity or listing data, building the microsoft-store target, running submission preflight, generating a PWABuilder package ZIP, inspecting MSIX/AppX bundles, collecting optional WACK evidence, or preparing Partner Center submission evidence.
4
+ ---
5
+
6
+ # Release to Microsoft Store
7
+
8
+ Read `docs/MPGD_KIT_WORKFLOWS.md`, `mpgd.microsoft-store.json`, and the
9
+ `microsoft-store` entry in `mpgd.targets.json`. If the target is absent, stop
10
+ and run `pnpm exec mpgd target init microsoft-store --game .` before editing
11
+ Store-specific files.
12
+
13
+ ## Prepare the PWA
14
+
15
+ 1. Replace every placeholder in `mpgd.microsoft-store.json` with the reserved
16
+ Partner Center identity, publisher, listing, age-rating, privacy, and
17
+ screenshot data.
18
+ 2. Keep the web manifest ID, start URL, scope, orientation, icons, and deployed
19
+ URL aligned with the game-owned PWA.
20
+ 3. Generate and verify production icons with `pnpm icons:generate` and
21
+ `pnpm icons:verify`.
22
+ 4. Run `pnpm build:microsoft-store`, `pnpm smoke:microsoft-store`, and
23
+ `pnpm preflight:microsoft-store`. Fix warnings that reflect missing
24
+ submission inputs; retain the resulting preflight JSON and Markdown.
25
+
26
+ ## Generate and accept packages
27
+
28
+ 1. Deploy the exact bytes that passed preflight. Do not rebuild between
29
+ preflight, deployment, and package generation.
30
+ 2. Set `PWA_URL` and `MANIFEST_URL` to the public production endpoints, then
31
+ run:
32
+
33
+ ```sh
34
+ pnpm package:microsoft-store -- \
35
+ --pwa-url "$PWA_URL" \
36
+ --manifest-url "$MANIFEST_URL" \
37
+ --package-version <four-part-version> \
38
+ --classic-version <lower-four-part-version>
39
+ ```
40
+
41
+ 3. Keep `release-input/microsoft-store/pwabuilder-package.zip` together with
42
+ `release-output/microsoft-store/package-generation.json` and `.md`.
43
+ 4. On Windows with the current SDK, inspect the generated MSIX/AppX bundles
44
+ using:
45
+
46
+ ```sh
47
+ pnpm exec mpgd target accept-package microsoft-store \
48
+ --packages <game-relative-package-paths>
49
+ ```
50
+
51
+ Keep `package-acceptance.json` and `.md`.
52
+ 5. Treat WACK as optional recommended evidence. Pass `--appcert
53
+ <path-to-appcert.exe>` only when the active Windows environment can run it;
54
+ do not block otherwise valid package acceptance solely because WACK was not
55
+ run.
56
+
57
+ Require identity, version, signature, payload, submission-evidence, and package
58
+ hash checks to pass before Partner Center submission. Never grant purchases
59
+ from client callbacks; add Store commerce only through a dedicated adapter and
60
+ backend ledger verification.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Release to Microsoft Store"
3
+ short_description: "Build and verify Microsoft Store PWA releases"
4
+ default_prompt: "Prepare this game for a Microsoft Store PWA release and produce the required acceptance evidence."
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: use-mpgd-kit
3
+ description: Route Phaser game development, platform integration, target builds, icons, localization, analytics, game services, acceptance, and release work through this generated game's mpgd-kit contracts. Use for any change that adds gameplay-facing platform behavior, configures a distribution target, prepares release evidence, or needs to discover which mpgd capability and validation flow applies.
4
+ ---
5
+
6
+ # Use mpgd-kit
7
+
8
+ Read `AGENTS.md`, `agent/game-manifest.json`, and
9
+ `docs/MPGD_KIT_WORKFLOWS.md` before editing. Treat the manifest as the list of
10
+ enabled targets and the workflow guide as the routing reference.
11
+
12
+ ## Route the request
13
+
14
+ - Put deterministic state and rules in game/simulation modules.
15
+ - Keep Phaser scenes limited to rendering and input glue.
16
+ - Route identity, storage, commerce, ads, leaderboard, lifecycle, and host
17
+ presentation through `PlatformGateway`.
18
+ - Keep SDK imports in adapters or target wrappers.
19
+ - Route purchases, rewarded-ad grants, and verified scores through a backend
20
+ ledger or verifier before mutating durable state.
21
+ - Use `@mpgd/target-config` for target-owned runtime configuration and
22
+ `mpgd.targets.json` for build ownership.
23
+ - Use the generated icon, localization, analytics, acceptance, and evidence
24
+ flows instead of creating target-specific copies.
25
+ - For a configured target with a target skill in `agent/game-manifest.json`,
26
+ read that skill before changing its release flow.
27
+
28
+ ## Work in order
29
+
30
+ 1. Identify the owning capability and files from the manifest and workflow
31
+ guide.
32
+ 2. Inspect the target entry and effective configuration; do not assume a target
33
+ is enabled.
34
+ 3. Implement the smallest change that preserves `PlatformGateway` and backend
35
+ authority boundaries.
36
+ 4. Update `agent/game-manifest.json`, `agent/brief.md`, and acceptance guidance
37
+ when the game's capabilities or handoff contract changes.
38
+ 5. Run the focused check first, then `pnpm check`, `pnpm build`, and
39
+ `pnpm accept` when the change affects a handoff or target release.
40
+ 6. Preserve generated JSON/Markdown evidence under `artifacts/acceptance` or
41
+ the target's `release-output` directory.
42
+
43
+ Use official target documentation or the target's configured MCP for SDK and
44
+ submission requirements. Do not commit personal MCP configuration, tokens,
45
+ credentials, signing material, or platform login state.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Use mpgd-kit"
3
+ short_description: "Route game work through mpgd-kit workflows"
4
+ default_prompt: "Use the mpgd-kit workflow guide and project manifest to implement and validate this game change."
@@ -0,0 +1,34 @@
1
+ # Generated Game Agent Instructions
2
+
3
+ This repository is a standalone Phaser game generated with `@mpgd/create-game`.
4
+
5
+ ## Start here
6
+
7
+ - Read `agent/game-manifest.json` for enabled targets, capability ownership, and
8
+ target-specific skills.
9
+ - Use `.agents/skills/use-mpgd-kit/SKILL.md` for game, platform, target, build,
10
+ acceptance, or release work.
11
+ - Read `docs/MPGD_KIT_WORKFLOWS.md` only for the relevant capability or target.
12
+ - Keep `agent/brief.md` and `agent/acceptance.md` aligned with material changes.
13
+
14
+ ## Boundaries
15
+
16
+ - Keep deterministic game state outside Phaser scenes.
17
+ - Keep platform SDK imports in adapters or target wrappers.
18
+ - Use `PlatformGateway` from game-facing code; do not call platform SDKs from
19
+ scenes.
20
+ - Keep pure game packages free of Phaser, DOM, network, and platform SDKs.
21
+ - Send purchases, rewarded-ad grants, and verified scores through backend
22
+ ledger or verifier APIs before changing durable state.
23
+ - Do not put side effects inside debug calls that a production strip pass may
24
+ remove.
25
+ - Do not commit secrets, signing keys, personal MCP configuration, or platform
26
+ authentication state.
27
+
28
+ ## Tooling and checks
29
+
30
+ - Use `ttsx`, not `tsx`, for TypeScript scripts.
31
+ - Use `ttsc` and `@ttsc/lint`; do not add ESLint or Prettier for TypeScript.
32
+ - Run focused checks, then `pnpm check` and `pnpm build`.
33
+ - Run `pnpm accept` before a target handoff or release. Keep its evidence and
34
+ any target-specific release evidence with the handoff.
@@ -2,6 +2,11 @@
2
2
 
3
3
  Standalone Phaser 4 game starter generated by `@mpgd/create-game`.
4
4
 
5
+ For agent-assisted work, start with `AGENTS.md`, then use
6
+ `.agents/skills/use-mpgd-kit/SKILL.md` and
7
+ `docs/MPGD_KIT_WORKFLOWS.md` to route platform, content, service, target, and
8
+ release changes through the generated game manifest.
9
+
5
10
  ## Local Loop
6
11
 
7
12
  ```sh
@@ -31,17 +36,17 @@ platform-specific artifacts. Keep an `mpgd-kit` checkout nearby and pass it with
31
36
  pnpm exec mpgd target build-all \
32
37
  --targets-file ./mpgd.targets.json \
33
38
  --kit-path ../mpgd-kit \
34
- --targets web,microsoft-store,verse8,ait,reddit \
39
+ --targets __RECOMMENDED_MATRIX_TARGETS__ \
35
40
  --profile staging \
36
41
  --ait-variant wrapper
37
42
  pnpm exec mpgd target smoke-all \
38
43
  --targets-file ./mpgd.targets.json \
39
44
  --kit-path ../mpgd-kit \
40
- --targets web,microsoft-store,verse8,ait,reddit
45
+ --targets __RECOMMENDED_MATRIX_TARGETS__
41
46
  pnpm exec mpgd target doctor \
42
47
  --targets-file ./mpgd.targets.json \
43
48
  --kit-path ../mpgd-kit \
44
- --targets web,microsoft-store,verse8,ait,reddit
49
+ --targets __RECOMMENDED_MATRIX_TARGETS__
45
50
  ```
46
51
 
47
52
  When developing the kit itself, the same commands work through the repository
@@ -51,7 +56,7 @@ script:
51
56
  pnpm --dir ../mpgd-kit mpgd target build-all \
52
57
  --targets-file "$PWD/mpgd.targets.json" \
53
58
  --kit-path ../mpgd-kit \
54
- --targets web,microsoft-store,verse8,ait,reddit \
59
+ --targets __RECOMMENDED_MATRIX_TARGETS__ \
55
60
  --profile staging \
56
61
  --ait-variant wrapper
57
62
  ```
@@ -60,18 +65,30 @@ pnpm --dir ../mpgd-kit mpgd target build-all \
60
65
  into `.mpgd.targets.generated.json` before calling the kit's existing target
61
66
  build and smoke scripts.
62
67
 
63
- The starter's Apps in Toss and Capacitor entries intentionally point at kit
64
- reference wrappers, so their reusable validation builds use the `staging`
65
- profile. Before an AIT, Android, or iOS production build, copy or create the
66
- wrapper/shell under this game directory, update `mpgd.targets.json`, and set
67
- `VITE_MPGD_GAME_SERVICES_URL` to a public HTTPS endpoint without embedded
68
- credentials. Production preflight resolves real paths, rejects wrappers or
69
- shells outside the game root (including symbolic-link escapes), and blocks
70
- localhost plus literal private or reserved IP addresses.
68
+ The starter owns its Apps in Toss wrapper under `apps/target-ait`. With
69
+ `authoritativeGameServices: false`, production keeps native identity, storage,
70
+ sharing, and Game Center while disabling IAP and ads; no game-services URL is
71
+ required for that fail-closed first release. To enable purchases or ads later,
72
+ set the authority flag to `true`, add app-owned product or ad IDs, and configure
73
+ `VITE_MPGD_GAME_SERVICES_URL` to a public HTTPS verifier without embedded
74
+ credentials.
75
+
76
+ The Capacitor entries still intentionally point at kit reference shells, so
77
+ their reusable validation builds use the `staging` profile. Before an Android
78
+ or iOS production build, copy or create the shell under this game directory and
79
+ update `mpgd.targets.json`. Production preflight resolves real paths, rejects
80
+ wrappers or shells outside the game root (including symbolic-link escapes), and
81
+ blocks localhost plus literal private or reserved IP addresses.
71
82
 
72
83
  `mpgd target doctor` verifies that release manifest artifact paths stay under
73
- this game directory, even when a build used the kit reference Apps in Toss or
74
- Capacitor wrappers.
84
+ this game directory, including non-production builds that use kit reference
85
+ Capacitor shells.
86
+
87
+ Optional targets can add their own config, scripts, runtime wiring, and release
88
+ skill. To enable Microsoft Store after creation, run
89
+ `pnpm exec mpgd target init microsoft-store --game . --kit-path ../mpgd-kit`.
90
+ The initializer is idempotent and stops before writing when it finds conflicting
91
+ game-owned values.
75
92
 
76
93
  ## Acceptance Handoff
77
94
 
@@ -145,7 +162,7 @@ hard-lock the device. Use `responsive` when both orientations are playable,
145
162
  `prefer-landscape` or `prefer-portrait` when layout guidance should favor one
146
163
  orientation, and `lock-landscape` or `lock-portrait` when the game should show a
147
164
  soft rotate prompt on mismatch. The generated PWA manifest also declares
148
- `"orientation": "landscape"` for installed web and Microsoft Store shells; keep
165
+ `"orientation": "landscape"` for installed web shells; keep
149
166
  that manifest value aligned with the runtime policy if you make a portrait-first
150
167
  game.
151
168
 
@@ -213,8 +230,8 @@ pnpm build:ait
213
230
  pnpm smoke:ait
214
231
  ```
215
232
 
216
- The kit reference wrapper includes the Apps in Toss community devtools package
217
- for SDK mock and device debugging while the wrapper is still kit-owned:
233
+ The game-owned wrapper includes the Apps in Toss community devtools package for
234
+ SDK mocks and device debugging:
218
235
 
219
236
  ```sh
220
237
  pnpm ait:wrapper:dev
@@ -224,7 +241,7 @@ pnpm ait:devtools:mcp
224
241
  pnpm ait:devtools:mcp:mobile
225
242
  ```
226
243
 
227
- `ait:wrapper:dev` runs the kit wrapper with the community Vite plugin enabled.
244
+ `ait:wrapper:dev` runs `apps/target-ait` with the community Vite plugin enabled.
228
245
  It loads the last game bundle copied by `pnpm build:ait` from the wrapper's
229
246
  `public/game` directory, so run `pnpm build:ait` again after game changes before
230
247
  opening a wrapper devtools session. Use `ait:wrapper:dev:plain` to disable the
@@ -255,15 +272,15 @@ pnpm ait:console:deploy -- release-output/ait/YOUR_APP.ait
255
272
  `ait:console:register` creates the mini-app and writes its `miniAppId` back to
256
273
  that file. Before registration, add the real logo, thumbnail, and screenshot
257
274
  files referenced by `aitcc.yaml` under `./assets/`. Use `pnpm build:ait` for the
258
- kit wrapper smoke loop, and run `pnpm build:ait:package` before console deploys
259
- so `release-output/ait/` contains the `.ait` bundle you pass after `--`.
275
+ game-owned wrapper smoke loop, and run `pnpm build:ait:package` before console
276
+ deploys so `release-output/ait/` contains the `.ait` bundle you pass after `--`.
260
277
 
261
278
  The starter also installs `@apps-in-toss/web-framework` and awaits
262
279
  `install()` from `@ait-co/polyfill` only when `__APP_TARGET__` is `ait`. In the
263
280
  Apps in Toss WebView runtime, standard Web APIs such as `navigator.clipboard`,
264
281
  `navigator.geolocation`, `navigator.share`, `navigator.vibrate`, network status,
265
282
  and `_blank` `window.open` calls route through the Apps in Toss SDK. Plain
266
- browser, Microsoft Store, Reddit, Android, and iOS builds do not import the AIT
283
+ browser, Reddit, Android, and iOS builds do not import the AIT
267
284
  SDK chunk and keep their native browser behavior. `pnpm dev:ait` is useful for
268
285
  checking the AIT-gated bundle path, but SDK-backed API behavior should be
269
286
  verified in the Apps in Toss sandbox or a game-owned devtools setup. If your
@@ -271,9 +288,16 @@ game uses permission-gated APIs such as clipboard or geolocation, declare the
271
288
  matching permissions in the game-owned Apps in Toss `granite.config.ts` before
272
289
  submission.
273
290
 
291
+ The generated AIT target starts with `authoritativeGameServices: false`. Native
292
+ anonymous identity, persistent Storage, sharing, and Game Center remain
293
+ available, while IAP and ads are removed from the effective game configuration.
294
+ Only switch the flag to `true` after adding app-owned catalog/ad ids and a public
295
+ HTTPS game-services backend that verifies purchase or reward evidence.
296
+
274
297
  ## Target Ownership Notes
275
298
 
276
299
  - Browser preview is fully game-owned and writes to `artifacts/web-preview`.
300
+ <!-- mpgd:microsoft-store:start -->
277
301
  - Microsoft Store is a game-owned PWA target that reuses the browser adapter and
278
302
  writes to `artifacts/microsoft-store` with `manifest.webmanifest` for
279
303
  PWABuilder packaging. Replace the starter icon and manifest metadata before
@@ -323,6 +347,7 @@ submission.
323
347
  recommended optional local check; from an active administrator user session,
324
348
  pass `--appcert <path-to-appcert.exe>` to require `OVERALL_RESULT="PASS"`
325
349
  and bind its report hash.
350
+ <!-- mpgd:microsoft-store:end -->
326
351
  - Verse8 is a game-owned iframe web target that writes to `artifacts/verse8`.
327
352
  The adapter verifies the host-provided auth credential and distinguishes
328
353
  Verse8-signed accounts from self-signed guest accounts. Ads are available
@@ -343,10 +368,10 @@ submission.
343
368
  - Reddit Devvit is game-owned in `apps/target-devvit`. Its Redis-backed storage
344
369
  bridge fails closed on identity, provider, serialization, and quota errors;
345
370
  it never switches progress to browser `localStorage`.
346
- - Apps in Toss currently uses the kit reference wrapper at
347
- `${MPGD_KIT_PATH}/apps/target-ait` for smoke packaging. Before a real Toss
348
- submission, create a game-owned wrapper/config so the app name, CLI state, and
349
- review metadata are not shared with the kit demo.
371
+ - Apps in Toss is game-owned in `apps/target-ait`. The wrapper keeps the app
372
+ name, console state, review metadata, and `@ait-co/devtools` development
373
+ integration local to the game while reusing `@mpgd/adapter-ait` for the
374
+ production bridge and game-bundle loader.
350
375
  - Android and iOS currently use the kit reference Capacitor shell at
351
376
  `${MPGD_KIT_PATH}/apps/mobile-capacitor`. That is useful for local artifact
352
377
  checks, and final artifacts are copied back to this game's `release-output/`
@@ -2,6 +2,10 @@
2
2
 
3
3
  Run these checks before handing off a generated game starter:
4
4
 
5
+ Use `agent/game-manifest.json` and `.agents/skills/use-mpgd-kit/SKILL.md` to
6
+ select any target-specific acceptance workflow required by the configured
7
+ targets.
8
+
5
9
  ```sh
6
10
  pnpm icons:generate
7
11
  pnpm icons:verify
@@ -32,9 +36,13 @@ Play here starts gameplay inside the post, and the `game` entry opens the
32
36
  separate expanded mode Phaser document. Inline gameplay must remain tap/click
33
37
  only and must not trap feed scrolling.
34
38
 
39
+ <!-- mpgd:microsoft-store:start -->
35
40
  For Microsoft Store changes, keep the first pass as a PWA/web target that uses
36
41
  the browser adapter. Add a dedicated Store commerce adapter only when wiring
37
42
  Digital Goods API and Payment Request through backend ledger verification.
43
+ Run the generated Store release skill from build and preflight through package
44
+ acceptance; WACK is optional recommended evidence.
45
+ <!-- mpgd:microsoft-store:end -->
38
46
 
39
47
  ## Verse8 Agent8 Structured Server
40
48
 
@@ -2,6 +2,10 @@
2
2
 
3
3
  Build a Phaser 4 game on top of the mpgd platform boundary.
4
4
 
5
+ Read `AGENTS.md`, `agent/game-manifest.json`, and the generated
6
+ `.agents/skills/use-mpgd-kit/SKILL.md` router before changing kit-facing
7
+ capabilities or target workflows.
8
+
5
9
  Boundaries:
6
10
 
7
11
  - Phaser scenes render and collect input only.
@@ -20,8 +24,16 @@ pnpm check
20
24
  pnpm build
21
25
  pnpm icons:generate
22
26
  pnpm icons:verify
23
- pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets web,microsoft-store,verse8,ait,reddit --profile staging --ait-variant wrapper
27
+ pnpm exec mpgd target build-all --targets-file ./mpgd.targets.json --kit-path ../mpgd-kit --targets __RECOMMENDED_MATRIX_TARGETS__ --profile staging --ait-variant wrapper
24
28
  pnpm devvit:login
25
29
  pnpm devvit:init
26
30
  pnpm devvit:playtest
27
31
  ```
32
+
33
+ <!-- mpgd:microsoft-store:start -->
34
+ For Microsoft Store releases, use the generated
35
+ `.agents/skills/release-microsoft-store/SKILL.md` workflow. Build and preflight
36
+ the game-owned PWA before package generation, then run package acceptance on
37
+ Windows before Partner Center submission. WACK remains an optional recommended
38
+ evidence source, not a universal prerequisite.
39
+ <!-- mpgd:microsoft-store:end -->
@@ -8,6 +8,13 @@
8
8
  "targets": ["web-preview", "microsoft-store", "verse8", "android", "ios", "ait", "reddit"],
9
9
  "futureTargets": ["telegram", "tauri"],
10
10
  "platformBoundary": "PlatformGateway",
11
+ "agentWorkflow": {
12
+ "guide": "docs/MPGD_KIT_WORKFLOWS.md",
13
+ "routerSkill": ".agents/skills/use-mpgd-kit/SKILL.md",
14
+ "targetSkills": {
15
+ "microsoft-store": ".agents/skills/release-microsoft-store/SKILL.md"
16
+ }
17
+ },
11
18
  "mcpRequirements": {
12
19
  "ait": "Use apps-in-toss MCP before Apps in Toss SDK or review-flow changes.",
13
20
  "reddit": "Use Devvit documentation/MCP before Devvit SDK or publish-flow changes. Keep Reddit deployment files in apps/target-devvit."
@@ -0,0 +1,35 @@
1
+ import { defineConfig, type AppsInTossWebConfig } from '@apps-in-toss/web-framework/config';
2
+
3
+ const config: AppsInTossWebConfig = {
4
+ appName: readEnvString(process.env.MPGD_AIT_APP_NAME) ?? '__GAME_NAME__',
5
+ brand: {
6
+ displayName: readEnvString(process.env.MPGD_AIT_DISPLAY_NAME) ?? '__GAME_TITLE__',
7
+ primaryColor: readEnvString(process.env.MPGD_AIT_PRIMARY_COLOR) ?? '#101820',
8
+ icon: readEnvString(process.env.MPGD_AIT_BRAND_ICON_URL) ?? 'generated/console-icon.png',
9
+ },
10
+ permissions: [],
11
+ web: {
12
+ host: 'localhost',
13
+ port: 5173,
14
+ commands: {
15
+ dev: 'pnpm dev',
16
+ build: 'pnpm build',
17
+ },
18
+ },
19
+ webViewProps: {
20
+ bounces: false,
21
+ pullToRefreshEnabled: false,
22
+ overScrollMode: 'never',
23
+ allowsBackForwardNavigationGestures: false,
24
+ allowsInlineMediaPlayback: true,
25
+ },
26
+ };
27
+
28
+ const definedConfig: AppsInTossWebConfig = defineConfig(config);
29
+
30
+ export default definedConfig;
31
+
32
+ function readEnvString(input: string | undefined): string | undefined {
33
+ const trimmed = input?.trim();
34
+ return trimmed === undefined || trimmed.length === 0 ? undefined : trimmed;
35
+ }
@@ -0,0 +1,15 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta
6
+ name="viewport"
7
+ content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
8
+ />
9
+ <title>__GAME_TITLE__</title>
10
+ </head>
11
+ <body>
12
+ <main id="app"></main>
13
+ <script type="module" src="/src/main.ts"></script>
14
+ </body>
15
+ </html>
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "__PACKAGE_NAME__-target-ait",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite --host 0.0.0.0",
8
+ "dev:plain": "MPGD_AIT_DEVTOOLS=0 VITE_MPGD_AIT_MOCK_IDENTITY=1 vite --host 0.0.0.0",
9
+ "dev:phone": "AIT_TUNNEL=1 AIT_TUNNEL_CDP=1 vite --host 0.0.0.0",
10
+ "build": "vite build",
11
+ "ait:build": "ait build",
12
+ "ait:deploy": "ait deploy --api-key \"$AIT_API_KEY\"",
13
+ "devtools:mcp": "pnpm exec devtools-mcp",
14
+ "devtools:mcp:mobile": "pnpm exec devtools-mcp --target=mobile",
15
+ "check": "ttsc --noEmit -p tsconfig.json",
16
+ "lint": "ttsc --noEmit -p tsconfig.json",
17
+ "format": "ttsc format",
18
+ "fix": "ttsc fix"
19
+ },
20
+ "dependencies": {
21
+ "@apps-in-toss/web-framework": "^2.10.6",
22
+ "@mpgd/adapter-ait": "__MPGD_DEPENDENCY_VERSION_ADAPTER_AIT__"
23
+ },
24
+ "devDependencies": {
25
+ "@ait-co/devtools": "^0.1.138",
26
+ "@apps-in-toss/cli": "^2.10.6",
27
+ "@ttsc/unplugin": "0.18.4",
28
+ "@types/node": "^24.0.0",
29
+ "ttsc": "0.18.4",
30
+ "typescript": "7.0.2",
31
+ "vite": "^8.1.3"
32
+ }
33
+ }
@@ -0,0 +1,34 @@
1
+ import './styles.css';
2
+
3
+ import { installAitHostBridge, type InstallAitHostBridgeOptions } from '@mpgd/adapter-ait/host';
4
+ import { mountAitGameBundle } from '@mpgd/adapter-ait/wrapper';
5
+
6
+ declare const __MPGD_AIT_APP_NAME__: string;
7
+ declare const __MPGD_AIT_AD_GROUP_IDS__: Readonly<Record<string, string>>;
8
+ declare const __MPGD_AIT_AD_PLACEMENT_TYPES__: Readonly<
9
+ Record<string, 'rewarded' | 'interstitial'>
10
+ >;
11
+
12
+ installAitHostBridge({
13
+ appName: __MPGD_AIT_APP_NAME__,
14
+ adGroupIds: __MPGD_AIT_AD_GROUP_IDS__,
15
+ adPlacementTypes: __MPGD_AIT_AD_PLACEMENT_TYPES__,
16
+ ...identityBridgeOptions(),
17
+ });
18
+
19
+ const app = document.querySelector<HTMLElement>('#app');
20
+ if (app !== null) {
21
+ void mountAitGameBundle(app).catch((error: unknown) => {
22
+ console.error('AIT game bundle mount failed unexpectedly.', error);
23
+ });
24
+ }
25
+
26
+ function identityBridgeOptions(): Pick<InstallAitHostBridgeOptions, 'dependencies'> {
27
+ return import.meta.env.VITE_MPGD_AIT_MOCK_IDENTITY === '1'
28
+ ? {
29
+ dependencies: {
30
+ identityProvider: async () => ({ type: 'HASH', hash: 'ait-local-player' }),
31
+ },
32
+ }
33
+ : {};
34
+ }
@@ -0,0 +1,33 @@
1
+ html,
2
+ body,
3
+ #app {
4
+ width: 100%;
5
+ height: 100%;
6
+ margin: 0;
7
+ }
8
+
9
+ body {
10
+ background: #101820;
11
+ color: #f8fafc;
12
+ font-family:
13
+ Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
14
+ }
15
+
16
+ .shell {
17
+ min-height: 100%;
18
+ display: grid;
19
+ place-content: center;
20
+ gap: 12px;
21
+ padding: 24px;
22
+ box-sizing: border-box;
23
+ text-align: center;
24
+ }
25
+
26
+ h1,
27
+ p {
28
+ margin: 0;
29
+ }
30
+
31
+ code {
32
+ color: #fff7ad;
33
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["vite/client", "node"],
5
+ "noEmit": true
6
+ },
7
+ "include": ["src/**/*.ts", "vite.config.ts", "granite.config.ts"]
8
+ }
@@ -0,0 +1,53 @@
1
+ import { readFileSync } from 'node:fs';
2
+
3
+ import aitDevtools from '@ait-co/devtools/unplugin';
4
+ import { extractAitAdBridgeConfig } from '@mpgd/adapter-ait/ad-config';
5
+ import ttsc from '@ttsc/unplugin/vite';
6
+ import { defineConfig } from 'vite';
7
+
8
+ const isTruthyEnv = (value: string | undefined): boolean =>
9
+ value !== undefined && value !== '' && value !== '0' && value.toLowerCase() !== 'false';
10
+ const aitDevtoolsTunnel = isTruthyEnv(process.env.AIT_TUNNEL)
11
+ ? { cdp: isTruthyEnv(process.env.AIT_TUNNEL_CDP) }
12
+ : false;
13
+ const aitAppName = process.env.MPGD_AIT_APP_NAME?.trim() || '__GAME_NAME__';
14
+ const aitAdConfig = readAitAdConfig(process.env.MPGD_AD_PLACEMENTS_FILE);
15
+
16
+ export default defineConfig(({ command, isPreview }) => ({
17
+ define: {
18
+ __MPGD_AIT_APP_NAME__: JSON.stringify(aitAppName),
19
+ __MPGD_AIT_AD_GROUP_IDS__: JSON.stringify(aitAdConfig.adGroupIds),
20
+ __MPGD_AIT_AD_PLACEMENT_TYPES__: JSON.stringify(aitAdConfig.adPlacementTypes),
21
+ },
22
+ plugins: [
23
+ ...(command === 'serve' && !isPreview && process.env.MPGD_AIT_DEVTOOLS !== '0'
24
+ ? [aitDevtools.vite({ mcp: true, tunnel: aitDevtoolsTunnel })]
25
+ : []),
26
+ ttsc({ project: 'tsconfig.json', plugins: false }),
27
+ ],
28
+ build: {
29
+ target: 'es2022',
30
+ outDir: 'dist',
31
+ emptyOutDir: true,
32
+ },
33
+ }));
34
+
35
+ function readAitAdConfig(path: string | undefined): {
36
+ readonly adGroupIds: Readonly<Record<string, string>>;
37
+ readonly adPlacementTypes: Readonly<Record<string, 'rewarded' | 'interstitial'>>;
38
+ } {
39
+ if (path === undefined || path.trim().length === 0) {
40
+ return { adGroupIds: {}, adPlacementTypes: {} };
41
+ }
42
+
43
+ let parsed: unknown;
44
+ try {
45
+ parsed = JSON.parse(readFileSync(path, 'utf8')) as unknown;
46
+ } catch (error) {
47
+ throw new Error(`AIT ad placements file is unreadable or invalid JSON: ${path}`, {
48
+ cause: error,
49
+ });
50
+ }
51
+
52
+ return extractAitAdBridgeConfig(parsed, path);
53
+ }