@helix3/helix-cli 0.1.15-helix3.236 → 0.1.15-helix3.237
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/README.md +1 -0
- package/dist/index.js +102 -1
- package/dist/index.js.map +1 -1
- package/dist/item.d.ts +9 -0
- package/dist/item.js +22 -3
- package/dist/item.js.map +1 -1
- package/dist/lib.d.ts +6 -5
- package/dist/lib.js +39 -18
- package/dist/lib.js.map +1 -1
- package/dist/pack/locomotionReference.d.ts +40 -0
- package/dist/pack/locomotionReference.js +132 -0
- package/dist/pack/locomotionReference.js.map +1 -0
- package/dist/pack/publish.d.ts +60 -0
- package/dist/pack/publish.js +185 -0
- package/dist/pack/publish.js.map +1 -0
- package/dist/pack/scaffold.d.ts +15 -0
- package/dist/pack/scaffold.js +149 -0
- package/dist/pack/scaffold.js.map +1 -0
- package/dist/pack/validate.d.ts +67 -0
- package/dist/pack/validate.js +317 -0
- package/dist/pack/validate.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
package/README.md
CHANGED
|
@@ -64,6 +64,7 @@ The token is stored in `~/.helix/credentials.json` (mode `600`). It's sent as
|
|
|
64
64
|
| `helix assets credits\|check-loaders` | Render asset credits from provenance and reject models requiring unsupported loaders. |
|
|
65
65
|
| `helix character import <body.glb> [--map <json>] [--fit source\|canonical] [--provenance <json>]` | Convert one self-contained third-party humanoid through the public `helix-humanoid@1` pipeline. The command rejects external/remote resources and resource bombs before parsing, generates bounded LODs, and emits a source/license/transformation/checksum receipt beside the output. `--fit canonical` aligns the rest skeleton/proportions; it does not prove that Base Male-targeted garments fit a different body surface. |
|
|
66
66
|
| `helix character retarget-animation <clip.fbx\|clip.glb>` | Retarget a raw Mixamo/Meshy clip directly to `helix-humanoid@1`. FBX conversion is deterministic and runs inside the CLI; no hidden Blender/DCC pre-export is required. |
|
|
67
|
+
| `helix pack scaffold\|validate\|publish <dir>` | Locomotion packs — the replacement movement clips a player equips as a character add-on in the `character.locomotion@1` clip-set slot. `scaffold` writes `anims/clip-meta.json` plus a README carrying the per-clip contract; `validate` runs the whole gate offline in **one** pass (clip-meta schema, one GLB per entry with exactly one animation, measured length against the declared duration, the gait-only vocabulary, the `strideSpeed` bands, and walk < run < sprint); `publish` uploads each clip GLB as a public Vault animation, records the returned pins in `anims/pins.json`, then publishes the **meshless** add-on whose ops pin those versions — a re-run reuses every unchanged pin, so an interrupted publish resumes. The governing rule of the slot: a pack may change how a walk *looks*; it may never change how far that walk *gets you*. Partial packs are valid products down to a single clip. `--dry-run` stops before any network call and works logged out. |
|
|
67
68
|
| `helix world audit\|source-audit\|perf-gate\|prove-live` | Run the blocking world QA, performance, and deployed-build identity gates. |
|
|
68
69
|
| `helix world performance-report [bundle] [--scene <scene-v2.json>] [--package <package-version.json>] [--snapshot <inspect.json>] [--perf <receipt.json>]` | Analyze exact declared scene resources and existing reference-profile budgets, while keeping authored geometry/material/delivery estimates separate from supplied runtime claims. Prints actionable instancing, Palette, lighting, transfer, and visual-QA guidance; it never predicts FPS from static counts. |
|
|
69
70
|
| `helix world scene-source inventory\|compile <helsinki\|bistro> <archive>` | Verify and safely inventory a known CC BY source archive, then compile deterministic local proxy/detail GLBs and an existing-schema Scene v2 package. |
|
package/dist/index.js
CHANGED
|
@@ -1454,7 +1454,7 @@ item
|
|
|
1454
1454
|
}
|
|
1455
1455
|
console.log(`✔ Dry run — nothing uploaded, no fee charged.`);
|
|
1456
1456
|
console.log(` POST ${plan.endpoint}`);
|
|
1457
|
-
console.log(` mesh: ${plan.mesh.file} (${(plan.mesh.sizeBytes / 1024).toFixed(1)} KiB, ${plan.mesh.contentType})`);
|
|
1457
|
+
console.log(` mesh: ${plan.mesh ? `${plan.mesh.file} (${(plan.mesh.sizeBytes / 1024).toFixed(1)} KiB, ${plan.mesh.contentType})` : '(none — the clips are the content)'}`);
|
|
1458
1458
|
console.log(` thumbnail: ${plan.thumbnail ? `${plan.thumbnail.file} (${(plan.thumbnail.sizeBytes / 1024).toFixed(1)} KiB, ${plan.thumbnail.contentType})` : '(none — server-rendered)'}`);
|
|
1459
1459
|
console.log(` payload: ${JSON.stringify(plan.payload, null, 2).replace(/\n/g, '\n ')}`);
|
|
1460
1460
|
for (const warning of plan.warnings)
|
|
@@ -3788,6 +3788,107 @@ itemDef
|
|
|
3788
3788
|
fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
3789
3789
|
}
|
|
3790
3790
|
});
|
|
3791
|
+
const pack = program
|
|
3792
|
+
.command('pack')
|
|
3793
|
+
.description('Locomotion packs — the replacement movement clips a player equips as a character add-on: scaffold the pack directory, validate it offline, publish it into the character.locomotion@1 slot');
|
|
3794
|
+
pack
|
|
3795
|
+
.command('scaffold')
|
|
3796
|
+
.description('Write a starter locomotion pack: anims/clip-meta.json with one example entry, plus a README carrying the per-clip contract the publish gate enforces')
|
|
3797
|
+
.argument('<dir>', 'directory for the new pack (the starter files land in <dir>/anims/)')
|
|
3798
|
+
.option('--overwrite', 'replace files that already exist (default: skip them)')
|
|
3799
|
+
.action(async (dir, opts) => {
|
|
3800
|
+
try {
|
|
3801
|
+
const { scaffoldLocomotionPack } = await Promise.resolve().then(() => __importStar(require('./pack/scaffold')));
|
|
3802
|
+
const result = scaffoldLocomotionPack({ dir, ...(opts.overwrite === true && { overwrite: true }) });
|
|
3803
|
+
console.log(`✔ Created ${result.created.length} file(s) in ${result.dir}`);
|
|
3804
|
+
if (result.skipped.length > 0) {
|
|
3805
|
+
console.log(` Kept ${result.skipped.length} existing file(s): ${result.skipped.join(', ')} (--overwrite to replace)`);
|
|
3806
|
+
}
|
|
3807
|
+
console.log(`\nNext steps:\n${result.nextSteps.map((step, index) => ` ${index + 1}. ${step}`).join('\n')}`);
|
|
3808
|
+
}
|
|
3809
|
+
catch (err) {
|
|
3810
|
+
fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
3811
|
+
}
|
|
3812
|
+
});
|
|
3813
|
+
pack
|
|
3814
|
+
.command('validate')
|
|
3815
|
+
.description('Validate a locomotion pack offline, reporting EVERY problem in one pass: the clip-meta schema, one GLB per entry with exactly one animation, the measured length against the declared duration, the gait-only vocabulary, the strideSpeed bands and the walk < run < sprint ladder')
|
|
3816
|
+
.argument('<dir>', 'the pack directory (the one containing anims/)')
|
|
3817
|
+
.action(async (dir) => {
|
|
3818
|
+
try {
|
|
3819
|
+
const { validateLocomotionPack } = await Promise.resolve().then(() => __importStar(require('./pack/validate')));
|
|
3820
|
+
const result = validateLocomotionPack(dir);
|
|
3821
|
+
if (result.warnings.length > 0)
|
|
3822
|
+
console.log(`warnings:\n ${result.warnings.join('\n ')}`);
|
|
3823
|
+
if (result.errors.length > 0) {
|
|
3824
|
+
fail(`✖ ${result.errors.length} error(s):\n - ${result.errors.join('\n - ')}`);
|
|
3825
|
+
}
|
|
3826
|
+
console.log(`✔ valid — ${result.clips.length} clip(s), ${result.clips.filter((clip) => clip.pin !== null).length} already pinned`);
|
|
3827
|
+
}
|
|
3828
|
+
catch (err) {
|
|
3829
|
+
fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
3830
|
+
}
|
|
3831
|
+
});
|
|
3832
|
+
pack
|
|
3833
|
+
.command('publish')
|
|
3834
|
+
.description('Publish a validated locomotion pack: upload each clip GLB as a public Vault animation carrying its measured duration, then publish the MESHLESS add-on whose ops pin those versions')
|
|
3835
|
+
.argument('<dir>', 'the pack directory')
|
|
3836
|
+
.option('--title <name>', 'add-on title (default: the pack directory name)')
|
|
3837
|
+
.option('--description <text>', 'store description — say WHICH clips the pack covers; every name it omits keeps the platform motion')
|
|
3838
|
+
.option('--tags <a,b,c>', 'comma-separated search keywords')
|
|
3839
|
+
.option('--dry-run', 'print what WOULD be uploaded and published; no upload, no publish, no fee')
|
|
3840
|
+
.action(async (dir, opts) => {
|
|
3841
|
+
const input = {
|
|
3842
|
+
dir,
|
|
3843
|
+
...(opts.title !== undefined && { title: opts.title }),
|
|
3844
|
+
...(opts.description !== undefined && { description: opts.description }),
|
|
3845
|
+
...(opts.tags !== undefined && { tags: (0, lib_1.parseTags)(opts.tags) }),
|
|
3846
|
+
};
|
|
3847
|
+
// --dry-run stops before ANY network call, so it works logged out — the point is to check the pack and
|
|
3848
|
+
// the metadata, not the account.
|
|
3849
|
+
if (opts.dryRun) {
|
|
3850
|
+
try {
|
|
3851
|
+
const { planPackPublish } = await Promise.resolve().then(() => __importStar(require('./pack/publish')));
|
|
3852
|
+
const plan = planPackPublish(input);
|
|
3853
|
+
console.log('✔ Dry run — nothing uploaded, no fee charged.');
|
|
3854
|
+
console.log(` ${plan.title} — ${plan.clips.length} clip(s): ${plan.uploads} to upload, ${plan.reused} pin(s) reused`);
|
|
3855
|
+
for (const clip of plan.clips) {
|
|
3856
|
+
const size = `${(clip.sizeBytes / 1024).toFixed(1)} KiB, ${clip.durationSeconds.toFixed(3)}s`;
|
|
3857
|
+
console.log(` ${clip.action === 'upload' ? '↑' : '='} ${clip.ref} (${size})`);
|
|
3858
|
+
}
|
|
3859
|
+
console.log(` payload: ${JSON.stringify(plan.payload, null, 2).replace(/\n/g, '\n ')}`);
|
|
3860
|
+
for (const warning of plan.warnings)
|
|
3861
|
+
console.log(` • ${warning}`);
|
|
3862
|
+
const status = (0, lib_1.authStatus)();
|
|
3863
|
+
if (!status.loggedIn)
|
|
3864
|
+
console.log(' • not logged in — run `helix login` before the real publish');
|
|
3865
|
+
}
|
|
3866
|
+
catch (err) {
|
|
3867
|
+
fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
3868
|
+
}
|
|
3869
|
+
return;
|
|
3870
|
+
}
|
|
3871
|
+
const creds = requireAuth();
|
|
3872
|
+
const mismatch = (0, config_1.credsEnvMismatchWarning)(creds.apiUrl);
|
|
3873
|
+
if (mismatch)
|
|
3874
|
+
fail(`✖ Refusing to publish a locomotion pack:\n${mismatch}`);
|
|
3875
|
+
try {
|
|
3876
|
+
const { publishLocomotionPack } = await Promise.resolve().then(() => __importStar(require('./pack/publish')));
|
|
3877
|
+
const report = await publishLocomotionPack(input, creds, { onProgress: (message) => console.log(` ${message}`) });
|
|
3878
|
+
const uploaded = report.clips.filter((clip) => clip.uploaded).length;
|
|
3879
|
+
console.log(`✔ Published "${report.item.title}" (${report.item.slug}) — ${report.clips.length} clip(s), ${uploaded} uploaded this run`);
|
|
3880
|
+
for (const clip of report.clips)
|
|
3881
|
+
console.log(` ${clip.name} → ${clip.assetId}@${clip.version}`);
|
|
3882
|
+
console.log(` status: ${report.item.status}`);
|
|
3883
|
+
console.log(` publish fee: ${report.item.publishFeeLix} LIX`);
|
|
3884
|
+
console.log(` id: ${report.item.id}`);
|
|
3885
|
+
if (report.warnings.length > 0)
|
|
3886
|
+
console.log(`warnings:\n ${report.warnings.join('\n ')}`);
|
|
3887
|
+
}
|
|
3888
|
+
catch (err) {
|
|
3889
|
+
fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
3890
|
+
}
|
|
3891
|
+
});
|
|
3791
3892
|
const world = program
|
|
3792
3893
|
.command('world')
|
|
3793
3894
|
.description("World tools — create the world's identity before publishing, and measure a built world's geometry as data instead of eyeballing screenshots");
|