@helix3/helix-cli 0.1.18-helix3.355 → 0.1.18-helix3.357

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 (39) hide show
  1. package/README.md +2 -0
  2. package/dist/avatarMeshReplacement.d.ts +3 -0
  3. package/dist/avatarMeshReplacement.js +9 -0
  4. package/dist/avatarMeshReplacement.js.map +1 -1
  5. package/dist/index.js +46 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/itemThumbnail.d.ts +40 -0
  8. package/dist/itemThumbnail.js +116 -0
  9. package/dist/itemThumbnail.js.map +1 -0
  10. package/dist/lib.d.ts +1 -0
  11. package/dist/lib.js +8 -1
  12. package/dist/lib.js.map +1 -1
  13. package/dist/tsconfig.build.tsbuildinfo +1 -1
  14. package/dist/visualQa/avatar.d.ts +1 -1
  15. package/dist/visualQa/avatar.js +116 -3
  16. package/dist/visualQa/avatar.js.map +1 -1
  17. package/dist/visualQa/avatarMath.d.ts +122 -0
  18. package/dist/visualQa/avatarMath.js +204 -1
  19. package/dist/visualQa/avatarMath.js.map +1 -1
  20. package/dist/visualQa/avatarProbe.d.ts +1 -1
  21. package/dist/visualQa/avatarProbe.js +151 -0
  22. package/dist/visualQa/avatarProbe.js.map +1 -1
  23. package/dist/visualQa/browser.d.ts +10 -0
  24. package/dist/visualQa/browser.js +35 -4
  25. package/dist/visualQa/browser.js.map +1 -1
  26. package/dist/visualQa/checklists.js +12 -1
  27. package/dist/visualQa/checklists.js.map +1 -1
  28. package/dist/visualQa/command.d.ts +2 -0
  29. package/dist/visualQa/command.js +30 -0
  30. package/dist/visualQa/command.js.map +1 -1
  31. package/dist/visualQa/harness.d.ts +3 -0
  32. package/dist/visualQa/resolve.js +12 -2
  33. package/dist/visualQa/resolve.js.map +1 -1
  34. package/package.json +1 -1
  35. package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
  36. package/plugins/beamng-vehicle/bin/__pycache__/beamng_audio.cpython-312.pyc +0 -0
  37. package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
  38. package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
  39. package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
package/README.md CHANGED
@@ -56,6 +56,8 @@ The token is stored in `~/.helix/credentials.json` (mode `600`). It's sent as
56
56
  | `helix item visual-qa <item-id> [--submit] [--local-critic] [--storage-state <file>] [--host <id…>]` | Render the item's current package version headless in the real runtime (test-grounds world for vehicles and whole avatars, the customiser for add-ons and wearables on every declared host/base, the item viewer for props), measure it, and with `--submit` record the backend's verdict (numeric asserts + vision critic) against that exact version. **Marketplace/Vault listing, distributions and version moves on a public item require a pass.** See [docs/visual-qa.md](docs/visual-qa.md). |
