@kurot/cli 3.7.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 (57) hide show
  1. package/CHANGELOG.md +87 -1
  2. package/README.md +23 -11
  3. package/dist/core/config-watcher.d.ts +8 -0
  4. package/dist/core/config-watcher.d.ts.map +1 -0
  5. package/dist/core/config-watcher.js +63 -0
  6. package/dist/core/config-watcher.js.map +1 -0
  7. package/dist/core/config.d.ts +9 -3
  8. package/dist/core/config.d.ts.map +1 -1
  9. package/dist/core/config.js +23 -6
  10. package/dist/core/config.js.map +1 -1
  11. package/dist/core/dev-server.d.ts.map +1 -1
  12. package/dist/core/dev-server.js +2 -0
  13. package/dist/core/dev-server.js.map +1 -1
  14. package/dist/core/diagnostics/codes.d.ts +2 -0
  15. package/dist/core/diagnostics/codes.d.ts.map +1 -1
  16. package/dist/core/diagnostics/codes.js +2 -0
  17. package/dist/core/diagnostics/codes.js.map +1 -1
  18. package/dist/core/diagnostics/output.d.ts +1 -1
  19. package/dist/core/diagnostics/output.d.ts.map +1 -1
  20. package/dist/core/plugins/generate-html.d.ts +7 -1
  21. package/dist/core/plugins/generate-html.d.ts.map +1 -1
  22. package/dist/core/plugins/generate-html.js +20 -4
  23. package/dist/core/plugins/generate-html.js.map +1 -1
  24. package/dist/core/plugins/index.d.ts +1 -1
  25. package/dist/core/plugins/index.d.ts.map +1 -1
  26. package/dist/core/plugins/index.js +3 -3
  27. package/dist/core/plugins/index.js.map +1 -1
  28. package/dist/core/plugins/resource-version-css.d.ts +7 -0
  29. package/dist/core/plugins/resource-version-css.d.ts.map +1 -0
  30. package/dist/core/plugins/resource-version-css.js +41 -0
  31. package/dist/core/plugins/resource-version-css.js.map +1 -0
  32. package/dist/core/plugins/resource-version-html.d.ts +7 -0
  33. package/dist/core/plugins/resource-version-html.d.ts.map +1 -0
  34. package/dist/core/plugins/resource-version-html.js +66 -0
  35. package/dist/core/plugins/resource-version-html.js.map +1 -0
  36. package/dist/core/plugins/version-resources.d.ts +7 -0
  37. package/dist/core/plugins/version-resources.d.ts.map +1 -0
  38. package/dist/core/plugins/version-resources.js +89 -0
  39. package/dist/core/plugins/version-resources.js.map +1 -0
  40. package/docs/ai-context.md +15 -7
  41. package/docs/architecture.md +12 -7
  42. package/docs/default-ui-skins.md +4 -5
  43. package/docs/dev-resource-watching.md +23 -3
  44. package/docs/game-template.md +17 -0
  45. package/docs/release-assets.md +64 -55
  46. package/package.json +3 -2
  47. package/templates/empty/README.md +13 -1
  48. package/templates/empty/kurot.config.ts +1 -1
  49. package/templates/empty/src/Main.ts +5 -7
  50. package/templates/game/README.md +13 -1
  51. package/templates/game/kurot.config.ts +1 -1
  52. package/templates/game/src/Main.ts +3 -9
  53. package/templates/game/src/StyleManager.ts +3 -2
  54. package/dist/core/plugins/version-assets.d.ts +0 -7
  55. package/dist/core/plugins/version-assets.d.ts.map +0 -1
  56. package/dist/core/plugins/version-assets.js +0 -108
  57. package/dist/core/plugins/version-assets.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurot/cli",
3
- "version": "3.7.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",
@@ -33,7 +33,10 @@ browser console, resource requests and intended interactions.
33
33
  - `src/Main.ts`: creates the single Player and root Sprite; add game objects
34
34
  and input/update logic here or in application modules it imports.
35
35
  - `kurot.config.ts`: build entry, stage settings and output paths. Keep explicit
36
- createPlayer options in Main consistent with the intended stage settings.
36
+ stage defaults here; Main uses `createPlayer({ canvas })` to consume the generated
37
+ canvas attributes. This requires Core >= 2.6.0 within 2.x. With CLI >= 3.8.0
38
+ within 3.x, save stage edits, wait for the dev update, then refresh the browser;
39
+ structural build changes require restarting dev.
37
40
  - `template/web/index.html`: authored HTML and canvas.
38
41
  - `bin-debug/`, `bin-release/` and `.kurot/`: generated files; edit their inputs.
39
42
 
@@ -58,3 +61,12 @@ source if needed. Repository `src/` paths are not guaranteed inside npm packages
58
61
 
59
62
  The project starts with Core only. Add further SDKs explicitly when gameplay
60
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,
@@ -21,12 +21,10 @@ class Main extends Sprite {
21
21
  }
22
22
 
23
23
  // ── Bootstrap ─────────────────────────────────────────────────────────────
24
- const app = createPlayer({
25
- canvas: document.getElementById('gameCanvas') as HTMLCanvasElement,
26
- contentWidth: 640,
27
- contentHeight: 1136,
28
- scaleMode: 'showAll',
29
- frameRate: 60,
30
- });
24
+ const canvas = document.getElementById('gameCanvas');
25
+ if (!(canvas instanceof HTMLCanvasElement)) {
26
+ throw new Error('Missing gameCanvas.');
27
+ }
28
+ const app = createPlayer({ canvas });
31
29
 
32
30
  app.start(new Main());
@@ -45,7 +45,10 @@ requests and the intended interactions in the browser.
45
45
  `src/components/<Name>.ts` with
46
46
  `resource/ui/components/<Name>Skin.kui.xml`; export the matching class name.
47
47
  - `kurot.config.ts`: build/stage/component settings; `template/web/index.html`:
48
- authored HTML. Keep explicit createPlayer options consistent with stage intent.
48
+ authored HTML. Main uses `createPlayer({ canvas })` with the generated canvas
49
+ attributes; edit stage defaults only in config. This requires Core >= 2.6.0
50
+ within 2.x. With CLI >= 3.8.0 within 3.x, save stage edits, wait for the update
51
+ and refresh the browser; structural build changes require restarting.
49
52
  - `bin-debug/`, `bin-release/`, `.kurot/` and generated theme JSON: build outputs.
50
53
  Edit authored inputs; the CLI generates the Skin module and part declarations.
51
54
 
@@ -88,3 +91,12 @@ The 2× default atlas needs Core >= 2.5.0 within 2.x; also satisfy the installed
88
91
  UI's Core peer. ui-document supports this starter's stylesheet parsing.
89
92
  CLI-compiled skins run through UI; add ui-runtime only for its materialization
90
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
 
@@ -181,13 +181,7 @@ async function start(): Promise<void> {
181
181
  if (!(canvas instanceof HTMLCanvasElement)) {
182
182
  throw new Error('Missing gameCanvas.');
183
183
  }
184
- const app = createPlayer({
185
- canvas,
186
- contentWidth: 640,
187
- contentHeight: 1136,
188
- scaleMode: 'showAll',
189
- frameRate: 60,
190
- });
184
+ const app = createPlayer({ canvas });
191
185
  app.start(new Main());
192
186
  }
193
187
 
@@ -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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"}