@helix3/helix-cli 0.1.13-helix3.140 → 0.1.13-helix3.142

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 (47) hide show
  1. package/README.md +2 -0
  2. package/dist/index.js +113 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/item.d.ts +2 -0
  5. package/dist/item.js +26 -0
  6. package/dist/item.js.map +1 -1
  7. package/dist/sceneImport/archive.d.ts +30 -0
  8. package/dist/sceneImport/archive.js +336 -0
  9. package/dist/sceneImport/archive.js.map +1 -0
  10. package/dist/sceneImport/bistroMaterialBake.d.ts +20 -0
  11. package/dist/sceneImport/bistroMaterialBake.js +165 -0
  12. package/dist/sceneImport/bistroMaterialBake.js.map +1 -0
  13. package/dist/sceneImport/bistroTexturePlan.d.ts +6 -0
  14. package/dist/sceneImport/bistroTexturePlan.js +23 -0
  15. package/dist/sceneImport/bistroTexturePlan.js.map +1 -0
  16. package/dist/sceneImport/compiler.d.ts +36 -0
  17. package/dist/sceneImport/compiler.js +244 -0
  18. package/dist/sceneImport/compiler.js.map +1 -0
  19. package/dist/sceneImport/fbx.d.ts +32 -0
  20. package/dist/sceneImport/fbx.js +208 -0
  21. package/dist/sceneImport/fbx.js.map +1 -0
  22. package/dist/sceneImport/obj.d.ts +14 -0
  23. package/dist/sceneImport/obj.js +231 -0
  24. package/dist/sceneImport/obj.js.map +1 -0
  25. package/dist/sceneImport/package.d.ts +34 -0
  26. package/dist/sceneImport/package.js +411 -0
  27. package/dist/sceneImport/package.js.map +1 -0
  28. package/dist/sceneImport/packageReader.d.ts +10 -0
  29. package/dist/sceneImport/packageReader.js +200 -0
  30. package/dist/sceneImport/packageReader.js.map +1 -0
  31. package/dist/sceneImport/publish.d.ts +43 -0
  32. package/dist/sceneImport/publish.js +88 -0
  33. package/dist/sceneImport/publish.js.map +1 -0
  34. package/dist/sceneImport/spawnProbe.d.ts +48 -0
  35. package/dist/sceneImport/spawnProbe.js +94 -0
  36. package/dist/sceneImport/spawnProbe.js.map +1 -0
  37. package/dist/sceneImport/textureDecode.d.ts +19 -0
  38. package/dist/sceneImport/textureDecode.js +275 -0
  39. package/dist/sceneImport/textureDecode.js.map +1 -0
  40. package/dist/sceneImport/types.d.ts +50 -0
  41. package/dist/sceneImport/types.js +9 -0
  42. package/dist/sceneImport/types.js.map +1 -0
  43. package/dist/tsconfig.build.tsbuildinfo +1 -1
  44. package/dist/vaultPublish.d.ts +4 -1
  45. package/dist/vaultPublish.js +15 -1
  46. package/dist/vaultPublish.js.map +1 -1
  47. package/package.json +5 -3
package/README.md CHANGED
@@ -59,6 +59,8 @@ The token is stored in `~/.helix/credentials.json` (mode `600`). It's sent as
59
59
  | `helix assets credits\|check-loaders` | Render asset credits from provenance and reject models requiring unsupported loaders. |
60
60
  | `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. |
61
61
  | `helix world audit\|source-audit\|perf-gate\|prove-live` | Run the blocking world QA, performance, and deployed-build identity gates. |
62
+ | `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. |
63
+ | `helix world scene-source publish <world-id> <package-dir> [--publish]` | Validate the Scene v2 package and print its multipart build receipt. Execution remains dry-run-only until backend private-pin entitlement lands; `--publish` currently fails closed, and access control never changes CC BY rights. |
62
64
  | `helix unreal init\|validate\|doctor\|package [project]` | Create and gate a shared-runtime or native-game publish manifest, check optional editor MCP, and assemble a local upload-shaped package. |
63
65
  | `helix unreal publish <candidate> --world <slug>` | Upload a **cooked** Unreal world to HELIX: verify the candidate, presign, upload every artifact, finalize, and promote it as the world's active build. |
64
66
  | `helix doctor [--project <dir>]` | Print the environment + whether the @helix toolchain (CLI/MCP/SDK/manifest) is current. |
package/dist/index.js CHANGED
@@ -702,6 +702,7 @@ item
702
702
  .option('--ops <json|file>', 'add_on operation array (tune/hide/mount/patch); accepts inline JSON or a JSON file')
703
703
  .option('--host-kind <kind>', 'base host class with a published slot pack: vehicle or character')