57
57
  | `helix item visual-qa <item-id> --package-version <v> [--vehicle-package <file>]` | Render a version the item is **not pinned to yet**, so a refused version move can pass the gate before the pointer moves. Vehicles and avatars go through Try Now (vehicles also need the move's vehicle package), add-ons and wearables through the customiser; the bundle names the candidate, and the vehicle checksum is the one the server minted for that trial. Never falls back to the current version. See [docs/visual-qa-candidate-versions.md](docs/visual-qa-candidate-versions.md). With `--submit`, a PASS prints the next command (`helix item set-version …`); a 403 for a non-creator says so on the first line; `--status` also lists the item's pending (sealed, not current) versions. |
58
58
  | `helix item set-version <item-id> --package-version <v> --reason <text> [--vehicle-package <file>] [--expected-current-version-id <uuid>] [--json]` | Move an item to a sealed Package Version of its own package (pin resolved from the public Package API; `POST /api/v1/universal-items/<id>/versions`). The flow for a **listed** item: `item publish-version` seals vN and the move is refused → `item visual-qa <id> --package-version vN --submit` → `item set-version`. A refusal prints the server's message first (it names the next command), then the remedy and any hosted render it queued. An unknown version lists the sealed ones. |
59
+ | `helix item thumbnail refresh <item-id> [--force] [--dry-run] [--json]` | Re-render a published item's canonical thumbnail from its **active Package Version** with the standard server renderer (`POST /api/v1/universal-items/<id>/thumbnail/regenerate`, owner or admin). Prints the status (`generated` / `current` / `dry-run`), old -> new thumbnail URL, renderer version and the source lane + Package Version. `--dry-run` writes nothing; `--force` re-renders even when the stored thumbnail is current. Moving an item to a new Package Version now refreshes the thumbnail automatically unless you uploaded one. An older backend answers 404 and the CLI says it does not support thumbnail refresh yet. Not the world `helix thumbnail set <slug>` command. |
60
+ | `helix item thumbnail set <item-id> <image> [--json]` | Upload your own thumbnail (png/jpg/webp, up to 10 MiB, checked locally) for a published item (`PUT /api/v1/universal-items/<id>/thumbnail`, moderated). A creator upload stays in place across version moves until you run `thumbnail refresh --force`. 403 = you are not the item's owner. |
59
61
  | `helix device create <dir> --id <slug> --title <t> --model <mesh.glb> --template standing-desk\|clock\|television` | Scaffold a GLB-backed `helix.device/1` definition, including the interactive TV/media-player template. There is intentionally no website Device editor. |
60
62
  | `helix device validate [dir] [--json]` | Validate the definition, GLB bytes and named-node bindings, typed state/controls, capabilities, and Home+World compatibility, including [declarative character hand reach](docs/device-hand-reach.md). |
61
63
  | `helix device test [dir] [--mode single\|multiplayer\|both] [--json]` | Exercise every interaction, persistence remount, and deterministic one-/two-client authority convergence. |
@@ -11,3 +11,6 @@ export interface AvatarMeshReplacementResult {
11
11
  }
12
12
  /** Replace a legacy avatar's presentation through backend authority, retaining its identity. */
13
13
  export declare function replaceAvatarMesh(itemId: string, file: string, expectedContentHash: string, credentials: CliCredentials): Promise<AvatarMeshReplacementResult>;
14
+ export declare const PACKAGE_VERSION_HINT: string;
15
+ /** Append the Package Version route to the server's refusal for a Package-backed avatar; other errors pass through. */
16
+ export declare function withPackageVersionHint(rendered: string): string;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PACKAGE_VERSION_HINT = void 0;
3
4
  exports.replaceAvatarMesh = replaceAvatarMesh;
5
+ exports.withPackageVersionHint = withPackageVersionHint;
4
6
  const promises_1 = require("node:fs/promises");
5
7
  const node_path_1 = require("node:path");
6
8
  const api_1 = require("./api");
@@ -24,4 +26,11 @@ async function replaceAvatarMesh(itemId, file, expectedContentHash, credentials)
24
26
  form.set('mesh', new Blob([new Uint8Array(bytes)], { type: 'model/gltf-binary' }), (0, node_path_1.basename)(file));
25
27
  return api_1.HelixApi.forCredentials(credentials).postMultipart(`/api/v1/universal-items/${itemId}/avatar/mesh`, form, AVATAR_REPLACEMENT_TIMEOUT_MS);
26
28
  }
29
+ exports.PACKAGE_VERSION_HINT = 'Package-backed avatars cannot be replaced in place: seal the correction as a new Package Version ' +
30
+ '(`helix publish-package`), move the item onto it (`helix item set-version <item-id> --package-version <v> --reason <text>`), ' +
31
+ 'then re-render the thumbnail with `helix item thumbnail refresh <item-id>` (or upload one with `helix item thumbnail set <item-id> <image>`).';
32
+ /** Append the Package Version route to the server's refusal for a Package-backed avatar; other errors pass through. */
33
+ function withPackageVersionHint(rendered) {
34
+ return /package-backed or adopted avatars/i.test(rendered) ? `${rendered}\n → ${exports.PACKAGE_VERSION_HINT}` : rendered;
35
+ }
27
36
  //# sourceMappingURL=avatarMeshReplacement.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"avatarMeshReplacement.js","sourceRoot":"","sources":["../src/avatarMeshReplacement.ts"],"names":[],"mappings":";;AAcA,8CAuBC;AArCD,+CAA4C;AAC5C,yCAAqC;AACrC,+BAAiC;AAEjC,iCAA4C;AAE5C,MAAM,6BAA6B,GAAG,OAAO,CAAC;AAO9C,gGAAgG;AACzF,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,IAAY,EACZ,mBAA2B,EAC3B,WAA2B;IAE3B,IAAI,CAAC,iEAAiE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;IAC3G,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAI,CAAC,CAAC;IACnC,IAAA,yBAAkB,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,WAAW,EAAE,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE,IAAA,oBAAQ,EAAC,IAAI,CAAC,CAAC,CAAC;IACnG,OAAO,cAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,aAAa,CACvD,2BAA2B,MAAM,cAAc,EAAE,IAAI,EAAE,6BAA6B,CACrF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"avatarMeshReplacement.js","sourceRoot":"","sources":["../src/avatarMeshReplacement.ts"],"names":[],"mappings":";;;AAcA,8CAuBC;AAQD,wDAEC;AA/CD,+CAA4C;AAC5C,yCAAqC;AACrC,+BAAiC;AAEjC,iCAA4C;AAE5C,MAAM,6BAA6B,GAAG,OAAO,CAAC;AAO9C,gGAAgG;AACzF,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,IAAY,EACZ,mBAA2B,EAC3B,WAA2B;IAE3B,IAAI,CAAC,iEAAiE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;IAC3G,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAI,CAAC,CAAC;IACnC,IAAA,yBAAkB,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,WAAW,EAAE,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE,IAAA,oBAAQ,EAAC,IAAI,CAAC,CAAC,CAAC;IACnG,OAAO,cAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,aAAa,CACvD,2BAA2B,MAAM,cAAc,EAAE,IAAI,EAAE,6BAA6B,CACrF,CAAC;AACJ,CAAC;AAEY,QAAA,oBAAoB,GAC/B,mGAAmG;IACnG,+HAA+H;IAC/H,+IAA+I,CAAC;AAElJ,uHAAuH;AACvH,SAAgB,sBAAsB,CAAC,QAAgB;IACrD,OAAO,oCAAoC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,SAAS,4BAAoB,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrH,CAAC"}
