@kurot/cli 3.8.0 → 3.8.1

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 (37) hide show
  1. package/CHANGELOG.md +33 -2
  2. package/README.md +11 -11
  3. package/dist/core/config.d.ts +3 -2
  4. package/dist/core/config.d.ts.map +1 -1
  5. package/dist/core/config.js.map +1 -1
  6. package/dist/core/plugins/index.d.ts +1 -1
  7. package/dist/core/plugins/index.d.ts.map +1 -1
  8. package/dist/core/plugins/index.js +3 -3
  9. package/dist/core/plugins/index.js.map +1 -1
  10. package/dist/core/plugins/resource-version-css.d.ts +7 -0
  11. package/dist/core/plugins/resource-version-css.d.ts.map +1 -0
  12. package/dist/core/plugins/resource-version-css.js +41 -0
  13. package/dist/core/plugins/resource-version-css.js.map +1 -0
  14. package/dist/core/plugins/resource-version-html.d.ts +7 -0
  15. package/dist/core/plugins/resource-version-html.d.ts.map +1 -0
  16. package/dist/core/plugins/resource-version-html.js +66 -0
  17. package/dist/core/plugins/resource-version-html.js.map +1 -0
  18. package/dist/core/plugins/version-resources.d.ts +7 -0
  19. package/dist/core/plugins/version-resources.d.ts.map +1 -0
  20. package/dist/core/plugins/version-resources.js +89 -0
  21. package/dist/core/plugins/version-resources.js.map +1 -0
  22. package/docs/ai-context.md +10 -7
  23. package/docs/architecture.md +8 -7
  24. package/docs/default-ui-skins.md +4 -5
  25. package/docs/game-template.md +7 -0
  26. package/docs/release-assets.md +64 -55
  27. package/package.json +3 -2
  28. package/templates/empty/README.md +9 -0
  29. package/templates/empty/kurot.config.ts +1 -1
  30. package/templates/game/README.md +9 -0
  31. package/templates/game/kurot.config.ts +1 -1
  32. package/templates/game/src/Main.ts +2 -2
  33. package/templates/game/src/StyleManager.ts +3 -2
  34. package/dist/core/plugins/version-assets.d.ts +0 -7
  35. package/dist/core/plugins/version-assets.d.ts.map +0 -1
  36. package/dist/core/plugins/version-assets.js +0 -108
  37. package/dist/core/plugins/version-assets.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,10 +7,37 @@ and CLI command/configuration APIs follow [Semantic Versioning](https://semver.o
7
7
  The early KUI XML contract follows the pre-1.0 `ui-document` kernel; authored
8
8
  format changes are documented explicitly in each release.
9
9
 
10
- ## 3.8.0 — 2026-10-30
10
+ ## 3.8.1 — 2026-10-30
11
11
 
12
12
  Prepared for publication; not yet published.
13
13
 
14
+ ### Changed
15
+
16
+ - Replace output.versionedAssets directory relocation with release build-number
17
+ queries. Preserve the original JS content hashes, import map, manifest and
18
+ output paths; remove the complete-build digest, assets/<hash>/ and HTML base.
19
+ Replace the unused packaging approach before project deployment adoption.
20
+ - Stamp every HTML entry with kurot-resource-version metadata. Version static
21
+ HTML/CSS assets using parsed URL references, including page-shell files outside
22
+ resource/. Keep navigation, script contents, remote URLs and generated js/ paths.
23
+ Reject ambiguous authored metadata/base or missing head before rewriting pages.
24
+ - Enable the option explicitly in new game/empty starters and resolve the game
25
+ starter's native style/font/Theme requests through the new Core helper. Existing
26
+ configurations retain the false default; Core >= 2.7.0 within 2.x is required
27
+ for the resource protocol and the game starter's native helper calls.
28
+ - Add postcss-value-parser for CSS references, plus release-output and startup
29
+ font regressions. Document CDN query keys and the limits of cache busting.
30
+
31
+ ### Verification
32
+
33
+ - Build and all 144 tests pass. Both starters pass strict development/release,
34
+ full declaration checks and browser startup; API documentation checks pass.
35
+
36
+ ## 3.8.0 — 2026-10-30
37
+
38
+ Published; exact version, npm latest and downloaded archive SHA-512 integrity
39
+ verified on 2026-10-30.
40
+
14
41
  ### Added
15
42
 
16
43
  - Watch root ESM TS/JS configuration stage defaults in dev, including atomic
@@ -50,7 +77,11 @@ Prepared for publication; not yet published.
50
77
  - The 243-file local package includes the compiled configuration watcher,
51
78
  diagnostics, watching guide and both canvas-only starters with their Core
52
79
  2.6.0 requirement. ui-document remains ^0.13.0; no Core runtime dependency
53
- is added. npm registry checks confirm 3.8.0 is not published.
80
+ is added.
81
+ - The published archive contains 243 files, all matching the tested preparation
82
+ checkout byte for byte. npm latest is CLI 3.8.0 and its required Core startup
83
+ behavior is available in published Core 2.6.0. Repository publication-status
84
+ updates follow verification; the npm archive retains preparation-time docs.
54
85
 
55
86
  ## 3.7.0 — 2026-10-27
56
87
 
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @kurot/cli
2
2
 
3
3
  Build-time KUI XML → ESM Skin compilation, game scaffolding and development
4
- resource watching. Package version: **3.8.0** (prepared; publication pending).
4
+ resource watching. Package version: **3.8.1** (prepared for publication).
5
5
  Requires Node.js >= 20 and
6
6
  ui-document **^0.13.0**; games supply their own Core/UI runtime packages.
7
7
 
@@ -12,11 +12,11 @@ the separate CLI 1.3.x line. KUI configuration and resource files are project-ow
12
12
  ## Usage
13
13
 
14
14
  The CLI does not require a global install. Install it as a project development
15
- dependency. Both new scaffolds need Core ^2.6.0 for canvas stage-attribute
16
- startup. Existing projects keep their own installed SDKs and resources.
15
+ dependency. New scaffolds use Core ^2.7.0 for release resource versioning and canvas
16
+ stage-attribute startup. Existing projects keep their own installed SDKs and resources.
17
17
 
18
18
  ```bash
19
- npx @kurot/cli@3.8.0 create my-game
19
+ npx @kurot/cli@3.8.1 create my-game
20
20
  cd my-game
21
21
  pnpm install
22
22
  pnpm dev
@@ -24,7 +24,7 @@ pnpm dev
24
24
 
25
25
  Scaffolded projects expose `build`, `dev`, and `clean` scripts. For an
26
26
  Editor-managed KUI XML project, install the package with
27
- `pnpm add -D @kurot/cli@^3.8.0`. Existing EXML projects should keep their current
27
+ `pnpm add -D @kurot/cli@^3.8.1`. Existing EXML projects should keep their current
28
28
  1.3.x dependency.
29
29
 
30
30
  ## Commands
@@ -60,12 +60,12 @@ Development output is written to `bin-debug/`. Release output is written to
60
60
  project namespace, theme, and application code are separate ESM chunks joined
61
61
  by the generated HTML import map.
62
62
 
63
- Set `output: { dir: 'bin-debug', versionedAssets: true }` to place release
64
- resources and scripts in `assets/<content-hash>/`. A generated HTML base URL
65
- versions relative requests, including atlas pages, fonts and startup images.
66
- Identical builds reuse the same path; development output is unchanged.
67
- See [release assets and deployment](docs/release-assets.md) for theme loading,
68
- cache headers and upload order. This option requires CLI >= 3.7.0 within 3.x.
63
+ CLI >= 3.8.1 within 3.x with Core >= 2.7.0 within 2.x uses
64
+ `output: { dir: 'bin-debug', versionedAssets: true }` to append the release build
65
+ number to local resources as `?v=<timestamp>`. JS keeps its existing content-hashed
66
+ filename and `js/` path. New starters enable the option explicitly; development
67
+ output is unchanged. See [release resources and deployment](docs/release-assets.md)
68
+ for matching Core support, native font/fetch/Theme calls and cache settings.
69
69
 
70
70
  Asset copying omits empty runtime directory trees. With KUI enabled, authored
71
71
  `.kui.xml` files are compiled into the theme chunk and excluded from `resource/`;
@@ -68,8 +68,9 @@ export interface OutputConfig {
68
68
  */
69
69
  readonly dir: string;
70
70
  /**
71
- * Place release assets in `assets/<content-hash>/` and set the entry page's
72
- * base URL to that directory. Defaults to false; ignored in development.
71
+ * Append the release build number as v to resource requests and static page
72
+ * assets. Generated JS keeps its content hash and path. Ignored in development.
73
+ * Defaults to false.
73
74
  */
74
75
  readonly versionedAssets?: boolean;
75
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC;AAElC,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACzB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAChC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IAC1B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC;CACxB;AA4BD;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CA6DzG"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC;AAElC,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACzB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAChC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IAC1B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC;CACxB;AA4BD;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CA6DzG"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ export { compileSource } from './compile-source.js';
8
8
  export { generateHtml } from './generate-html.js';
9
9
  export { writeManifest } from './manifest.js';
10
10
  export { copyAssets } from './copy-assets.js';
11
- export { versionAssets } from './version-assets.js';
11
+ export { versionResources } from './version-resources.js';
12
12
  /**
13
13
  * The standard build sequence.
14
14
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAYlD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,WAAW,EAAE,CAa9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAYlD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,WAAW,EAAE,CAa9C"}
@@ -7,7 +7,7 @@ import { compileSource } from './compile-source.js';
7
7
  import { generateHtml } from './generate-html.js';
8
8
  import { writeManifest } from './manifest.js';
9
9
  import { copyAssets } from './copy-assets.js';
10
- import { versionAssets } from './version-assets.js';
10
+ import { versionResources } from './version-resources.js';
11
11
  export { cleanOutput } from './clean-output.js';
12
12
  export { compileKUI } from './compile-kui.js';
13
13
  export { compileEngine } from './compile-engine.js';
@@ -17,7 +17,7 @@ export { compileSource } from './compile-source.js';
17
17
  export { generateHtml } from './generate-html.js';
18
18
  export { writeManifest } from './manifest.js';
19
19
  export { copyAssets } from './copy-assets.js';
20
- export { versionAssets } from './version-assets.js';
20
+ export { versionResources } from './version-resources.js';
21
21
  /**
22
22
  * The standard build sequence.
23
23
  *
@@ -39,7 +39,7 @@ export function defaultPlugins() {
39
39
  generateHtml(),
40
40
  writeManifest(),
41
41
  copyAssets(),
42
- versionAssets(),
42
+ versionResources(),
43
43
  ];
44
44
  }
45
45
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/plugins/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc;IAC7B,OAAO;QACN,WAAW,EAAE;QACb,UAAU,EAAE;QACZ,aAAa,EAAE;QACf,uBAAuB,EAAE;QACzB,qBAAqB,EAAE;QACvB,aAAa,EAAE;QACf,YAAY,EAAE;QACd,aAAa,EAAE;QACf,UAAU,EAAE;QACZ,aAAa,EAAE;KACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/plugins/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc;IAC7B,OAAO;QACN,WAAW,EAAE;QACb,UAAU,EAAE;QACZ,aAAa,EAAE;QACf,uBAAuB,EAAE;QACzB,qBAAqB,EAAE;QACvB,aAAa,EAAE;QACf,YAAY,EAAE;QACd,aAAa,EAAE;QACf,UAAU,EAAE;QACZ,gBAAgB,EAAE;KAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type ResourceUrlVersioner = (source: string, baseFile: string) => string;
2
+ /**
3
+ * Version CSS url() and string @import references, preserving comments and
4
+ * ordinary strings. CSS escaping is decoded for lookup and retained on output.
5
+ */
6
+ export declare function versionCssResources(css: string, file: string, versionUrl: ResourceUrlVersioner): string;
7
+ //# sourceMappingURL=resource-version-css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-version-css.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-css.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,GAAG,MAAM,CAmCvG"}
@@ -0,0 +1,41 @@
1
+ import valueParser from 'postcss-value-parser';
2
+ /**
3
+ * Version CSS url() and string @import references, preserving comments and
4
+ * ordinary strings. CSS escaping is decoded for lookup and retained on output.
5
+ */
6
+ export function versionCssResources(css, file, versionUrl) {
7
+ const parsed = valueParser(css);
8
+ parsed.walk((node, index, nodes) => {
9
+ if (node.type === 'function' && node.value.toLowerCase() === 'url') {
10
+ const value = node.nodes.find(child => child.type !== 'space' && child.type !== 'comment');
11
+ if (value?.type === 'string' || value?.type === 'word') {
12
+ update(value);
13
+ }
14
+ return false;
15
+ }
16
+ if (node.type === 'word' && node.value.toLowerCase() === '@import') {
17
+ const next = nodes.slice(index + 1).find(child => child.type !== 'space' && child.type !== 'comment');
18
+ if (next?.type === 'string') {
19
+ update(next);
20
+ }
21
+ }
22
+ });
23
+ return parsed.toString();
24
+ function update(node) {
25
+ const decoded = node.value.replace(/\\(?:([a-f0-9]{1,6})\s?|([\s\S]))/gi, (_match, hex, character) => {
26
+ if (hex) {
27
+ const point = Number.parseInt(hex, 16);
28
+ return point > 0 && point <= 0x10ffff ? String.fromCodePoint(point) : '\uFFFD';
29
+ }
30
+ return character && !/[\r\n\f]/.test(character) ? character : '';
31
+ });
32
+ const next = versionUrl(decoded, file);
33
+ if (next === decoded) {
34
+ return;
35
+ }
36
+ node.value = node.type === 'word'
37
+ ? next.replace(/[\\\s"'()]/g, character => '\\' + character)
38
+ : next.replace(/\\/g, '\\\\').split(node.quote).join('\\' + node.quote);
39
+ }
40
+ }
41
+ //# sourceMappingURL=resource-version-css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-version-css.js","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-css.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAI/C;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,IAAY,EAAE,UAAgC;IAC9F,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;YACpE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YAC3F,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;gBACxD,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,SAAS,EAAE,CAAC;YACpE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YACtG,IAAI,IAAI,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,CAAC;YACd,CAAC;QACF,CAAC;IACF,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;IAEzB,SAAS,MAAM,CAAC,IAAmD;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,MAAc,EAAE,GAAuB,EAAE,SAA6B,EAAE,EAAE;YACpJ,IAAI,GAAG,EAAE,CAAC;gBACT,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACvC,OAAO,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAChF,CAAC;YACD,OAAO,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM;YAChC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC;YAC5D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1E,CAAC;AACF,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ResourceUrlVersioner } from './resource-version-css.js';
2
+ /**
3
+ * Write build metadata and static resource versions without serializing scripts
4
+ * or moving files. Navigation destinations and generated JS URLs remain intact.
5
+ */
6
+ export declare function versionHtmlResources(html: string, file: string, version: string, versionUrl: ResourceUrlVersioner): string;
7
+ //# sourceMappingURL=resource-version-html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-version-html.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-html.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAQtE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,GAAG,MAAM,CAsD1H"}
@@ -0,0 +1,66 @@
1
+ import { defaultTreeAdapter, parse } from 'parse5';
2
+ import { BuildError } from '../errors.js';
3
+ import { versionCssResources } from './resource-version-css.js';
4
+ /**
5
+ * Write build metadata and static resource versions without serializing scripts
6
+ * or moving files. Navigation destinations and generated JS URLs remain intact.
7
+ */
8
+ export function versionHtmlResources(html, file, version, versionUrl) {
9
+ const document = parse(html, { sourceCodeLocationInfo: true });
10
+ const pending = [document];
11
+ const edits = [];
12
+ let headEnd;
13
+ while (pending.length > 0) {
14
+ const parent = pending.pop();
15
+ for (const element of parent.childNodes.filter(defaultTreeAdapter.isElementNode)) {
16
+ pending.push(element);
17
+ if (element.tagName === 'base') {
18
+ throw new BuildError('output.versionedAssets requires document-relative resources; remove the authored base element.');
19
+ }
20
+ if (element.tagName === 'head') {
21
+ headEnd = element.sourceCodeLocation?.startTag?.endOffset;
22
+ }
23
+ if (element.tagName === 'meta' && element.attrs.some(attr => attr.name === 'name' && attr.value === 'kurot-resource-version')) {
24
+ throw new BuildError('output.versionedAssets owns the kurot-resource-version metadata; remove the authored value.');
25
+ }
26
+ for (const attr of element.attrs) {
27
+ const attributeName = attr.prefix ? `${attr.prefix}:${attr.name}` : attr.name;
28
+ const location = element.sourceCodeLocation?.attrs?.[attributeName];
29
+ if (!location) {
30
+ continue;
31
+ }
32
+ const asset = attr.name === 'src' || attr.name === 'poster' ||
33
+ (attr.name === 'href' && ['link', 'image', 'use'].includes(element.tagName)) ||
34
+ (attr.name === 'data' && element.tagName === 'object');
35
+ const next = attr.name === 'style'
36
+ ? versionCssResources(attr.value, file, versionUrl)
37
+ : asset ? versionUrl(attr.value, file) : attr.value;
38
+ if (next !== attr.value) {
39
+ edits.push({ start: location.startOffset, end: location.endOffset, text: `${attributeName}="${escapeAttribute(next)}"` });
40
+ }
41
+ }
42
+ if (element.tagName === 'style') {
43
+ for (const text of element.childNodes.filter(defaultTreeAdapter.isTextNode)) {
44
+ const location = text.sourceCodeLocation;
45
+ const next = versionCssResources(text.value, file, versionUrl);
46
+ if (location && next !== text.value) {
47
+ edits.push({ start: location.startOffset, end: location.endOffset, text: next });
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ if (headEnd === undefined) {
54
+ throw new BuildError('output.versionedAssets requires an explicit HTML head element.');
55
+ }
56
+ edits.push({ start: headEnd, end: headEnd, text: `\n\t<meta name="kurot-resource-version" content="${escapeAttribute(version)}">` });
57
+ let result = html;
58
+ for (const edit of edits.sort((left, right) => right.start - left.start)) {
59
+ result = result.slice(0, edit.start) + edit.text + result.slice(edit.end);
60
+ }
61
+ return result;
62
+ }
63
+ function escapeAttribute(value) {
64
+ return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;');
65
+ }
66
+ //# sourceMappingURL=resource-version-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-version-html.js","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { BuildPlugin } from '../pipeline.js';
2
+ /**
3
+ * Stamp resource requests with the release build number. Generated JavaScript
4
+ * keeps its content-hashed names and original paths; no document base is changed.
5
+ */
6
+ export declare function versionResources(): BuildPlugin;
7
+ //# sourceMappingURL=version-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-resources.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/version-resources.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKhE;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CA2B9C"}
@@ -0,0 +1,89 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ import { BuildError } from '../errors.js';
4
+ import { versionCssResources } from './resource-version-css.js';
5
+ import { versionHtmlResources } from './resource-version-html.js';
6
+ /**
7
+ * Stamp resource requests with the release build number. Generated JavaScript
8
+ * keeps its content-hashed names and original paths; no document base is changed.
9
+ */
10
+ export function versionResources() {
11
+ return {
12
+ name: 'version release resources',
13
+ async apply(ctx) {
14
+ if (ctx.project.mode !== 'release' || !ctx.project.config.output.versionedAssets) {
15
+ return;
16
+ }
17
+ const files = await listFiles(ctx.project.outputDir);
18
+ const version = path.basename(ctx.project.outputDir);
19
+ const versionUrl = createVersioner(new Set(files), version);
20
+ const updates = [];
21
+ for (const file of files) {
22
+ if (!/\.(?:html|css)$/i.test(file)) {
23
+ continue;
24
+ }
25
+ const source = await fs.readFile(path.join(ctx.project.outputDir, file), 'utf8');
26
+ const contents = /\.html$/i.test(file)
27
+ ? versionHtmlResources(source, file, version, versionUrl)
28
+ : versionCssResources(source, file, versionUrl);
29
+ updates.push({ file, contents });
30
+ }
31
+ // Validate every page before replacing any generated HTML/CSS.
32
+ for (const update of updates) {
33
+ await fs.writeFile(path.join(ctx.project.outputDir, update.file), update.contents);
34
+ }
35
+ },
36
+ };
37
+ }
38
+ function createVersioner(files, version) {
39
+ return (source, baseFile) => {
40
+ if (!source || source.startsWith('#')) {
41
+ return source;
42
+ }
43
+ let target;
44
+ try {
45
+ target = new URL(source, `https://kurot.invalid/${baseFile}`);
46
+ }
47
+ catch {
48
+ return source;
49
+ }
50
+ if (target.origin !== 'https://kurot.invalid') {
51
+ return source;
52
+ }
53
+ let file;
54
+ try {
55
+ file = decodeURIComponent(target.pathname).slice(1);
56
+ }
57
+ catch {
58
+ return source;
59
+ }
60
+ if (!files.has(file) || file.startsWith('js/') || /\.html?$/i.test(file)) {
61
+ return source;
62
+ }
63
+ const hash = source.indexOf('#');
64
+ const fragment = hash < 0 ? '' : source.slice(hash);
65
+ const reference = hash < 0 ? source : source.slice(0, hash);
66
+ const query = reference.indexOf('?');
67
+ const pathname = query < 0 ? reference : reference.slice(0, query);
68
+ const parameters = new URLSearchParams(query < 0 ? '' : reference.slice(query + 1));
69
+ parameters.set('v', version);
70
+ return `${pathname}?${parameters}${fragment}`;
71
+ };
72
+ }
73
+ async function listFiles(root, directory = '') {
74
+ const files = [];
75
+ for (const entry of await fs.readdir(path.join(root, directory), { withFileTypes: true })) {
76
+ const relative = path.posix.join(directory, entry.name);
77
+ if (entry.isDirectory()) {
78
+ files.push(...await listFiles(root, relative));
79
+ }
80
+ else if (entry.isFile()) {
81
+ files.push(relative);
82
+ }
83
+ else {
84
+ throw new BuildError(`Versioned resources require regular output files: ${relative}`);
85
+ }
86
+ }
87
+ return files;
88
+ }
89
+ //# sourceMappingURL=version-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-resources.js","sourceRoot":"","sources":["../../../src/core/plugins/version-resources.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  # @kurot/cli — AI context map
2
2
 