704
704
  .option('--host-surface <json|file>', 'measured base surface ({ sockets, nodes, materialSlots, paths, skeleton }); inline JSON or file')
705
+ .option('--vehicle-package <json|file>', 'authored Universal Vehicle package, required for vehicles; inline JSON or file')
705
706
  .option('--slug <slug>', 'url slug (default: derived from the title)')
706
707
  .option('--description <text>', 'item description')
707
708
  .option('--thumbnail <file>', 'thumbnail image (png/jpg/webp); rendered from the mesh when omitted, required for an avatar')
@@ -733,6 +734,9 @@ item
733
734
  hostSurface: opts.hostSurface !== undefined
734
735
  ? (0, lib_1.parseJsonObjectOrFile)(opts.hostSurface, '--host-surface')
735
736
  : undefined,
737
+ vehiclePackage: opts.vehiclePackage !== undefined
738
+ ? (0, lib_1.parseJsonObjectOrFile)(opts.vehiclePackage, '--vehicle-package')
739
+ : undefined,
736
740
  slug: opts.slug,
737
741
  description: opts.description,
738
742
  collectibleSupply: opts.collectibleSupply !== undefined
@@ -1738,15 +1742,19 @@ assets
1738
1742
  .option('--description <text>', 'what this asset is')
1739
1743
  .option('--tags <a,b>', 'comma-separated tags')
1740
1744
  .option('--private', 'keep it out of Vault search — only you can reference it')
1745
+ .option('--license <license>', 'asset license (use cc_by for CC BY source derivatives)')
1741
1746
  .option('--human', 'readable summary instead of JSON')