package/dist/index.js CHANGED
@@ -46,6 +46,7 @@ const commands_1 = require("./sceneHlod/commands");
46
46
  const placementRequest_1 = require("./placementRequest");
47
47
  const bundle_1 = require("./bundle");
48
48
  const avatarMeshReplacement_1 = require("./avatarMeshReplacement");
49
+ const itemThumbnail_1 = require("./itemThumbnail");
49
50
  const addOnPackageVersion_1 = require("./addOnPackageVersion");
50
51
  const node_child_process_1 = require("node:child_process");
51
52
  const node_fs_1 = require("node:fs");
@@ -1545,7 +1546,51 @@ item
1545
1546
  console.log(`✔ Corrected avatar ${result.item.id}. Existing ownership and previous rendition bytes are preserved.`);
1546
1547
  }
1547
1548
  catch (error) {
1548
- fail(error instanceof lib_1.ApiError ? error.render() : String(error));
1549
+ fail(error instanceof lib_1.ApiError ? (0, avatarMeshReplacement_1.withPackageVersionHint)(error.render()) : String(error));
1550
+ }
1551
+ });
1552
+ // Refresh or replace the thumbnail of an ALREADY-published item. Unrelated to the top-level `thumbnail` command
1553
+ // (worlds, by slug): items are addressed by UUID and the server owns the render.
1554
+ const itemThumbnail = item
1555
+ .command('thumbnail')
1556
+ .description('Refresh or replace a published item\'s thumbnail (by item UUID; for a world\'s cover use `helix thumbnail set`)');
1557
+ itemThumbnail
1558
+ .command('refresh')
1559
+ .description('Re-render the canonical thumbnail from the item\'s active Package Version with the standard server renderer (owner or admin)')
1560
+ .argument('<item-id>', 'published item UUID')
1561
+ .option('--force', 're-render even when the stored thumbnail already matches the current renderer and source')
1562
+ .option('--dry-run', 'report what would change without writing anything')
1563
+ .option('--json', 'print the authoritative server receipt')
1564
+ .action(async (itemId, opts) => {
1565
+ try {
1566
+ const result = await (0, itemThumbnail_1.refreshItemThumbnail)(itemId, { force: opts.force, dryRun: opts.dryRun }, requireAuth());
1567
+ if (opts.json)
1568
+ console.log(JSON.stringify(result, null, 2));
1569
+ else
1570
+ for (const line of (0, itemThumbnail_1.renderItemThumbnailResult)(result))
1571
+ console.log(line);
1572
+ }
1573
+ catch (error) {
1574
+ fail(`✖ ${(0, itemThumbnail_1.describeThumbnailError)(error, itemId)}`);
1575
+ }
1576
+ });
1577
+ itemThumbnail
1578
+ .command('set')
1579
+ .description('Upload your own thumbnail image (png, jpg, or webp) for a published item; moderated, and it stays until you refresh with --force')
1580
+ .argument('<item-id>', 'published item UUID')
1581
+ .argument('<image>', 'png / jpg / webp file')
1582
+ .option('--json', 'print the authoritative server receipt')
1583
+ .action(async (itemId, image, opts) => {
1584
+ try {
1585
+ const result = await (0, itemThumbnail_1.setItemThumbnail)(itemId, (0, node_path_1.resolve)(image), requireAuth());
1586
+ if (opts.json)
1587
+ console.log(JSON.stringify(result, null, 2));
1588
+ else
1589
+ for (const line of (0, itemThumbnail_1.renderItemThumbnailResult)(result))
1590
+ console.log(line);
1591
+ }
1592
+ catch (error) {
1593
+ fail(`✖ ${(0, itemThumbnail_1.describeThumbnailError)(error, itemId)}`);
1549
1594
  }
1550
1595
  });
1551
1596
  // Ship a fix to an already-published item WITHOUT churning it onto a new id: