@series-inc/stowkit-cli 0.1.17 → 0.1.20
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.
- package/dist/app/disk-project.js +6 -0
- package/dist/core/types.d.ts +6 -1
- package/dist/core/types.js +5 -0
- package/dist/init.js +8 -6
- package/dist/server.js +10 -1
- package/package.json +2 -2
- package/skill.md +115 -0
package/dist/app/disk-project.js
CHANGED
|
@@ -64,7 +64,13 @@ export const PREVIEW_FLAG_STRINGS = {
|
|
|
64
64
|
mainTex: 1,
|
|
65
65
|
tint: 2,
|
|
66
66
|
alphaTest: 3,
|
|
67
|
+
metalness: 4,
|
|
68
|
+
roughness: 5,
|
|
69
|
+
normalMap: 6,
|
|
70
|
+
emissiveMap: 7,
|
|
71
|
+
emissive: 8,
|
|
67
72
|
};
|
|
68
73
|
export const PREVIEW_FLAG_TO_STRING = {
|
|
69
74
|
0: 'none', 1: 'mainTex', 2: 'tint', 3: 'alphaTest',
|
|
75
|
+
4: 'metalness', 5: 'roughness', 6: 'normalMap', 7: 'emissiveMap', 8: 'emissive',
|
|
70
76
|
};
|
package/dist/core/types.d.ts
CHANGED
|
@@ -39,7 +39,12 @@ export declare enum PreviewPropertyFlag {
|
|
|
39
39
|
None = 0,
|
|
40
40
|
MainTex = 1,
|
|
41
41
|
Tint = 2,
|
|
42
|
-
AlphaTest = 3
|
|
42
|
+
AlphaTest = 3,
|
|
43
|
+
Metalness = 4,
|
|
44
|
+
Roughness = 5,
|
|
45
|
+
NormalMap = 6,
|
|
46
|
+
EmissiveMap = 7,
|
|
47
|
+
Emissive = 8
|
|
43
48
|
}
|
|
44
49
|
export declare enum AacQuality {
|
|
45
50
|
Lowest = 0,
|
package/dist/core/types.js
CHANGED
|
@@ -49,6 +49,11 @@ export var PreviewPropertyFlag;
|
|
|
49
49
|
PreviewPropertyFlag[PreviewPropertyFlag["MainTex"] = 1] = "MainTex";
|
|
50
50
|
PreviewPropertyFlag[PreviewPropertyFlag["Tint"] = 2] = "Tint";
|
|
51
51
|
PreviewPropertyFlag[PreviewPropertyFlag["AlphaTest"] = 3] = "AlphaTest";
|
|
52
|
+
PreviewPropertyFlag[PreviewPropertyFlag["Metalness"] = 4] = "Metalness";
|
|
53
|
+
PreviewPropertyFlag[PreviewPropertyFlag["Roughness"] = 5] = "Roughness";
|
|
54
|
+
PreviewPropertyFlag[PreviewPropertyFlag["NormalMap"] = 6] = "NormalMap";
|
|
55
|
+
PreviewPropertyFlag[PreviewPropertyFlag["EmissiveMap"] = 7] = "EmissiveMap";
|
|
56
|
+
PreviewPropertyFlag[PreviewPropertyFlag["Emissive"] = 8] = "Emissive";
|
|
52
57
|
})(PreviewPropertyFlag || (PreviewPropertyFlag = {}));
|
|
53
58
|
// ─── Audio Enums ────────────────────────────────────────────────────────
|
|
54
59
|
export var AacQuality;
|
package/dist/init.js
CHANGED
|
@@ -49,15 +49,17 @@ export async function initProject(projectDir) {
|
|
|
49
49
|
catch {
|
|
50
50
|
await fs.writeFile(gitignorePath, stowkitIgnores + '\n');
|
|
51
51
|
}
|
|
52
|
-
// Copy
|
|
53
|
-
const skillDir = path.join(absDir, '.claude', 'skills');
|
|
54
|
-
await fs.mkdir(skillDir, { recursive: true });
|
|
52
|
+
// Copy AI skill/rule files (CLI skill only — loader skills are installed locally with their packages)
|
|
55
53
|
const thisDir = path.dirname(fileURLToPath(import.meta.url));
|
|
56
54
|
const skillSrc = path.resolve(thisDir, '../skill.md');
|
|
57
|
-
const skillDst = path.join(skillDir, 'stowkit.md');
|
|
58
55
|
try {
|
|
59
56
|
const skillContent = await fs.readFile(skillSrc, 'utf-8');
|
|
60
|
-
|
|
57
|
+
const claudeDir = path.join(absDir, '.claude', 'skills', 'stowkit');
|
|
58
|
+
await fs.mkdir(claudeDir, { recursive: true });
|
|
59
|
+
await fs.writeFile(path.join(claudeDir, 'SKILL.md'), skillContent);
|
|
60
|
+
const cursorDir = path.join(absDir, '.cursor', 'rules');
|
|
61
|
+
await fs.mkdir(cursorDir, { recursive: true });
|
|
62
|
+
await fs.writeFile(path.join(cursorDir, 'stowkit.mdc'), `---\ndescription: StowKit asset pipeline — CLI usage, .stowmeta/.stowmat formats, GLB containers, and runtime reader packages\nalwaysApply: true\n---\n\n${skillContent}`);
|
|
61
63
|
}
|
|
62
64
|
catch {
|
|
63
65
|
// Skill file not found in package — skip silently
|
|
@@ -66,7 +68,7 @@ export async function initProject(projectDir) {
|
|
|
66
68
|
console.log(` Source art dir: ${srcArtDir}/`);
|
|
67
69
|
console.log(` Output dir: public/cdn-assets/`);
|
|
68
70
|
console.log(` Config: .felicityproject`);
|
|
69
|
-
console.log(`
|
|
71
|
+
console.log(` AI skills: .claude/skills/stowkit/SKILL.md, .cursor/rules/stowkit.mdc`);
|
|
70
72
|
console.log('');
|
|
71
73
|
console.log('Drop your assets (PNG, JPG, FBX, WAV, etc.) into assets/');
|
|
72
74
|
console.log('Then run: npx stowkit build');
|
package/dist/server.js
CHANGED
|
@@ -523,8 +523,14 @@ async function processOneAsset(id) {
|
|
|
523
523
|
const asset = assets.find(a => a.id === id);
|
|
524
524
|
if (!asset)
|
|
525
525
|
return;
|
|
526
|
-
if (asset.type === AssetType.MaterialSchema)
|
|
526
|
+
if (asset.type === AssetType.MaterialSchema) {
|
|
527
|
+
// Materials are metadata-only — no encoding needed. Ensure they're always ready.
|
|
528
|
+
if (asset.status !== 'ready') {
|
|
529
|
+
asset.status = 'ready';
|
|
530
|
+
broadcast({ type: 'asset-update', id, updates: { status: 'ready' } });
|
|
531
|
+
}
|
|
527
532
|
return;
|
|
533
|
+
}
|
|
528
534
|
// GLB children: if source data isn't in BlobStore, re-extract from parent GLB
|
|
529
535
|
// and process just this child (not the entire container)
|
|
530
536
|
if (asset.parentId && !BlobStore.getSource(id)) {
|
|
@@ -741,9 +747,12 @@ async function handleRequest(req, res, staticApps) {
|
|
|
741
747
|
[...currentIds].some(id => !diskIds.has(id)) ||
|
|
742
748
|
[...diskIds].some(id => !currentIds.has(id));
|
|
743
749
|
// Check for modified files (size or mtime changed)
|
|
750
|
+
// Skip MaterialSchema — .stowmat files are metadata-only and written by the server itself
|
|
744
751
|
const modifiedIds = [];
|
|
745
752
|
if (!changed) {
|
|
746
753
|
for (const asset of currentAssets) {
|
|
754
|
+
if (asset.type === AssetType.MaterialSchema)
|
|
755
|
+
continue;
|
|
747
756
|
const diskFile = diskFiles.get(asset.id);
|
|
748
757
|
if (diskFile && asset.sourceSize > 0 && diskFile.size !== asset.sourceSize) {
|
|
749
758
|
modifiedIds.push(asset.id);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@series-inc/stowkit-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"stowkit": "./dist/cli.js"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dev": "tsc --watch"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@series-inc/stowkit-packer-gui": "^0.1.
|
|
20
|
+
"@series-inc/stowkit-packer-gui": "^0.1.10",
|
|
21
21
|
"@series-inc/stowkit-editor": "^0.1.2",
|
|
22
22
|
"draco3d": "^1.5.7",
|
|
23
23
|
"fbx-parser": "^2.1.3",
|
package/skill.md
CHANGED
|
@@ -361,6 +361,121 @@ Cache is automatically invalidated when source files or settings change.
|
|
|
361
361
|
GLB children have their own cache entries stored alongside the container.
|
|
362
362
|
Add `*.stowcache` to `.gitignore`.
|
|
363
363
|
|
|
364
|
+
## Runtime Reader Packages
|
|
365
|
+
|
|
366
|
+
The CLI builds `.stow` packs. To **load** them at runtime you need a reader package. Choose based on your rendering engine:
|
|
367
|
+
|
|
368
|
+
| Package | Install | Use When |
|
|
369
|
+
|---------|---------|----------|
|
|
370
|
+
| `@series-inc/stowkit-reader` | `npm install @series-inc/stowkit-reader` | You want the low-level WASM reader only (zero deps) — parse packs, list assets, read binary data |
|
|
371
|
+
| `@series-inc/stowkit-three-loader` | `npm install @series-inc/stowkit-three-loader three` | Your game uses **Three.js** — loads meshes, skinned meshes, animations, textures, audio |
|
|
372
|
+
| `@series-inc/stowkit-phaser-loader` | `npm install @series-inc/stowkit-phaser-loader phaser` | Your game uses **Phaser** — loads KTX2/Basis compressed textures and audio |
|
|
373
|
+
|
|
374
|
+
If the project has a `.stow` build output but no reader dependency in `package.json`, the user likely needs one of these.
|
|
375
|
+
|
|
376
|
+
### Three.js Quick Start
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
import { StowKitLoader } from '@series-inc/stowkit-three-loader';
|
|
380
|
+
|
|
381
|
+
const pack = await StowKitLoader.load('game.stow');
|
|
382
|
+
|
|
383
|
+
const mesh = await pack.loadMesh('building');
|
|
384
|
+
scene.add(mesh);
|
|
385
|
+
|
|
386
|
+
const character = await pack.loadSkinnedMesh('player');
|
|
387
|
+
scene.add(character);
|
|
388
|
+
|
|
389
|
+
const { mixer } = await pack.loadAnimation(character, 'walk');
|
|
390
|
+
|
|
391
|
+
// In animation loop
|
|
392
|
+
mixer.update(clock.getDelta());
|
|
393
|
+
|
|
394
|
+
// Cleanup
|
|
395
|
+
pack.dispose();
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Key APIs on `StowKitPack`:
|
|
399
|
+
- `loadMesh(stringId)` / `loadMeshByIndex(i)` — static mesh → `THREE.Group`
|
|
400
|
+
- `loadSkinnedMesh(stringId)` / `loadSkinnedMeshByIndex(i)` — skeletal mesh → `THREE.Group`
|
|
401
|
+
- `loadAnimation(skinnedGroup, stringId)` — returns `{ mixer, action, clip }`
|
|
402
|
+
- `loadAnimationClip(stringId)` — returns `THREE.AnimationClip` without playback
|
|
403
|
+
- `loadTexture(stringId)` — KTX2 → `THREE.CompressedTexture`
|
|
404
|
+
- `loadAudio(stringId, listener)` — AAC → `THREE.Audio`
|
|
405
|
+
- `listAssets()` — full manifest of the pack
|
|
406
|
+
- `dispose()` — free resources
|
|
407
|
+
|
|
408
|
+
Loader options (passed to `StowKitLoader.load`):
|
|
409
|
+
- `wasmPath` — path to `stowkit_reader.wasm` (default `'/stowkit/stowkit_reader.wasm'`)
|
|
410
|
+
- `basisPath` — path to Basis Universal transcoder (default `'/stowkit/basis/'`)
|
|
411
|
+
- `dracoPath` — path to Draco decoder (default `'/stowkit/draco/'`)
|
|
412
|
+
|
|
413
|
+
The three-loader auto-copies WASM/Basis/Draco files into `public/stowkit/` via a postinstall script.
|
|
414
|
+
|
|
415
|
+
### Phaser Quick Start
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
import { StowKitPhaserLoader } from '@series-inc/stowkit-phaser-loader';
|
|
419
|
+
|
|
420
|
+
const pack = await StowKitPhaserLoader.load('/assets/game.stow');
|
|
421
|
+
|
|
422
|
+
await pack.loadTexture('characters/player', this); // registers with Phaser texture manager
|
|
423
|
+
const player = this.add.sprite(400, 300, 'characters/player');
|
|
424
|
+
|
|
425
|
+
const audioBuffer = await pack.loadAudio('sounds/bgm');
|
|
426
|
+
|
|
427
|
+
pack.dispose();
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Key APIs on `StowKitPhaserPack`:
|
|
431
|
+
- `loadTexture(assetPath, scene)` — KTX2 → Phaser texture (auto-transcodes to best GPU format)
|
|
432
|
+
- `loadAudio(assetPath, audioContext?)` — AAC → `AudioBuffer`
|
|
433
|
+
- `listAssets()` / `getAssetCount()` — pack manifest
|
|
434
|
+
- `dispose()` — free resources
|
|
435
|
+
|
|
436
|
+
Phaser limitation: no 3D model support — only 2D textures and audio. For 3D, use the three-loader.
|
|
437
|
+
|
|
438
|
+
### Low-Level Reader
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
import { StowKitReader } from '@series-inc/stowkit-reader';
|
|
442
|
+
|
|
443
|
+
const reader = new StowKitReader();
|
|
444
|
+
await reader.init();
|
|
445
|
+
await reader.open(await fetch('assets.stow').then(r => r.arrayBuffer()));
|
|
446
|
+
|
|
447
|
+
const assets = reader.listAssets();
|
|
448
|
+
const texInfo = reader.parseTextureMetadata(0);
|
|
449
|
+
const audioInfo = reader.parseAudioMetadata(1);
|
|
450
|
+
const data = reader.readAssetData(0);
|
|
451
|
+
|
|
452
|
+
reader.close();
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
All binary parsing is done in WASM (Zig) — 10-50x faster than JavaScript DataView.
|
|
456
|
+
|
|
457
|
+
### Multiple Packs
|
|
458
|
+
|
|
459
|
+
All reader packages support loading multiple `.stow` packs simultaneously with isolated state:
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
const [envPack, charPack] = await Promise.all([
|
|
463
|
+
StowKitLoader.load('environment.stow'),
|
|
464
|
+
StowKitLoader.load('characters.stow'),
|
|
465
|
+
]);
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Performance Logging
|
|
469
|
+
|
|
470
|
+
All reader packages re-export `PerfLogger`:
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
import { PerfLogger } from '@series-inc/stowkit-three-loader';
|
|
474
|
+
PerfLogger.enable();
|
|
475
|
+
// ... load assets — timing details appear in console ...
|
|
476
|
+
PerfLogger.disable();
|
|
477
|
+
```
|
|
478
|
+
|
|
364
479
|
## Common Tasks for AI Agents
|
|
365
480
|
|
|
366
481
|
### Adding a GLB model (recommended 3D workflow)
|