3
- `@kurot/cli@3.8.0` (prepared; publication pending) is build-time tooling on Node.js >= 20, with ordinary
3
+ `@kurot/cli@3.8.1` (prepared for publication) is build-time tooling on Node.js >= 20, with ordinary
4
4
  ui-document dependency **^0.13.0**. Projects supply their own Core/UI runtime.
5
5
  Read [architecture](architecture.md) for the plugin pipeline; the source and
6
6
  configuration exports establish current behavior.
@@ -150,12 +150,15 @@ manual prefix cannot conflict with `ui.components.namespace`.
150
150
  Do not reorder namespace or source compilation without reviewing externalization
151
151
  in `namespace-external-plugin.ts`.
152
152
 
153
- Release versioning runs last so the digest covers generated themes, scripts,
154
- resource bytes and template assets. It keeps index.html/manifest.json at the
155
- output root and moves all other files under assets/<hash>/. The HTML base URL
156
- versions document-relative requests; callers that explicitly resolve URLs must
157
- use document.baseURI. Existing UI Theme must receive an absolute config URL.
158
- See [release assets](release-assets.md). This option requires CLI >= 3.7.0 within 3.x.
153
+ CLI >= 3.8.1 within 3.x with Core >= 2.7.0 within 2.x supports resource
154
+ queries. `version-resources.ts` runs last and
155
+ stamps each HTML page with the release directory's timestamp. HTML/CSS local
156
+ assets receive a `v` query; Core transports version local resource/ requests.
157
+ Generated JS, import maps, manifest paths and output directories stay unchanged.
158
+ `resource-version-html.ts` preserves script bytes and owns metadata validation;
159
+ `resource-version-css.ts` owns CSS URL parsing. Native fetch/FontFace/Theme calls
160
+ use Core's resolveResourceUrl; new starters enable the flag explicitly. See
161
+ [release resources](release-assets.md) for the protocol and deployment limits.
159
162
 