1742
1747
  .action(async (file, opts) => {
1743
1748
  const creds = requireAuth();
1744
1749
  try {
1745
- const { publishVaultAsset } = await Promise.resolve().then(() => __importStar(require('./vaultPublish')));
1750
+ const { isVaultAssetLicense, publishVaultAsset } = await Promise.resolve().then(() => __importStar(require('./vaultPublish')));
1746
1751
  const path = (0, node_path_1.resolve)(file);
1747
1752
  if (!(0, node_fs_1.existsSync)(path))
1748
1753
  fail(`✖ no such file: ${file}`);
1749
1754
  const bytes = (0, node_fs_1.readFileSync)(path);
1755
+ if (opts.license !== undefined && !isVaultAssetLicense(opts.license)) {
1756
+ fail('✖ unknown Vault license; use helix_standard, cc0, cc_by, or all_rights_reserved');
1757
+ }
1750
1758
  const result = await publishVaultAsset(lib_1.HelixApi.forCredentials(creds), {
1751
1759
  bytes,
1752
1760
  filename: (0, node_path_1.basename)(path),
@@ -1755,6 +1763,7 @@ assets
1755
1763
  ...(opts.description !== undefined && { description: opts.description }),
1756
1764
  ...(opts.tags !== undefined && { tags: opts.tags.split(',') }),
1757
1765
  ...(opts.private === true && { visibility: 'private' }),
1766
+ ...(opts.license !== undefined && { license: opts.license }),
1758
1767
  });
1759
1768
  if (opts.human) {
1760
1769
  console.log(`✔ ${result.assetId} v${result.artifact.version}`);
@@ -3115,6 +3124,109 @@ world
3115
3124
  fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
3116
3125
  }
3117
3126
  });
3127
+ const sceneSource = world
3128
+ .command('scene-source')
3129
+ .description('Inventory and compile rights-clean native Scene v2 source packages');
3130
+ sceneSource
3131
+ .command('inventory')
3132
+ .description('Hash and inventory one supported source archive without extracting it')
3133
+ .argument('<source>', 'helsinki-672496d1 or bistro-interior')
3134
+ .argument('<archive>', 'immutable original ZIP')
3135
+ .action(async (source, archive) => {
3136
+ try {
3137
+ const { inventoryKnownSceneSource } = await Promise.resolve().then(() => __importStar(require('./sceneImport/compiler')));
3138
+ if (source !== 'helsinki-672496d1' && source !== 'bistro-interior') {
3139
+ fail('✖ source must be helsinki-672496d1 or bistro-interior');
3140
+ }
3141
+ console.log(JSON.stringify(await inventoryKnownSceneSource(source, (0, node_path_1.resolve)(archive)), null, 2));
3142
+ }
3143
+ catch (err) {
3144
+ fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
3145
+ }
3146
+ });
3147
+ sceneSource
3148
+ .command('compile')
3149
+ .description('Compile deterministic proxy/detail GLBs and an existing-schema Scene v2 package')
3150
+ .argument('<source>', 'helsinki-672496d1 or bistro-interior')
3151
+ .argument('<archive>', 'immutable original ZIP')
3152
+ .requiredOption('-o, --output <dir>', 'empty/new output directory for generated artifacts')
3153
+ .action(async (source, archive, opts) => {
3154
+ try {
3155
+ const { compileKnownSceneSource } = await Promise.resolve().then(() => __importStar(require('./sceneImport/compiler')));
3156
+ if (source !== 'helsinki-672496d1' && source !== 'bistro-interior') {
3157
+ fail('✖ source must be helsinki-672496d1 or bistro-interior');
3158
+ }
3159
+ const outputDir = (0, node_path_1.resolve)(opts.output);
3160
+ const result = await compileKnownSceneSource({ source, archivePath: (0, node_path_1.resolve)(archive), outputDir });
3161
+ const vaultPublication = result.resourcePaths.map((path) => ({
3162
+ path,
3163
+ license: 'cc_by',
3164
+ visibility: 'private',
3165
+ command: `helix assets publish ${JSON.stringify((0, node_path_1.join)(outputDir, path))} --license cc_by --private`,
3166
+ }));
3167
+ console.log(JSON.stringify({ ...result, scene: undefined, vaultPublication }, null, 2));
3168
+ }
3169
+ catch (err) {
3170
+ fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
3171
+ }
3172
+ });
3173
+ sceneSource
3174
+ .command('publish')
3175
+ .description('Validate and dry-run the native Scene v2 World-build multipart request')
3176
+ .argument('<world-id>', 'owned World UUID')
3177
+ .argument('<package-dir>', 'compiled Scene v2 package directory')
3178
+ .option('--profile <id>', 'Scene profile', 'world')
3179
+ .option('--content-rating <rating>', 'everyone, teen, or mature', 'everyone')
3180
+ .option('--supports-mobile', 'declare mobile support', false)
3181
+ .option('--requires-auth', 'require an authenticated player', false)
3182
+ .option('--visibility <visibility>', 'private, unlisted, or public', 'private')
3183
+ .option('--publish', 'upload the package and activate it as the World\'s build', false)
3184
+ .action(async (worldId, packageDir, opts) => {
3185
+ try {
3186
+ if (!['everyone', 'teen', 'mature'].includes(opts.contentRating)) {
3187
+ fail('✖ --content-rating must be everyone, teen, or mature');
3188
+ }
3189
+ if (!['private', 'unlisted', 'public'].includes(opts.visibility)) {
3190
+ fail('✖ --visibility must be private, unlisted, or public');
3191
+ }
3192
+ const { loadSceneV2Package } = await Promise.resolve().then(() => __importStar(require('./sceneImport/packageReader')));
3193
+ const { createSceneV2DryRunReceipt, publishSceneV2World } = await Promise.resolve().then(() => __importStar(require('./sceneImport/publish')));
3194
+ const input = await loadSceneV2Package({
3195
+ packageDir: (0, node_path_1.resolve)(packageDir),
3196
+ worldId,
3197
+ profileId: opts.profile,
3198
+ contentRating: opts.contentRating,
3199
+ supportsMobile: opts.supportsMobile,
3200
+ requiresAuth: opts.requiresAuth,
3201
+ visibility: opts.visibility,
3202
+ });
3203
+ if (!opts.publish) {
3204
+ console.log(JSON.stringify(createSceneV2DryRunReceipt(input), null, 2));
3205
+ return;
3206
+ }
3207
+ // `--visibility private` gates the WORLD ROW, not the bytes: published
3208
+ // Scene resources are content-addressed objects on the public worlds
3209
+ // bucket, so a private World is unlisted, not confidential. Say so
3210
+ // rather than letting the flag name imply a guarantee the backend does
3211
+ // not make yet.
3212
+ const creds = requireAuth();
3213
+ const receipt = await publishSceneV2World(lib_1.HelixApi.forCredentials(creds), input);
3214
+ console.log(JSON.stringify({
3215
+ schemaVersion: 'helix.scene-v2-world-build/1',
3216
+ dryRun: false,
3217
+ published: true,
3218
+ apiUrl: creds.apiUrl,
3219
+ worldId: input.worldId,
3220
+ profileId: input.profileId,
3221
+ visibility: input.visibility,
3222
+ contentDelivery: 'public-content-addressed; --visibility gates World discovery only',
3223
+ receipt,
3224
+ }, null, 2));
3225
+ }
3226
+ catch (err) {
3227
+ fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
3228
+ }
3229
+ });
3118
3230
  addBundledAudit(world, {
3119
3231
  name: 'audit',
3120
3232
  description: 'Run the blocking composition, bundle-budget, loader, and provenance audit',