@helix3/helix-cli 0.1.18-helix3.255 → 0.1.18-helix3.256
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 +116 -6
- package/dist/index.js.map +1 -1
- package/dist/looks.d.ts +101 -0
- package/dist/looks.js +102 -0
- package/dist/looks.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/vault.d.ts +121 -0
- package/dist/vault.js +136 -0
- package/dist/vault.js.map +1 -0
- package/package.json +2 -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/dist/index.js
CHANGED
|
@@ -47,6 +47,8 @@ const scenePerformance_1 = require("./scenePerformance");
|
|
|
47
47
|
const lib_1 = require("./lib");
|
|
48
48
|
const itemQuote_1 = require("./itemQuote");
|
|
49
49
|
const itemSearch_1 = require("./itemSearch");
|
|
50
|
+
const vault_1 = require("./vault");
|
|
51
|
+
const looks_1 = require("./looks");
|
|
50
52
|
const tables_1 = require("./itemDef/tables");
|
|
51
53
|
const emoteRules_1 = require("./itemDef/emoteRules");
|
|
52
54
|
const scaffold_1 = require("./itemDef/scaffold");
|
|
@@ -1210,14 +1212,14 @@ item
|
|
|
1210
1212
|
// list it is always read with. `--gender`'s own help carries the same values.
|
|
1211
1213
|
item
|
|
1212
1214
|
.command('search')
|
|
1213
|
-
.description(
|
|
1215
|
+
.description("Search the published MARKETPLACE catalogue — including Looks (user-facing name for a `build`: a free, never-owned preset), the dressed presets someone already assembled. A Look is never owned itself; its parts are acquired individually from their own listings")
|
|
1214
1216
|
.argument('[query]', 'free text over title, slug and tags')
|
|
1215
1217
|
.option('--kind <kind>', 'universal item kind (avatar, wearable, vehicle, weapon, add_on, home_item, emote, prop)')
|
|
1216
1218
|
.option('--category <category>', 'marketplace category')
|
|
1217
1219
|
.option('--sub-category <subCategory>', 'form factor beneath the category, e.g. car / rifle / art')
|
|
1218
1220
|
.option('--tag <tag>', 'exact tag')
|
|
1219
1221
|
.option('--host-kind <hostKind>', 'host class, e.g. vehicle / character / weapon')
|
|
1220
|
-
.option('--builds <mode>', `builds in the results: ${itemSearch_1.BUILD_FILTER_MODES.join(' | ')} (default include — a
|
|
1222
|
+
.option('--builds <mode>', `Looks (API identifier: builds) in the results: ${itemSearch_1.BUILD_FILTER_MODES.join(' | ')} (default include — a Look is filed under its base's own category, so it comes back alongside bases unless you narrow)`)
|
|
1221
1223
|
.option('--limit <n>', 'rows to return (1-100, default 20)')
|
|
1222
1224
|
.option('--json', 'machine-readable output')
|
|
1223
1225
|
.action(async (query, opts) => {
|
|
@@ -1243,11 +1245,12 @@ item
|
|
|
1243
1245
|
return;
|
|
1244
1246
|
}
|
|
1245
1247
|
for (const row of result.items) {
|
|
1246
|
-
// The
|
|
1248
|
+
// The Look mark leads the line (`buildKind` is the field's API name;
|
|
1249
|
+
// "Look" is what a human reads). A Look is filed under its base's
|
|
1247
1250
|
// own kind, so without it these rows are indistinguishable from the
|
|
1248
|
-
// bases they were assembled from — which is the whole reason
|
|
1251
|
+
// bases they were assembled from — which is the whole reason Looks
|
|
1249
1252
|
// do not get a category of their own.
|
|
1250
|
-
const mark = row.buildKind ? `[
|
|
1253
|
+
const mark = row.buildKind ? `[look:${row.buildKind}] ` : '';
|
|
1251
1254
|
const price = row.priceLix === null ? 'unlisted' : `Ⱡ${row.priceLix}`;
|
|
1252
1255
|
console.log(`${mark}${row.title} (${row.kind}, ${price})`);
|
|
1253
1256
|
console.log(` ${row.id}${row.creator ? ` by ${row.creator}` : ''}`);
|
|
@@ -1262,7 +1265,7 @@ item
|
|
|
1262
1265
|
});
|
|
1263
1266
|
item
|
|
1264
1267
|
.command('build')
|
|
1265
|
-
.description("What is in a published build: its base, its parts, what you own, and what the parts cost together")
|
|
1268
|
+
.description("What is in a published Look (API identifier: build): its base, its add-on parts, what you own, and what the parts cost together. A Look is never owned itself — only its parts are, each bought or held from its own listing")
|
|
1266
1269
|
.argument('<itemId>', 'universal item id of the build')
|
|
1267
1270
|
.option('--json', 'machine-readable output')
|
|
1268
1271
|
.action(async (itemId, opts) => {
|
|
@@ -2161,6 +2164,113 @@ product
|
|
|
2161
2164
|
fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
2162
2165
|
}
|
|
2163
2166
|
});
|
|
2167
|
+
// --- helix vault -------------------------------------------------------------
|
|
2168
|
+
// The Continuum Vault catalog (`GET /api/v1/vault/catalog`) — the table that
|
|
2169
|
+
// backs the website's Vault page and actually lists Looks (build Packages),
|
|
2170
|
+
// characters, vehicles, weapons, devices, and every other sealed Continuum
|
|
2171
|
+
// Package. Distinct from `helix assets search`, which hits the LEGACY
|
|
2172
|
+
// `/api/v1/vault/assets` table and has no Looks and never will.
|
|
2173
|
+
const vault = program
|
|
2174
|
+
.command('vault')
|
|
2175
|
+
.description('Discover sealed Continuum Packages — including Looks — through the public Vault catalog');
|
|
2176
|
+
vault
|
|
2177
|
+
.command('search')
|
|
2178
|
+
.description('Search the Continuum Vault catalog. Finds Looks (pass --package-type look) and every other sealed, listed Continuum Package. Public — no login required')
|
|
2179
|
+
.argument('[query]', 'free-text search over title and tags')
|
|
2180
|
+
.option('--package-type <type>', `filter by Continuum Package type. "look" is accepted as an alias for "build" (${vault_1.VAULT_CATALOG_PACKAGE_TYPE_INPUTS.join(', ')})`)
|
|
2181
|
+
.option('--sort <mode>', 'recent or name')
|
|
2182
|
+
.option('--cursor <token>', 'pagination cursor from a previous nextCursor')
|
|
2183
|
+
.option('--limit <n>', 'page size (1-100)')
|
|
2184
|
+
.action(async (query, opts) => {
|
|
2185
|
+
const creds = (0, config_1.loadCredentials)();
|
|
2186
|
+
const apiUrl = creds?.apiUrl ?? config_1.DEFAULT_API_URL;
|
|
2187
|
+
if (opts.sort && !['recent', 'name'].includes(opts.sort)) {
|
|
2188
|
+
fail('✖ --sort must be recent or name');
|
|
2189
|
+
}
|
|
2190
|
+
try {
|
|
2191
|
+
printJson(await (0, vault_1.searchVaultCatalog)(apiUrl, {
|
|
2192
|
+
q: query,
|
|
2193
|
+
packageType: opts.packageType,
|
|
2194
|
+
sort: opts.sort,
|
|
2195
|
+
cursor: opts.cursor,
|
|
2196
|
+
limit: optionalNumber(opts.limit, '--limit'),
|
|
2197
|
+
}, creds ?? undefined));
|
|
2198
|
+
}
|
|
2199
|
+
catch (err) {
|
|
2200
|
+
fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
2201
|
+
}
|
|
2202
|
+
});
|
|
2203
|
+
// --- helix look --------------------------------------------------------------
|
|
2204
|
+
// A Look is a Universal Item pinned to a Continuum Package of type `build`: a
|
|
2205
|
+
// free, never-owned preset — a base plus the exact add-ons installed on it.
|
|
2206
|
+
// Its parts are still owned and acquired individually from their own listings;
|
|
2207
|
+
// applying a Look never grants, buys, or moves anything the caller does not
|
|
2208
|
+
// already own. Contract: run/open-alpha-qa/looks/phase2-contract.txt (items 4
|
|
2209
|
+
// and 6) in the workspace root.
|
|
2210
|
+
const look = program
|
|
2211
|
+
.command('look')
|
|
2212
|
+
.description('Read and save Looks — dressed-character presets (API identifier: build)');
|
|
2213
|
+
look
|
|
2214
|
+
.command('get')
|
|
2215
|
+
.description('The dressed character behind one Look in a single public call: base model plus every add-on, with pinned Packages, model URLs/CIDs, and fit data — enough to render it')
|
|
2216
|
+
.argument('<ref>', 'Look item id, or packageId@version (an @ splits packageId from an explicit version; without one, the value is read as an item id)')
|
|
2217
|
+
.option('--json', 'machine-readable output')
|
|
2218
|
+
.action(async (ref, opts) => {
|
|
2219
|
+
const creds = (0, config_1.loadCredentials)();
|
|
2220
|
+
const apiUrl = creds?.apiUrl ?? config_1.DEFAULT_API_URL;
|
|
2221
|
+
const api = creds ? lib_1.HelixApi.forCredentials(creds) : new lib_1.HelixApi(apiUrl);
|
|
2222
|
+
try {
|
|
2223
|
+
const result = await (0, looks_1.resolveLook)(api, (0, looks_1.parseLookRef)(ref));
|
|
2224
|
+
if (opts.json)
|
|
2225
|
+
return printJson(result);
|
|
2226
|
+
console.log(`${result.look.title ?? result.look.packageId} (${result.look.kind})`);
|
|
2227
|
+
console.log(` base: ${result.base.item?.title ?? result.base.package.packageId}`);
|
|
2228
|
+
if (result.base.model)
|
|
2229
|
+
console.log(` ${result.base.model.url}`);
|
|
2230
|
+
for (const addOn of result.addOns) {
|
|
2231
|
+
console.log(` + [${addOn.slot}] ${addOn.item?.title ?? addOn.package.packageId}`);
|
|
2232
|
+
if (addOn.model)
|
|
2233
|
+
console.log(` ${addOn.model.url}`);
|
|
2234
|
+
}
|
|
2235
|
+
console.log(result.merged
|
|
2236
|
+
? `\nmerged Runtime Artifact: ${result.merged.url}`
|
|
2237
|
+
: '\nno merged Runtime Artifact yet — assemble base + add-ons at runtime');
|
|
2238
|
+
}
|
|
2239
|
+
catch (err) {
|
|
2240
|
+
fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
2241
|
+
}
|
|
2242
|
+
});
|
|
2243
|
+
look
|
|
2244
|
+
.command('save')
|
|
2245
|
+
.description("Freeze an inventory instance's current composition into a Look. Never charges a publish fee, never grants a copy of any part, never creates a distribution — it publishes the recipe, not the parts")
|
|
2246
|
+
.argument('<inventory-item-id>', 'inventory instance to freeze')
|
|
2247
|
+
.requiredOption('--title <title>', 'Look title (1-80 chars)')
|
|
2248
|
+
.option('--description <text>', 'Look description (<=500 chars)')
|
|
2249
|
+
.option('--public', 'publish publicly (sealed public Package + Vault + Marketplace listings); default is private')
|
|
2250
|
+
.option('--look <lookItemId>', 'an existing Look you created — advances it to a new version instead of creating a new one')
|
|
2251
|
+
.option('--json', 'machine-readable output')
|
|
2252
|
+
.action(async (inventoryItemId, opts) => {
|
|
2253
|
+
const creds = requireAuth();
|
|
2254
|
+
try {
|
|
2255
|
+
const result = await (0, looks_1.saveLook)(lib_1.HelixApi.forCredentials(creds), inventoryItemId, {
|
|
2256
|
+
title: opts.title,
|
|
2257
|
+
description: opts.description,
|
|
2258
|
+
visibility: opts.public ? 'public' : 'private',
|
|
2259
|
+
lookItemId: opts.look,
|
|
2260
|
+
});
|
|
2261
|
+
if (opts.json)
|
|
2262
|
+
return printJson(result);
|
|
2263
|
+
console.log(`✔ ${result.created ? 'Saved' : 'Updated'} Look ${result.lookItemId} (${result.visibility})`);
|
|
2264
|
+
console.log(` package: ${result.package.packageId}@${result.package.version}`);
|
|
2265
|
+
if (result.vaultListingId)
|
|
2266
|
+
console.log(` vault listing: ${result.vaultListingId}`);
|
|
2267
|
+
if (result.marketplaceListingId)
|
|
2268
|
+
console.log(` marketplace listing: ${result.marketplaceListingId}`);
|
|
2269
|
+
}
|
|
2270
|
+
catch (err) {
|
|
2271
|
+
fail(err instanceof lib_1.ApiError ? err.render() : `✖ ${err instanceof Error ? err.message : String(err)}`);
|
|
2272
|
+
}
|
|
2273
|
+
});
|
|
2164
2274
|
// --- helix assets ----------------------------------------------------------
|
|
2165
2275
|
// Operational asset work lives here. MCP surfaces may point agents at these
|
|
2166
2276
|
// commands, but they must not reimplement Vault, Dreamer, download, or receipt
|