160
163
  Since CLI 3.8.0, root ESM config stage changes regenerate HTML in `kurot dev` without
161
164
  restarting dev; `core/config-watcher.ts` owns this path. See
@@ -40,7 +40,7 @@ factory variables, property assignments, semantic layout children, and state
40
40
  property overrides. Document contracts, reusable instances, data bindings, and
41
41
  actions remain `UIDocument` concepts.
42
42
 
43
- CLI 3.8.0 consumes ui-document ^0.13.0, retaining Label text-fitting metadata. The
43
+ CLI 3.8.1 consumes ui-document ^0.13.0, retaining Label text-fitting metadata. The
44
44
  compiler emits `textFit`, `minFontSize`, base font sizes and state overrides;
45
45
  native UI owns measurement and derives drawing sizes after layout validation.
46
46
  See [Label compilation](label-text-layout.md). The application supplies UI
@@ -72,12 +72,13 @@ Development builds preserve application source module structure under
72
72
  `manifest.json`. Static resources retain stable paths because application code
73
73
  addresses them by key or URL.
74
74
 
75
- With `output.versionedAssets: true`, the final stage hashes the complete output
76
- and moves runtime files into `assets/<hash>/`. The entry HTML receives a base URL;
77
- the root release manifest and BuildContext script paths receive the same prefix.
78
- Relative references inside resources and ESM modules remain intact. This is one
79
- version for the complete build, rather than independent hashes per resource.
80
- See [release deployment](release-assets.md) for URL and hosting requirements.
75
+ With CLI >= 3.8.1 within 3.x and Core >= 2.7.0 within 2.x,
76
+ `output.versionedAssets: true` writes the release directory timestamp to HTML
77
+ metadata and appends it as `v` to static HTML/CSS assets. Core transports use that
78
+ metadata for local resource/ files, including secondary atlas/font pages. Native
79
+ fetch/FontFace/Theme callers use Core's resolveResourceUrl. Generated JS hashes,
80
+ manifest paths and BuildContext outputs remain unchanged. No files move and no
81
+ HTML base is inserted. See [release resources](release-assets.md).
81
82
 
