@helix3/helix-cli 0.1.13-helix3.92 → 0.1.13-helix3.96

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 (76) hide show
  1. package/assets/item-def-sounds/Common/A_DryShot.ogg +0 -0
  2. package/assets/item-def-sounds/Common/A_LMG_CloseCoverA.ogg +0 -0
  3. package/assets/item-def-sounds/Common/A_LMG_CloseCoverB.ogg +0 -0
  4. package/assets/item-def-sounds/Common/A_LMG_InsertMag.ogg +0 -0
  5. package/assets/item-def-sounds/Common/A_LMG_RemoveMag.ogg +0 -0
  6. package/assets/item-def-sounds/Common/A_Pistol_InsertMag_001.ogg +0 -0
  7. package/assets/item-def-sounds/Common/A_Pistol_InsertMag_002.ogg +0 -0
  8. package/assets/item-def-sounds/Common/A_Pistol_InsertMag_003.ogg +0 -0
  9. package/assets/item-def-sounds/Common/A_Pistol_RemoveMag_001.ogg +0 -0
  10. package/assets/item-def-sounds/Common/A_Pistol_RemoveMag_002.ogg +0 -0
  11. package/assets/item-def-sounds/Common/A_Pistol_RemoveMag_003.ogg +0 -0
  12. package/assets/item-def-sounds/Common/A_Rifle_ChargingHandle_001.ogg +0 -0
  13. package/assets/item-def-sounds/Common/A_Rifle_ChargingHandle_002.ogg +0 -0
  14. package/assets/item-def-sounds/Common/A_Rifle_ChargingHandle_003.ogg +0 -0
  15. package/assets/item-def-sounds/Common/A_Rifle_InsertMag_001.ogg +0 -0
  16. package/assets/item-def-sounds/Common/A_Rifle_InsertMag_002.ogg +0 -0
  17. package/assets/item-def-sounds/Common/A_Rifle_InsertMag_003.ogg +0 -0
  18. package/assets/item-def-sounds/Common/A_Rifle_RemoveMag_001.ogg +0 -0
  19. package/assets/item-def-sounds/Common/A_Rifle_RemoveMag_002.ogg +0 -0
  20. package/assets/item-def-sounds/Common/A_Rifle_RemoveMag_003.ogg +0 -0
  21. package/assets/item-def-sounds/Common/A_SMG_ChargingHandle_001.ogg +0 -0
  22. package/assets/item-def-sounds/Common/A_SMG_ChargingHandle_002.ogg +0 -0
  23. package/assets/item-def-sounds/Common/A_SMG_ChargingHandle_003.ogg +0 -0
  24. package/assets/item-def-sounds/Common/A_Sniper_ChargingHandle.ogg +0 -0
  25. package/assets/item-def-sounds/Common/A_Sniper_RemoveMag_001.ogg +0 -0
  26. package/assets/item-def-sounds/Common/A_Sniper_RemoveMag_002.ogg +0 -0
  27. package/assets/item-def-sounds/Common/A_Sniper_RemoveMag_003.ogg +0 -0
  28. package/assets/item-def-sounds/LMG/A_LWS-32_Shot_001.ogg +0 -0
  29. package/assets/item-def-sounds/LMG/A_LWS-32_Shot_002.ogg +0 -0
  30. package/assets/item-def-sounds/LMG/A_LWS-32_Shot_003.ogg +0 -0
  31. package/assets/item-def-sounds/Pistol/A_Gaston_Shot_001.ogg +0 -0
  32. package/assets/item-def-sounds/Pistol/A_Gaston_Shot_002.ogg +0 -0
  33. package/assets/item-def-sounds/Pistol/A_Gaston_Shot_003.ogg +0 -0
  34. package/assets/item-def-sounds/Rifle/A_KAL_Shot_001.ogg +0 -0
  35. package/assets/item-def-sounds/Rifle/A_KAL_Shot_002.ogg +0 -0
  36. package/assets/item-def-sounds/Rifle/A_KAL_Shot_003.ogg +0 -0
  37. package/assets/item-def-sounds/SMG/A_Bison_InsertMag.ogg +0 -0
  38. package/assets/item-def-sounds/SMG/A_Bison_RemoveMag.ogg +0 -0
  39. package/assets/item-def-sounds/SMG/A_Bison_Shot_001.ogg +0 -0
  40. package/assets/item-def-sounds/SMG/A_Bison_Shot_002.ogg +0 -0
  41. package/assets/item-def-sounds/SMG/A_Bison_Shot_003.ogg +0 -0
  42. package/assets/item-def-sounds/Shotgun/A_DB-12_Shot_001.ogg +0 -0
  43. package/assets/item-def-sounds/Shotgun/A_DB-12_Shot_002.ogg +0 -0
  44. package/assets/item-def-sounds/Shotgun/A_DB-12_Shot_003.ogg +0 -0
  45. package/assets/item-def-sounds/Sniper/A_CS-446_Shot_001.ogg +0 -0
  46. package/assets/item-def-sounds/Sniper/A_CS-446_Shot_002.ogg +0 -0
  47. package/assets/item-def-sounds/Sniper/A_CS-446_Shot_003.ogg +0 -0
  48. package/dist/index.js +140 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/itemDef/gunConfigRules.d.ts +24 -0
  51. package/dist/itemDef/gunConfigRules.js +244 -0
  52. package/dist/itemDef/gunConfigRules.js.map +1 -0
  53. package/dist/itemDef/inspect.d.ts +17 -0
  54. package/dist/itemDef/inspect.js +118 -0
  55. package/dist/itemDef/inspect.js.map +1 -0
  56. package/dist/itemDef/publish.d.ts +33 -0
  57. package/dist/itemDef/publish.js +131 -0
  58. package/dist/itemDef/publish.js.map +1 -0
  59. package/dist/itemDef/scaffold.d.ts +28 -0
  60. package/dist/itemDef/scaffold.js +165 -0
  61. package/dist/itemDef/scaffold.js.map +1 -0
  62. package/dist/itemDef/tables.d.ts +56 -0
  63. package/dist/itemDef/tables.js +169 -0
  64. package/dist/itemDef/tables.js.map +1 -0
  65. package/dist/itemDef/validate.d.ts +16 -0
  66. package/dist/itemDef/validate.js +93 -0
  67. package/dist/itemDef/validate.js.map +1 -0
  68. package/dist/lib.d.ts +25 -0
  69. package/dist/lib.js +16 -0
  70. package/dist/lib.js.map +1 -1
  71. package/dist/tsconfig.build.tsbuildinfo +1 -1
  72. package/dist/world/baseline.js +7 -0
  73. package/dist/world/baseline.js.map +1 -1
  74. package/package.json +4 -3
  75. package/vendor/ability-manifest.mjs +4 -4
  76. package/vendor/installed-index.mjs +1 -1
