@helix3/helix-cli 0.1.13-helix3.126 → 0.1.13-helix3.128

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/index.js CHANGED
@@ -1667,6 +1667,61 @@ function printMaterialHuman(material) {
1667
1667
  console.log(` ${role}: ${url}`);
1668
1668
  }
1669
1669
  }
1670
+ // `helix assets publish <file>` — the verb that was missing.
1671
+ //
1672
+ // `POST /api/v1/vault/assets` has always accepted a plain file, but the only CLI
1673
+ // caller was `helix item-def publish`, which demands a weapon or emote
1674
+ // descriptor. So a finished .glb on disk could reach the Vault only by being
1675
+ // GENERATED through Dreamer or by being filed as a weapon it is not. This puts
1676
+ // the file in, and stops there: no descriptor, no product, no listing — those
1677
+ // stay separate decisions.
1678
+ assets
1679
+ .command('publish')
1680
+ .description('Publish a file you already have as a HELIX Vault asset')
1681
+ .argument('<file>', 'the file to upload (.glb, .wav/.mp3/.ogg, .png/.jpg/.webp/.ktx2, .spz)')
1682
+ .option('--kind <kind>', `Vault kind — inferred from the extension when omitted (${lib_1.VAULT_ASSET_KINDS.join(', ')})`)
1683
+ .option('--title <text>', 'human title (default: the filename without its extension)')
1684
+ .option('--description <text>', 'what this asset is')
1685
+ .option('--tags <a,b>', 'comma-separated tags')
1686
+ .option('--private', 'keep it out of Vault search — only you can reference it')
1687
+ .option('--human', 'readable summary instead of JSON')
1688
+ .action(async (file, opts) => {
1689
+ const creds = requireAuth();
1690
+ try {
1691
+ const { publishVaultAsset } = await Promise.resolve().then(() => __importStar(require('./vaultPublish')));
1692
+ const path = (0, node_path_1.resolve)(file);
1693
+ if (!(0, node_fs_1.existsSync)(path))
1694
+ fail(`✖ no such file: ${file}`);
1695
+ const bytes = (0, node_fs_1.readFileSync)(path);
1696
+ const result = await publishVaultAsset(lib_1.HelixApi.forCredentials(creds), {
1697
+ bytes,
1698
+ filename: (0, node_path_1.basename)(path),
1699
+ ...(opts.kind !== undefined && { kind: opts.kind }),
1700
+ ...(opts.title !== undefined && { title: opts.title }),
1701
+ ...(opts.description !== undefined && { description: opts.description }),
1702
+ ...(opts.tags !== undefined && { tags: opts.tags.split(',') }),
1703
+ ...(opts.private === true && { visibility: 'private' }),
1704
+ });
1705
+ if (opts.human) {
1706
+ console.log(`✔ ${result.assetId} v${result.artifact.version}`);
1707
+ // A HELD publish gets no URL — the moderation gate is holding the
1708
+ // bytes for a human, and saying so beats printing `null`.
1709
+ if (result.visibility === 'held') {
1710
+ console.log(' held for review — it serves once a human approves it');
1711
+ }
1712
+ else if (result.artifact.url) {
1713
+ console.log(` ${result.artifact.url}`);
1714
+ }
1715
+ console.log(` reference it as: vault:${result.assetId}`);
1716
+ }
1717
+ else {
1718
+ printJson(result);
1719
+ }
1720
+ }
1721
+ catch (err) {
1722
+ fail(`✖ ${err instanceof Error ? err.message : String(err)}`);
1723
+ }
1724
+ });
1670
1725
  assets
1671
1726
  .command('materials')
1672
1727
  .description('Search the versioned HELIX material catalog')