82
83
  Asset copying creates directories only when an accepted runtime file needs them.
83
84
  KUI source files and source theme JSON are excluded when UI compilation is enabled,
@@ -81,19 +81,18 @@ and wrap the node with Group/Image/Scroller for its surface and viewport.
81
81
  `src/DefaultUI.ts` only connects data and events. The example installs its own
82
82
  project font loader and document dependency; other projects are unchanged.
83
83
 
84
- Use the checkout CLI with the example's installed SDKs. From the repository root:
84
+ Use the example's installed registry CLI and SDKs. From the repository root:
85
85
 
86
86
  ```sh
87
- pnpm --dir packages/cli build
88
- cd examples/game
89
- node ../../packages/cli/dist/index.js dev
87
+ pnpm --dir examples/game install --frozen-lockfile
88
+ pnpm --dir examples/game dev
90
89
  ```
91
90
 
92
91
  Open the server URL with `?ui=1`; the ordinary scene remains available without
93
92
  that parameter. Try the inputs, switches, ComboBox, tabs, sliders, panel close
94
93
  button and draggable List. The gallery uses the example's installed Core/UI
95
94
  with compiled KUI XML, without modifying dependencies or locks. In that example
96
- directory, the same CLI accepts `build` and `build --release` for one-shot builds.
95
+ directory, `pnpm build --strict` and `pnpm release --strict` run one-shot builds.
97
96
  The private asset tool's isolated source preview remains an optional maintenance