package/dist/index.js CHANGED
@@ -694,6 +694,39 @@ item
694
694
  : `✖ ${err instanceof Error ? err.message : String(err)}`);
695
695
  }
696
696
  });
697
+ // `delete` is a dead end once anyone owns an instance — and a publish always
698
+ // self-grants the creator one — so the server refuses it with "Delist or
699
+ // suspend it instead." (CH-1669). This is the "instead": a creator-owned,
700
+ // non-destructive unlist. Existing owners keep their copies; the item stops
701
+ // appearing on browse/marketplace and can no longer be newly acquired. It is
702
+ // NOT a delete and NOT reversible from the CLI today — there is no `relist`.
703
+ // Distinct from `item distribution disable` below: a distribution is ONE
704
+ // acquisition route (you can have several); delist takes the whole item
705
+ // definition off browse/marketplace regardless of how many routes it has.
706
+ item
707
+ .command('delist')
708
+ .description('Unlist a published item you own — existing owners keep what they own, nobody new can acquire it. Not a delete (see `helix item publish` for why delete refuses an owned item), and not currently reversible.')
709
+ .argument('<item-id>', 'the universal item id (printed by `helix item publish`, or from the item URL/API)')
710
+ .option('--reason <text>', 'optional note for your own record; not shown to anyone else')
711
+ .option('--json', 'machine-readable output')
712
+ .action(async (itemId, opts) => {
713
+ const creds = requireAuth();
714
+ try {
715
+ const result = await (0, lib_1.delistItem)(itemId, creds, { reason: opts.reason });
716
+ if (opts.json) {
717
+ console.log(JSON.stringify(result, null, 2));
718
+ return;
719
+ }
720
+ console.log(`✔ Delisted "${result.title}" (${result.slug})`);
721
+ console.log(` status: ${result.status}`);
722
+ console.log(' existing owners keep their copies; nobody new can acquire it.');
723
+ }
724
+ catch (err) {
725
+ fail(err instanceof lib_1.ApiError
726
+ ? err.render()
727
+ : `✖ ${err instanceof Error ? err.message : String(err)}`);
728
+ }
729
+ });
697
730
  const itemDistribution = item