98
97
  tool for testing checkout engine changes; it is not required by the installed Core.
99
98
 
@@ -41,6 +41,13 @@ remain available for intentional overrides. In dev, save stage settings, wait
41
41
  for the configuration update and refresh the browser with CLI >= 3.8.0 within
42
42
  3.x; no dev restart is needed.
43
43
 
44
+ ## Release resources
45
+
46
+ Both starters enable output.versionedAssets. Resource queries use the release
47
+ build number with Core >= 2.7.0 within 2.x and CLI >= 3.8.1 within 3.x. The game
48
+ starter resolves native style/font and Theme requests through resolveResourceUrl
49
+ before Player creation. See [release resources](release-assets.md).
50
+
44
51
  ## HTML brand splash
45
52
 
46
53
  The game template's `web/index.html` presents `web/logo.png` beneath a small
@@ -1,76 +1,85 @@
1
- # Versioned release assets
1
+ # Release resource versions
2
2
 
3
- Enable content-addressed release packaging in `kurot.config.ts`:
3
+ The query-based protocol requires **CLI >= 3.8.1 within 3.x and Core >= 2.7.0
4
+ within 2.x**. These source versions are prepared for publication. It replaces
5
+ the earlier whole-build directory packaging.
6
+
7
+ Enable it in `kurot.config.ts`:
4
8
 
5
9
  ```ts
6
10
  export default {
7
- output: { dir: 'bin-debug', versionedAssets: true },
8
- // Keep the project's other settings.
11
+ output: { dir: 'bin-debug', versionedAssets: true },
12
+ // Keep the project's other settings.
9
13
  };
10
14
  ```
11
15
 
12
- The option requires CLI >= 3.7.0 within 3.x. It defaults to false and is ignored
13
- by development/watch builds.
14
- An index query string does not propagate to requests for resources.
16
+ The configuration field defaults to false for existing configurations. New game
17
+ and empty starters explicitly enable it. Development/watch builds are unchanged.
15
18
 
16
- ## Output and URLs
19
+ ## Output and build number
17
20
 
18
21
  ```text
19
- bin-release/web/<timestamp>/
22
+ bin-release/web/261030123456/
20
23
  ├── index.html
21
24
  ├── manifest.json
22
- └── assets/<hash>/
23
- ├── js/
24
- ├── resource/
25
- └── <files copied beside the HTML template>
25
+ ├── js/main.min_<content-hash>.js
26
+ ├── resource/
27
+ └── <files copied beside the HTML template>
26
28
  ```
27
29
 
28
- The hash is the first 32 hexadecimal characters of SHA-256 over sorted output
29
- paths, file sizes and bytes, including generated HTML, theme JSON and scripts.
30
- Any changed file changes the complete build's version. Identical builds retain
31
- their URL; unchanged individual files also get new URLs when another file changes.
32
- This trades granular cache reuse for one consistent release across all loaders.
33
-
34
- The CLI inserts `<base href="./assets/<hash>/">` first inside `<head>`. A request
35
- for `resource/assets/atlas.png` then resolves under the version directory, even
36
- when the entry is `/game/index.html?launch=...`. Atlas `file` references, bitmap
37
- font pages, stylesheet fonts, relative imports and direct browser requests use
38
- that directory without rewriting authored resources or keys. The release manifest
39
- stays at the root with prefixed script paths. Source maps move with their scripts.
40
-
41
- Custom templates must have an explicit `<head>` and no `<base>` element. The
42
- CLI inserts the base at the parsed start tag's source location without
43
- reserializing the template. Quoted attributes and script/style text are preserved.
44
- The build rejects symbolic links and other nonregular output files. Relative URLs
45
- must refer to files inside the build; root-relative URLs, remote URLs, and URLs
46
- explicitly based on location.href remain outside this mechanism. Applications
47
- that construct URLs should use document.baseURI for build assets. Relative links
48
- and forms also inherit the base; use explicit destinations for application navigation.
49
- If hosting has a CSP base-uri directive, it must allow this same-origin base.
50
-
51
- ## Theme loading with existing UI
52
-
53
- UI runtimes that resolve a relative Theme config against location.href need an
54
- absolute config URL. The game starter uses:
30
+ The existing release directory timestamp (`YYMMDDHHmmss`) is the resource build
31
+ number. The CLI inserts `<meta name="kurot-resource-version" content="261030123456">`
32
+ into each generated HTML page. It creates no asset hash directory or HTML base.
33
+ The release manifest, import map, generated JS filenames, source maps and JS
34
+ imports retain their original paths. Identical JS can retain its filename hash
35
+ across releases even when the resource build number changes.
36
+
37
+ Core reads the metadata before Player creation. Its GET HttpRequest, ImageLoader,
38
+ Sound, Video and sound-resource transports append `v` to same-origin files below
39
+ the page's `resource/` directory. Resource manifests, atlas and bitmap-font pages,
40
+ and adapters using these transports receive the same version. Authored resource
41
+ keys and descriptors remain unchanged. Existing query fields/fragments survive;
42
+ an existing `v` is replaced once.
43
+
44
+ Native browser callers must opt in through the public Core helper:
55
45
 
56
46
  ```ts
57
- const theme = new Theme(new URL('resource/default.thm.json', document.baseURI).href);
47
+ import { resolveResourceUrl } from '@kurot/core';
48
+
49
+ const response = await fetch(resolveResourceUrl('resource/config/style.json'));
50
+ const font = new FontFace('ProjectFont', `url("${resolveResourceUrl('resource/font.ttf')}")`);
51
+ const theme = new Theme(resolveResourceUrl(new URL('resource/default.thm.json', document.baseURI)));
58
52
  ```
59
53
 
60
- Use the same pattern in existing projects. This keeps the theme's `skinsJs`
61
- import inside the version directory without requiring a UI runtime update.
54
+ The game starter includes this wiring for startup fonts/styles and Theme. Theme
55
+ config is versioned, while its generated `skinsJs` continues using the JS filename
56
+ hash. Core does not replace global fetch or XMLHttpRequest. API requests outside
57
+ `resource/`, POST requests, remote/CDN URLs, data/blob URLs and JS modules retain
58
+ their original URLs. Remote or signed resources need their own version policy.
59
+
60
+ ## Static HTML and CSS
61
+
62
+ The CLI also versions existing local files referenced by HTML `src`, `poster`,
63
+ link/SVG `href`, object `data`, inline styles, style blocks, CSS `url()` and string
64
+ `@import`. This includes page logos, fonts, stylesheets and startup configuration
65
+ scripts outside `js/`. It preserves scripts and ordinary strings. Navigation
66
+ links, form destinations, HTML pages and generated files under `js/` are unchanged.
67
+ Native URLs constructed inside scripts must use the helper or read the generated
68
+ metadata in a standalone page without Core. `srcset` rewriting is not provided.
62
69
 
63
- ## Deployment
70
+ Custom HTML pages need an explicit `<head>` and no authored `<base>` or
71
+ `kurot-resource-version` metadata. The build validates every page before rewriting
72
+ HTML/CSS. Symbolic links and other nonregular output files are rejected.
73
+ Use document-relative paths to support deployment under a subdirectory.
64
74
 
65
- Upload the complete generated directory, including `assets/<hash>/`. Upload new
66
- asset directories first, then replace root manifest.json and index.html. Keep
67
- previous version directories available while older sessions may request assets;
68
- avoid deploy commands that delete those directories immediately. Publish the
69
- entry at a directory URL ending in `/` or at its actual `index.html` URL.
75
+ ## Deployment and caching
70
76
 