698
731
  .command('distribution')
699
732
  .description('Create and manage primary Claim/Buy routes for one published item definition');
@@ -2633,6 +2666,113 @@ gesture
2633
2666
  fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
2634
2667
  }
2635
2668
  });
2669
+ const itemDef = program
2670
+ .command('item-def')
2671
+ .description('Interactive weapon definitions — scaffold a complete descriptor from a mesh + category, validate it offline, publish it to the Vault, and inspect a published one');
2672
+ itemDef
2673
+ .command('scaffold')
2674
+ .description('Emit a complete, publishable weapon descriptor: category archetype + engine spread/reload tables resolved in, default (or your own) sounds copied next to it')
2675
+ .requiredOption('--mesh <file.glb>', 'the prop mesh (grip at origin, +y up, +z out the barrel, meters)')
2676
+ .requiredOption('--category <category>', 'Rifle | Pistol | SMG | Shotgun | Sniper | LMG — inherits spread, reload foley, grip preset and shell class')
2677
+ .option('--sounds <dir>', 'directory of your own .ogg shot sounds (mono opus-in-ogg; a file named *dry* becomes the dry-fire click)')
2678
+ .option('--title <name>', 'item title, also the source of the item id (default: the mesh basename)')
2679
+ .option('--out <dir>', 'output directory for the descriptor + copied files', '.')
2680
+ .action(async (opts) => {
2681
+ try {
2682
+ const { scaffoldItemDef } = await Promise.resolve().then(() => __importStar(require('./itemDef/scaffold')));
2683
+ const result = scaffoldItemDef({
2684
+ mesh: opts.mesh,
2685
+ category: opts.category,
2686
+ ...(opts.sounds !== undefined && { sounds: opts.sounds }),
2687
+ ...(opts.title !== undefined && { title: opts.title }),
2688
+ out: opts.out,
2689
+ });
2690
+ console.log(`✔ ${result.descriptorPath}`);
2691
+ console.log(` ${result.copiedSounds.length} sound file(s) copied into sounds/`);
2692
+ if (result.warnings.length > 0)
2693
+ console.log(`warnings:\n ${result.warnings.join('\n ')}`);
2694
+ console.log(`next steps:\n ${result.nextSteps.join('\n ')}`);
2695
+ }
2696
+ catch (err) {
2697
+ fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
2698
+ }
2699
+ });
2700
+ itemDef
2701
+ .command('validate')
2702
+ .description('Validate a weapon descriptor offline: the manifest authority validator, the vendored engine gun-config rules, referenced-file existence, and the mesh precheck')
2703
+ .argument('<file>', 'the .helix-interactive.json descriptor')
2704
+ .action(async (file) => {
2705
+ try {
2706
+ const { validateItemDefFile } = await Promise.resolve().then(() => __importStar(require('./itemDef/validate')));
2707
+ const result = validateItemDefFile(file);
2708
+ if (result.warnings.length > 0)
2709
+ console.log(`warnings:\n ${result.warnings.join('\n ')}`);
2710
+ if (result.errors.length > 0) {
2711
+ fail(`✖ ${result.errors.length} error(s):\n - ${result.errors.join('\n - ')}`);
2712
+ }
2713
+ console.log(`✔ valid — ${result.relativeRefs.length} referenced file(s) present`);
2714
+ }
2715
+ catch (err) {
2716
+ fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
2717
+ }
2718
+ });
2719
+ itemDef
2720
+ .command('publish')
2721
+ .description('Publish a weapon definition: upload the mesh + every referenced sound, rewrite sound paths to vault: refs, publish the descriptor, link the product')
2722
+ .argument('<file>', 'the .helix-interactive.json descriptor')
2723
+ .option('--slug <slug>', 'product slug, unique platform-wide (default: weapon-<id>; reruns need a fresh one)')
2724
+ .option('--keep-personal', 'keep the product off the marketplace and out of the publish fee; the link still grants you an instance')
2725
+ .action(async (file, opts) => {
2726
+ const creds = requireAuth();
2727
+ const mismatch = (0, config_1.credsEnvMismatchWarning)(creds.apiUrl);
2728
+ if (mismatch)
2729
+ console.log(mismatch);
2730
+ try {
2731
+ const { publishItemDef } = await Promise.resolve().then(() => __importStar(require('./itemDef/publish')));
2732
+ if (opts.keepPersonal !== true) {
2733
+ console.log('note: a marketplace product link can charge a publish fee — pass --keep-personal for a fee-free personal publish.');
2734
+ }
2735
+ const report = await publishItemDef(lib_1.HelixApi.forCredentials(creds), {
2736
+ file,
2737
+ ...(opts.slug !== undefined && { slug: opts.slug }),
2738
+ keepPersonal: opts.keepPersonal === true,
2739
+ });
2740
+ console.log(`✔ ${report.title} — definition ${report.definition.assetId}@${report.definition.version}`);
2741
+ console.log(` prop ${report.prop.assetId}@${report.prop.version} · ${report.audio.length} audio upload(s) · product slug ${report.product.slug}`);
2742
+ if (report.warnings.length > 0)
2743
+ console.log(`warnings:\n ${report.warnings.join('\n ')}`);
2744
+ }
2745
+ catch (err) {
2746
+ fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
2747
+ }
2748
+ });
2749
+ itemDef
2750
+ .command('inspect')
2751
+ .description('Resolve a published weapon definition and print the numbers an author tunes against')
2752
+ .argument('<asset-ref>', 'definition assetId, optionally @version (e.g. abc123@2)')
2753
+ .option('--json', 'machine-readable output (the raw descriptor + resolve metadata)')
2754
+ .action(async (ref, opts) => {
2755
+ const creds = (0, config_1.loadCredentials)();
2756
+ const apiUrl = creds?.apiUrl ?? config_1.DEFAULT_API_URL;
2757
+ try {
2758
+ const { inspectItemDef, formatItemDefInspect } = await Promise.resolve().then(() => __importStar(require('./itemDef/inspect')));
2759
+ const fetchText = async (url) => {
2760
+ const res = await fetch(url);
2761
+ if (!res.ok)
2762
+ throw new Error(`HTTP ${res.status}`);
2763
+ return res.text();
2764
+ };
2765
+ const api = creds ? lib_1.HelixApi.forCredentials(creds) : new lib_1.HelixApi(apiUrl);
2766
+ const result = await inspectItemDef(api, fetchText, ref);
2767
+ if (opts.json)
2768
+ console.log(JSON.stringify(result, null, 2));
2769
+ else
2770
+ console.log(formatItemDefInspect(result));
2771
+ }
2772
+ catch (err) {
2773
+ fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
2774
+ }
2775
+ });
2636
2776
  const world = program
2637
2777
  .command('world')
2638
2778
  .description("World tools — create the world's identity before publishing, and measure a built world's geometry as data instead of eyeballing screenshots");