71
- Serve index.html with revalidation, for example `Cache-Control: no-cache`.
72
- Serve `assets/<hash>/**` with `Cache-Control: public, max-age=31536000, immutable`.
73
- If a launcher reads root manifest.json, give it revalidation too. These are server
74
- settings; the CLI writes static files and cannot set response headers. Never
75
- overwrite files inside an already published hash directory. Rollback replaces
76
- the root entry files with those of the previous complete release.
77
+ Deploy the entire generated release directory. Revalidate entry HTML and
78
+ manifest.json (for example `Cache-Control: no-cache`). Configure CDN/cache keys to
79
+ include `v`; otherwise different builds can still share stale resource responses.
80
+ Generated content-hashed JS can retain long-lived immutable caching. Resource
81
+ URLs may be cached by their version query, but replacing a same-path file does
82
+ not retain older bytes for an uncached old URL. This is cache busting, not release
83
+ snapshot storage. Use separate deployment directories if old sessions must lazily
84
+ load their exact previous files after deployment. Server headers and atomic
85
+ publishing remain deployment responsibilities.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurot/cli",
3
- "version": "3.8.0",
3
+ "version": "3.8.1",
4
4
  "description": "Kurot CLI - build tool for Kurot Editor KUI XML workflows",
5
5
  "author": "Kelvin <kyia.x52@gmail.com>",
6
6
  "license": "MIT",
@@ -31,7 +31,8 @@
31
31
  "@kurot/ui-document": "^0.13.0",
32
32
  "commander": "^13.0.0",
33
33
  "esbuild": "^0.25.0",
34
- "parse5": "^7.3.0"
34
+ "parse5": "^7.3.0",
35
+ "postcss-value-parser": "^4.2.0"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@types/node": "^22.0.0",
@@ -61,3 +61,12 @@ source if needed. Repository `src/` paths are not guaranteed inside npm packages
61
61
 
62
62
  The project starts with Core only. Add further SDKs explicitly when gameplay
63
63
  requires them; keep dependency adoption separate from ordinary feature work.
64
+
65
+ ## Release resource cache
66
+
67
+ This starter explicitly enables output.versionedAssets. Core >= 2.7.0 within
68
+ 2.x and CLI >= 3.8.1 within 3.x version local resources with the release
69
+ build number; generated JS retains its filename hash. Development URLs are
70
+ unchanged. For native fetch/FontFace or Theme loading, use Core's
71
+ resolveResourceUrl. CDN cache keys must include v. See the installed CLI
72
+ [release guide](node_modules/@kurot/cli/docs/release-assets.md).
@@ -1,7 +1,7 @@
1
1
  export default {
2
2
  target: 'html5',
3
3
  entry: 'src/Main.ts',
4
- output: { dir: 'bin-debug' },
4
+ output: { dir: 'bin-debug', versionedAssets: true },
5
5
  html: { template: 'template/web/index.html' },
6
6
  stage: {
7
7
  width: 640,
@@ -91,3 +91,12 @@ The 2× default atlas needs Core >= 2.5.0 within 2.x; also satisfy the installed
91
91
  UI's Core peer. ui-document supports this starter's stylesheet parsing.
92
92
  CLI-compiled skins run through UI; add ui-runtime only for its materialization
93
93
  features. Existing project dependencies remain project-owned.
94
+
95
+ ## Release resource cache
96
+
97
+ This starter explicitly enables output.versionedAssets. Core >= 2.7.0 within
98
+ 2.x and CLI >= 3.8.1 within 3.x version local resources with the release
99
+ build number; generated JS retains its filename hash. Development URLs are
100
+ unchanged. For native fetch/FontFace or Theme loading, use Core's
101
+ resolveResourceUrl. CDN cache keys must include v. See the installed CLI
102
+ [release guide](node_modules/@kurot/cli/docs/release-assets.md).
@@ -1,7 +1,7 @@
1
1
  export default {
2
2
  target: 'html5',
3
3
  entry: 'src/Main.ts',
4
- output: { dir: 'bin-debug' },
4
+ output: { dir: 'bin-debug', versionedAssets: true },
5
5
  html: { template: 'template/web/index.html' },
6
6
  stage: {
7
7
  width: 640,
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Lifecycle: constructor → ADDED_TO_STAGE → $onAddToStage → runGame → load → createGameScene → startAnimation
7
7
  */
8
- import { createPlayer, Event, resource, TextField } from '@kurot/core';
8
+ import { resolveResourceUrl, createPlayer, Event, resource, TextField } from '@kurot/core';
9
9
  import { Button, Label, Rect, Theme, UILayer, setAssetAdapter } from '@kurot/ui';
10
10
  import { Tween } from '@kurot/game';
11
11
  import { AssetAdapter } from '@/AssetAdapter';
@@ -75,7 +75,7 @@ class Main extends UILayer {
75
75
 
76
76
  private async _loadTheme(): Promise<void> {
77
77
  // Load the theme and its default UI skin mappings.
78
- const theme = new Theme(new URL('resource/default.thm.json', document.baseURI).href);
78
+ const theme = new Theme(resolveResourceUrl(new URL('resource/default.thm.json', document.baseURI)));
79
79
  await new Promise<void>(resolve => theme.addEventListener(Event.COMPLETE, () => resolve()));
80
80
  }
81
81
 
@@ -1,3 +1,4 @@
1
+ import { resolveResourceUrl } from '@kurot/core';
1
2
  import { getUIStyleColor, getUIStyleFontAlias, getUIStyleFontFamily, parseUIStyleSheet } from '@kurot/ui-document';
2
3
  import type { UIStyleFontFace } from '@kurot/ui-document';
3
4
 
@@ -18,7 +19,7 @@ export class StyleManager {
18
19
 
19
20
  public static async init(): Promise<void> {
20
21
  const resourceRoot = new URL('resource/', document.baseURI);
21
- const response = await fetch(new URL('config/style.json', resourceRoot));
22
+ const response = await fetch(resolveResourceUrl(new URL('config/style.json', resourceRoot)));
22
23
  if (!response.ok) {
23
24
  throw new Error(`Unable to load resource/config/style.json: HTTP ${response.status}.`);
24
25
  }
@@ -45,7 +46,7 @@ export class StyleManager {
45
46
 
46
47
  private static async _loadFace(key: string, definition: UIStyleFontFace, resourceRoot: URL): Promise<FontFace> {
47
48
  const url = new URL(definition.url.split('/').map(encodeURIComponent).join('/'), resourceRoot);
48
- const face = new FontFace(getUIStyleFontAlias(key), `url("${url.href}")`, {
49
+ const face = new FontFace(getUIStyleFontAlias(key), `url("${resolveResourceUrl(url)}")`, {
49
50
  weight: String(definition.weight),
50
51
  });
51
52
  try {
@@ -1,7 +0,0 @@
1
- import type { BuildPlugin } from '../pipeline.js';
2
- /**
3
- * Gives every relative release URL one content-addressed base, including
4
- * secondary analyzer requests, fonts and assets owned by the HTML template.
5
- */
6
- export declare function versionAssets(): BuildPlugin;
7
- //# sourceMappingURL=version-assets.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"version-assets.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/version-assets.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEhE;;;GAGG;AACH,wBAAgB,aAAa,IAAI,WAAW,CAyC3C"}
@@ -1,108 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- import { createReadStream } from 'node:fs';
3
- import * as fs from 'node:fs/promises';
4
- import * as path from 'node:path';
5
- import { defaultTreeAdapter, parse } from 'parse5';
6
- import { BuildError } from '../errors.js';
7
- /**
8
- * Gives every relative release URL one content-addressed base, including
9
- * secondary analyzer requests, fonts and assets owned by the HTML template.
10
- */
11
- export function versionAssets() {
12
- return {
13
- name: 'version release assets',
14
- async apply(ctx) {
15
- if (ctx.project.mode !== 'release' || !ctx.project.config.output.versionedAssets) {
16
- return;
17
- }
18
- const outputDir = ctx.project.outputDir;
19
- const htmlPath = path.join(outputDir, 'index.html');
20
- const html = await fs.readFile(htmlPath, 'utf8');
21
- const headEnd = validateHtml(html);
22
- const version = await hashDirectory(outputDir);
23
- const prefix = `assets/${version}/`;
24
- const entries = await fs.readdir(outputDir);
25
- const staging = await fs.mkdtemp(path.join(outputDir, '.version-assets-'));
26
- try {
27
- for (const entry of entries) {
28
- if (entry === 'index.html' || entry === 'manifest.json') {
29
- continue;
30
- }
31
- await fs.rename(path.join(outputDir, entry), path.join(staging, entry));
32
- }
33
- await fs.mkdir(path.join(outputDir, 'assets'));
34
- await fs.rename(staging, path.join(outputDir, prefix));
35
- }
36
- finally {
37
- await fs.rm(staging, { recursive: true, force: true });
38
- }
39
- prefixOutputs(ctx, prefix);
40
- const manifest = {
41
- initial: Object.values(ctx.outputs.engine),
42
- game: [ctx.outputs.skinsScript, ctx.outputs.entryScript].filter(Boolean),
43
- };
44
- await fs.writeFile(path.join(outputDir, 'manifest.json'), JSON.stringify(manifest, undefined, '\t') + '\n');
45
- await fs.writeFile(htmlPath, `${html.slice(0, headEnd)}\n\t<base href="./${prefix}">${html.slice(headEnd)}`);
46
- },
47
- };
48
- }
49
- function validateHtml(html) {
50
- const document = parse(html, { sourceCodeLocationInfo: true });
51
- const root = document.childNodes.find(defaultTreeAdapter.isElementNode);
52
- const head = root?.childNodes.filter(defaultTreeAdapter.isElementNode).find(node => node.tagName === 'head');
53
- // HTML parsing can imply a head; insertion requires its authored start tag.
54
- const headEnd = head?.sourceCodeLocation?.startTag?.endOffset;
55
- if (headEnd === undefined) {
56
- throw new BuildError('output.versionedAssets requires an HTML template with a <head> element.');
57
- }
58
- const elements = root ? [root] : [];
59
- while (elements.length > 0) {
60
- const element = elements.pop();
61
- if (element.tagName === 'base') {
62
- throw new BuildError("output.versionedAssets owns the HTML base URL; remove the template's <base> element.");
63
- }
64
- elements.push(...element.childNodes.filter(defaultTreeAdapter.isElementNode));
65
- }
66
- return headEnd;
67
- }
68
- async function hashDirectory(root) {
69
- const hash = createHash('sha256');
70
- const files = await listFiles(root);
71
- for (const relative of files.sort()) {
72
- const file = path.join(root, relative);
73
- const stat = await fs.stat(file);
74
- hash.update(JSON.stringify([relative, stat.size]) + '\n');
75
- for await (const chunk of createReadStream(file)) {
76
- hash.update(chunk);
77
- }
78
- }
79
- return hash.digest('hex').slice(0, 32);
80
- }
81
- async function listFiles(root, directory = '') {
82
- const files = [];
83
- for (const entry of await fs.readdir(path.join(root, directory), { withFileTypes: true })) {
84
- const relative = path.posix.join(directory, entry.name);
85
- if (entry.isDirectory()) {
86
- files.push(...(await listFiles(root, relative)));
87
- }
88
- else if (entry.isFile()) {
89
- files.push(relative);
90
- }
91
- else {
92
- throw new BuildError(`Versioned assets require regular files or directories: ${relative}`);
93
- }
94
- }
95
- return files;
96
- }
97
- function prefixOutputs(ctx, prefix) {
98
- if (ctx.outputs.entryScript) {
99
- ctx.outputs.entryScript = prefix + ctx.outputs.entryScript;
100
- }
101
- if (ctx.outputs.skinsScript) {
102
- ctx.outputs.skinsScript = prefix + ctx.outputs.skinsScript;
103
- }
104
- for (const specifier of Object.keys(ctx.outputs.engine)) {
105
- ctx.outputs.engine[specifier] = prefix + ctx.outputs.engine[specifier];
106
- }
107
- }
108
- //# sourceMappingURL=version-assets.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"version-assets.js","sourceRoot":"","sources":["../../../src/core/plugins/version-assets.ts"],"names":[],"mappings":"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"}