@helix3/helix-cli 0.1.4-helix3.24
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/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/ability.d.ts +73 -0
- package/dist/ability.js +120 -0
- package/dist/ability.js.map +1 -0
- package/dist/api.d.ts +24 -0
- package/dist/api.js +83 -0
- package/dist/api.js.map +1 -0
- package/dist/browserLogin.d.ts +22 -0
- package/dist/browserLogin.js +148 -0
- package/dist/browserLogin.js.map +1 -0
- package/dist/bundle.d.ts +15 -0
- package/dist/bundle.js +98 -0
- package/dist/bundle.js.map +1 -0
- package/dist/character/canonicalSkeleton.d.ts +3 -0
- package/dist/character/canonicalSkeleton.js +23 -0
- package/dist/character/canonicalSkeleton.js.map +1 -0
- package/dist/character/canonicalSkeletonData.d.ts +6 -0
- package/dist/character/canonicalSkeletonData.js +92 -0
- package/dist/character/canonicalSkeletonData.js.map +1 -0
- package/dist/character/esm.d.ts +1 -0
- package/dist/character/esm.js +6 -0
- package/dist/character/esm.js.map +1 -0
- package/dist/character/importCharacter.d.ts +88 -0
- package/dist/character/importCharacter.js +293 -0
- package/dist/character/importCharacter.js.map +1 -0
- package/dist/character/mat4.d.ts +29 -0
- package/dist/character/mat4.js +103 -0
- package/dist/character/mat4.js.map +1 -0
- package/dist/character/meshyToHelixMap.d.ts +2 -0
- package/dist/character/meshyToHelixMap.js +40 -0
- package/dist/character/meshyToHelixMap.js.map +1 -0
- package/dist/character/quat.d.ts +15 -0
- package/dist/character/quat.js +137 -0
- package/dist/character/quat.js.map +1 -0
- package/dist/character/stages/bakeTexture.d.ts +20 -0
- package/dist/character/stages/bakeTexture.js +396 -0
- package/dist/character/stages/bakeTexture.js.map +1 -0
- package/dist/character/stages/conform.d.ts +56 -0
- package/dist/character/stages/conform.js +292 -0
- package/dist/character/stages/conform.js.map +1 -0
- package/dist/character/stages/ktx2.d.ts +22 -0
- package/dist/character/stages/ktx2.js +97 -0
- package/dist/character/stages/ktx2.js.map +1 -0
- package/dist/character/stages/mergeLods.d.ts +15 -0
- package/dist/character/stages/mergeLods.js +42 -0
- package/dist/character/stages/mergeLods.js.map +1 -0
- package/dist/character/stages/report.d.ts +2 -0
- package/dist/character/stages/report.js +19 -0
- package/dist/character/stages/report.js.map +1 -0
- package/dist/character/stages/resizeTextures.d.ts +11 -0
- package/dist/character/stages/resizeTextures.js +62 -0
- package/dist/character/stages/resizeTextures.js.map +1 -0
- package/dist/character/stages/retarget.d.ts +49 -0
- package/dist/character/stages/retarget.js +105 -0
- package/dist/character/stages/retarget.js.map +1 -0
- package/dist/character/stages/retargetClip.d.ts +27 -0
- package/dist/character/stages/retargetClip.js +237 -0
- package/dist/character/stages/retargetClip.js.map +1 -0
- package/dist/character/stages/simplifyMesh.d.ts +15 -0
- package/dist/character/stages/simplifyMesh.js +37 -0
- package/dist/character/stages/simplifyMesh.js.map +1 -0
- package/dist/character/stages/splitFacePrimitive.d.ts +30 -0
- package/dist/character/stages/splitFacePrimitive.js +115 -0
- package/dist/character/stages/splitFacePrimitive.js.map +1 -0
- package/dist/character/stages/weldedSimplify.d.ts +32 -0
- package/dist/character/stages/weldedSimplify.js +202 -0
- package/dist/character/stages/weldedSimplify.js.map +1 -0
- package/dist/character/testutil/syntheticRig.d.ts +9 -0
- package/dist/character/testutil/syntheticRig.js +84 -0
- package/dist/character/testutil/syntheticRig.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.js +103 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +378 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +87 -0
- package/dist/init.js.map +1 -0
- package/dist/initAbility.d.ts +1 -0
- package/dist/initAbility.js +71 -0
- package/dist/initAbility.js.map +1 -0
- package/dist/install.d.ts +51 -0
- package/dist/install.js +201 -0
- package/dist/install.js.map +1 -0
- package/dist/lib.d.ts +88 -0
- package/dist/lib.js +347 -0
- package/dist/lib.js.map +1 -0
- package/dist/package.d.ts +11 -0
- package/dist/package.js +136 -0
- package/dist/package.js.map +1 -0
- package/dist/prompt.d.ts +2 -0
- package/dist/prompt.js +55 -0
- package/dist/prompt.js.map +1 -0
- package/dist/resolve.d.ts +57 -0
- package/dist/resolve.js +103 -0
- package/dist/resolve.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +58 -0
- package/vendor/ability-manifest.mjs +558 -0
- package/vendor/installed-index.mjs +71 -0
package/dist/install.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RUNTIME_MODULE = exports.LOCKFILE = exports.INSTALLED_INDEX = exports.MODULES_DIR = void 0;
|
|
4
|
+
exports.installWorld = installWorld;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const ability_1 = require("./ability");
|
|
8
|
+
const resolve_1 = require("./resolve");
|
|
9
|
+
// `helix install` for a v0.2 world (consumer-plan decisions #2/#4/#8). Resolves the helix.json
|
|
10
|
+
// system/ability pins to exact versions, downloads CODE ONLY into public/helix_modules/<slug>/
|
|
11
|
+
// (assets always stream from the CDN — §11), and writes the v2 installed.json the runtime loader
|
|
12
|
+
// reads. The full resolution is locked in helix.lock.json: a bare re-run replays the lock (never
|
|
13
|
+
// re-resolves), `--update` re-resolves the live catalog and rewrites the lock.
|
|
14
|
+
exports.MODULES_DIR = 'helix_modules';
|
|
15
|
+
exports.INSTALLED_INDEX = 'installed.json';
|
|
16
|
+
exports.LOCKFILE = 'helix.lock.json';
|
|
17
|
+
exports.RUNTIME_MODULE = 'helix.runtime.ts'; // generated under src/
|
|
18
|
+
// The import map between these markers in index.html is (re)written by install with the resolved
|
|
19
|
+
// platform runtime URL, so the world's bare `three` resolves to the single hosted instance.
|
|
20
|
+
const IMPORTMAP_BLOCK = /(<!--\s*helix:three:start\s*-->)[\s\S]*?(<!--\s*helix:three:end\s*-->)/;
|
|
21
|
+
// Belt-and-suspenders: the server already splits code from assets, but a code channel must never
|
|
22
|
+
// carry a clip/texture/sound — that would put a HELIX asset on the consumer's disk.
|
|
23
|
+
const ASSET_EXT = /\.(glb|gltf|bin|ktx2|png|jpe?g|webp|mp3|ogg|wav)$/i;
|
|
24
|
+
const WORLD_MANIFEST_LOCATIONS = ['helix.json', (0, node_path_1.join)('public', 'helix.json')];
|
|
25
|
+
function readWorldManifest(worldDir) {
|
|
26
|
+
const manifestPath = WORLD_MANIFEST_LOCATIONS.map((rel) => (0, node_path_1.join)(worldDir, rel)).find((p) => (0, node_fs_1.existsSync)(p));
|
|
27
|
+
if (!manifestPath) {
|
|
28
|
+
throw new Error(`no helix.json found (looked in ./ and ./public/) — run \`helix install\` from a world project, or \`helix install <bundle> --first-party\` for a local ability`);
|
|
29
|
+
}
|
|
30
|
+
let manifest;
|
|
31
|
+
try {
|
|
32
|
+
manifest = JSON.parse((0, node_fs_1.readFileSync)(manifestPath, 'utf8'));
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw new Error(`${manifestPath} is not valid JSON: ${err instanceof Error ? err.message : err}`);
|
|
36
|
+
}
|
|
37
|
+
if (manifest.helixVersion !== '0.2' && manifest.helixVersion !== '0.3') {
|
|
38
|
+
throw new Error(`helix install resolves system/ability pins from a v0.2+ manifest, but ${manifestPath} is helixVersion "${manifest.helixVersion ?? '0.1'}" — set "helixVersion" to "0.2" or "0.3" with "systems"/"abilities" maps`);
|
|
39
|
+
}
|
|
40
|
+
return { manifestPath, pins: { systems: manifest.systems ?? {}, abilities: manifest.abilities ?? {} } };
|
|
41
|
+
}
|
|
42
|
+
// A bare re-run must replay the existing lock verbatim; it may only do so when helix.json hasn't
|
|
43
|
+
// drifted. Any added/removed pin, a changed range, or an out-of-range locked version means the
|
|
44
|
+
// lock is stale and the user must opt into re-resolving with --update.
|
|
45
|
+
function verifyLockMatchesPins(lock, pins, satisfies) {
|
|
46
|
+
const want = new Map();
|
|
47
|
+
for (const [slug, range] of Object.entries(pins.systems ?? {}))
|
|
48
|
+
want.set(slug, range);
|
|
49
|
+
for (const [slug, range] of Object.entries(pins.abilities ?? {}))
|
|
50
|
+
want.set(slug, range);
|
|
51
|
+
const have = new Map([...lock.systems, ...lock.abilities].map((p) => [p.slug, p]));
|
|
52
|
+
const drift = [];
|
|
53
|
+
for (const [slug, range] of want) {
|
|
54
|
+
const locked = have.get(slug);
|
|
55
|
+
if (!locked)
|
|
56
|
+
drift.push(`${slug} is newly pinned (${range})`);
|
|
57
|
+
else if (locked.range !== range)
|
|
58
|
+
drift.push(`${slug} pinned ${range}, lock has ${locked.range}`);
|
|
59
|
+
else if (!satisfies(locked.version, (0, resolve_1.normalizePinRange)(range)))
|
|
60
|
+
drift.push(`${slug}@${locked.version} no longer satisfies ${range}`);
|
|
61
|
+
}
|
|
62
|
+
for (const slug of have.keys())
|
|
63
|
+
if (!want.has(slug))
|
|
64
|
+
drift.push(`${slug} is in the lock but no longer pinned`);
|
|
65
|
+
if (drift.length) {
|
|
66
|
+
throw new Error(`helix.json pins differ from ${exports.LOCKFILE} — run \`helix install --update\` to re-resolve:\n${drift.map((d) => ` - ${d}`).join('\n')}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function assertCodeOnly(pkg) {
|
|
70
|
+
const leaked = pkg.codeFiles.filter((f) => ASSET_EXT.test(f));
|
|
71
|
+
if (leaked.length) {
|
|
72
|
+
throw new Error(`refusing to install ${pkg.slug}: asset files in its code channel (assets must stream from the CDN): ${leaked.join(', ')}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function defaultDownload(codeBaseUrl, files, destDir) {
|
|
76
|
+
const base = codeBaseUrl.replace(/\/+$/, '');
|
|
77
|
+
for (const rel of files) {
|
|
78
|
+
const res = await fetch(`${base}/${rel}`);
|
|
79
|
+
if (!res.ok)
|
|
80
|
+
throw new Error(`could not download ${rel} from ${base} (${res.status} ${res.statusText})`);
|
|
81
|
+
const dest = (0, node_path_1.join)(destDir, rel);
|
|
82
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(dest), { recursive: true });
|
|
83
|
+
(0, node_fs_1.writeFileSync)(dest, Buffer.from(await res.arrayBuffer()));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// The platform CDN base is the resolved code URL up to /packages/ — the hosted runtime lives at
|
|
87
|
+
// <base>/runtime/ on the same CDN. Deriving it from a real resolved URL means install never needs
|
|
88
|
+
// the base hardcoded or a separate endpoint.
|
|
89
|
+
function cdnRootFrom(url) {
|
|
90
|
+
const i = url.indexOf('/packages/');
|
|
91
|
+
return i > 0 ? url.slice(0, i) : null;
|
|
92
|
+
}
|
|
93
|
+
// Point the world at the single hosted three: rewrite index.html's import map and (re)generate
|
|
94
|
+
// src/helix.runtime.ts (the three module URL, KTX2 transcoder path, and the system's CDN asset
|
|
95
|
+
// base) for main.ts to import. Returns null when no system is pinned (nothing imports three by version).
|
|
96
|
+
function wireRuntime(worldDir, resolution, onProgress) {
|
|
97
|
+
const system = resolution.systems.find((s) => s.three);
|
|
98
|
+
if (!system || !system.three)
|
|
99
|
+
return null;
|
|
100
|
+
const cdnRoot = cdnRootFrom(system.codeUrl);
|
|
101
|
+
if (!cdnRoot)
|
|
102
|
+
throw new Error(`cannot derive the platform CDN base from "${system.codeUrl}" (expected a /packages/ path)`);
|
|
103
|
+
const threeVersion = system.three;
|
|
104
|
+
const threeModuleUrl = `${cdnRoot}/runtime/three/${threeVersion}/three.module.js`;
|
|
105
|
+
const transcoderPath = `${cdnRoot}/runtime/basis/three-${threeVersion}/`;
|
|
106
|
+
const htmlPath = (0, node_path_1.join)(worldDir, 'index.html');
|
|
107
|
+
if ((0, node_fs_1.existsSync)(htmlPath)) {
|
|
108
|
+
const html = (0, node_fs_1.readFileSync)(htmlPath, 'utf8');
|
|
109
|
+
if (IMPORTMAP_BLOCK.test(html)) {
|
|
110
|
+
const block = `$1\n <script type="importmap">\n { "imports": { "three": "${threeModuleUrl}" } }\n </script>\n $2`;
|
|
111
|
+
(0, node_fs_1.writeFileSync)(htmlPath, html.replace(IMPORTMAP_BLOCK, block));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
onProgress('! index.html has no <!-- helix:three:start/end --> markers — import map not written');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const runtimeTs = [
|
|
118
|
+
'// GENERATED by `helix install` — do not edit; re-run install to update.',
|
|
119
|
+
`export const THREE_VERSION = ${JSON.stringify(threeVersion)};`,
|
|
120
|
+
`export const THREE_MODULE_URL = ${JSON.stringify(threeModuleUrl)};`,
|
|
121
|
+
`export const TRANSCODER_PATH = ${JSON.stringify(transcoderPath)};`,
|
|
122
|
+
`export const SYSTEM_ASSET_BASE = ${JSON.stringify(system.assetBaseUrl ?? '')};`,
|
|
123
|
+
'',
|
|
124
|
+
].join('\n');
|
|
125
|
+
const srcDir = (0, node_path_1.join)(worldDir, 'src');
|
|
126
|
+
(0, node_fs_1.mkdirSync)(srcDir, { recursive: true });
|
|
127
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(srcDir, exports.RUNTIME_MODULE), runtimeTs);
|
|
128
|
+
return { threeVersion, threeModuleUrl, transcoderPath };
|
|
129
|
+
}
|
|
130
|
+
async function defaultDeps(apiUrl) {
|
|
131
|
+
const validator = await (0, ability_1.loadVendoredValidator)();
|
|
132
|
+
const indexValidator = await (0, ability_1.loadInstalledIndexValidator)();
|
|
133
|
+
if (!validator.satisfiesSystemPin)
|
|
134
|
+
throw new Error('vendored validator is missing satisfiesSystemPin — re-vendor ability-manifest.mjs');
|
|
135
|
+
const satisfies = validator.satisfiesSystemPin;
|
|
136
|
+
return {
|
|
137
|
+
resolve: (pins) => (0, resolve_1.resolvePins)(apiUrl, pins),
|
|
138
|
+
download: defaultDownload,
|
|
139
|
+
satisfies,
|
|
140
|
+
validateIndex: (value) => indexValidator.validateInstalledIndex(value),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
async function installWorld(worldDir, opts) {
|
|
144
|
+
const onProgress = opts.onProgress ?? (() => undefined);
|
|
145
|
+
const deps = opts.deps ?? (await defaultDeps(opts.apiUrl));
|
|
146
|
+
const { manifestPath, pins } = readWorldManifest(worldDir);
|
|
147
|
+
const lockPath = (0, node_path_1.join)(worldDir, exports.LOCKFILE);
|
|
148
|
+
let resolution;
|
|
149
|
+
let reresolved;
|
|
150
|
+
if (!opts.update && (0, node_fs_1.existsSync)(lockPath)) {
|
|
151
|
+
const lock = JSON.parse((0, node_fs_1.readFileSync)(lockPath, 'utf8'));
|
|
152
|
+
verifyLockMatchesPins(lock, pins, deps.satisfies);
|
|
153
|
+
resolution = { systems: lock.systems, abilities: lock.abilities };
|
|
154
|
+
reresolved = false;
|
|
155
|
+
onProgress(`Replaying ${exports.LOCKFILE} (run with --update to re-resolve)`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
onProgress(opts.update ? 'Re-resolving pins against the live catalog' : 'Resolving pins');
|
|
159
|
+
resolution = await deps.resolve(pins);
|
|
160
|
+
const lock = { lockfileVersion: 1, systems: resolution.systems, abilities: resolution.abilities };
|
|
161
|
+
(0, node_fs_1.writeFileSync)(lockPath, `${JSON.stringify(lock, null, 2)}\n`);
|
|
162
|
+
reresolved = true;
|
|
163
|
+
}
|
|
164
|
+
const all = [...resolution.systems, ...resolution.abilities];
|
|
165
|
+
all.forEach(assertCodeOnly);
|
|
166
|
+
// Clean rebuild of the managed dir so a re-run is byte-deterministic (no orphaned stale code).
|
|
167
|
+
const modulesDir = (0, node_path_1.join)(worldDir, 'public', exports.MODULES_DIR);
|
|
168
|
+
(0, node_fs_1.rmSync)(modulesDir, { recursive: true, force: true });
|
|
169
|
+
(0, node_fs_1.mkdirSync)(modulesDir, { recursive: true });
|
|
170
|
+
for (const pkg of all) {
|
|
171
|
+
onProgress(`Downloading ${pkg.slug}@${pkg.version} (${pkg.codeFiles.length} code files)`);
|
|
172
|
+
await deps.download(pkg.codeUrl, pkg.codeFiles, (0, node_path_1.join)(modulesDir, pkg.slug));
|
|
173
|
+
}
|
|
174
|
+
// Only abilities go in installed.json — the system is build-time-embedded via the alias. codeUrl is
|
|
175
|
+
// the ability's dir RELATIVE to the index base (just the slug); the loader resolves it against the
|
|
176
|
+
// base the world passes (document-derived), so a published world works from any deployment sub-path
|
|
177
|
+
// — a root-absolute "/helix_modules/<id>" would 404 once the world isn't at the origin root. Clips
|
|
178
|
+
// stream from the CDN assetBaseUrl.
|
|
179
|
+
const entries = resolution.abilities
|
|
180
|
+
.map((ab) => {
|
|
181
|
+
if (!ab.assetBaseUrl)
|
|
182
|
+
throw new Error(`ability "${ab.slug}" has no CDN asset base — cannot write a v2 installed.json entry`);
|
|
183
|
+
return { id: ab.slug, version: ab.version, codeUrl: ab.slug, assetBaseUrl: ab.assetBaseUrl };
|
|
184
|
+
})
|
|
185
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
186
|
+
const issues = deps.validateIndex(entries);
|
|
187
|
+
if (issues.length) {
|
|
188
|
+
throw new Error(`generated installed.json failed validation:\n${issues.map((i) => ` ${i.path || '(root)'}: ${i.message}`).join('\n')}`);
|
|
189
|
+
}
|
|
190
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(modulesDir, exports.INSTALLED_INDEX), `${JSON.stringify(entries, null, 2)}\n`);
|
|
191
|
+
const runtime = wireRuntime(worldDir, resolution, onProgress);
|
|
192
|
+
return {
|
|
193
|
+
manifestPath,
|
|
194
|
+
modulesDir,
|
|
195
|
+
systems: resolution.systems.map((s) => ({ slug: s.slug, version: s.version })),
|
|
196
|
+
abilities: resolution.abilities.map((a) => ({ slug: a.slug, version: a.version })),
|
|
197
|
+
reresolved,
|
|
198
|
+
runtime,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { HelixApi } from './api';
|
|
2
|
+
import { CliCredentials } from './config';
|
|
3
|
+
export { ApiError, HelixApi, uploadToTicket } from './api';
|
|
4
|
+
export { checkBundle, multiplayerConfigBundleFile, MULTIPLAYER_CONFIG_FILENAME, type BundleCheck, type BundleFile, } from './bundle';
|
|
5
|
+
export { checkPackageBundle, type PackageBundleCheck } from './package';
|
|
6
|
+
export { checkAbilityBundle, installLocalAbility, loadVendoredValidator, loadInstalledIndexValidator, type AbilityValidator, } from './ability';
|
|
7
|
+
export { normalizePinRange, resolvePins, type PinMap, type ResolveDeps, type ResolvedPackage, type ResolvedPins, type VersionDetail, type WorldPins, } from './resolve';
|
|
8
|
+
export { installWorld, INSTALLED_INDEX, LOCKFILE, MODULES_DIR, type InstalledEntry, type InstallDeps, type InstallWorldOptions, type InstallWorldResult, type WorldLock, } from './install';
|
|
9
|
+
export { DEFAULT_API_URL, DEFAULT_WEB_URL, HELIX_ENV, HELIX_SCOPE, loadCredentials, saveCredentials, clearCredentials, jwtExpiresAtIso, type CliCredentials, } from './config';
|
|
10
|
+
export { initTemplate } from './init';
|
|
11
|
+
export { initAbilityTemplate } from './initAbility';
|
|
12
|
+
export type { ImportCharacterClipResult, ImportCharacterOptions, ImportCharacterResult, } from './character/importCharacter';
|
|
13
|
+
import type { ImportCharacterOptions, ImportCharacterResult } from './character/importCharacter';
|
|
14
|
+
export declare function importCharacter(opts: ImportCharacterOptions): Promise<ImportCharacterResult>;
|
|
15
|
+
export type PublishResult = {
|
|
16
|
+
slug: string;
|
|
17
|
+
title: string;
|
|
18
|
+
buildId: string;
|
|
19
|
+
buildNumber: number;
|
|
20
|
+
playUrl: string | null;
|
|
21
|
+
worldUrl: string;
|
|
22
|
+
};
|
|
23
|
+
export type PublishProgress = (message: string) => void;
|
|
24
|
+
type WorldSummary = {
|
|
25
|
+
id: string;
|
|
26
|
+
slug: string;
|
|
27
|
+
title: string;
|
|
28
|
+
status: string;
|
|
29
|
+
hasActiveBuild: boolean;
|
|
30
|
+
};
|
|
31
|
+
export declare function publishWorld(root: string, creds: CliCredentials, onProgress?: PublishProgress): Promise<PublishResult>;
|
|
32
|
+
export type PublishPackageResult = {
|
|
33
|
+
kind: string;
|
|
34
|
+
slug: string;
|
|
35
|
+
version: string;
|
|
36
|
+
revision: number;
|
|
37
|
+
codeBaseUrl: string;
|
|
38
|
+
assetBaseUrl: string | null;
|
|
39
|
+
};
|
|
40
|
+
export declare function publishPackage(root: string, creds: CliCredentials, onProgress?: PublishProgress): Promise<PublishPackageResult>;
|
|
41
|
+
export type CatalogPackage = {
|
|
42
|
+
kind: string;
|
|
43
|
+
slug: string;
|
|
44
|
+
title: string;
|
|
45
|
+
description: string | null;
|
|
46
|
+
latestVersion: string | null;
|
|
47
|
+
targetSystem: {
|
|
48
|
+
id: string;
|
|
49
|
+
range: string | null;
|
|
50
|
+
} | null;
|
|
51
|
+
};
|
|
52
|
+
export type CatalogList = {
|
|
53
|
+
data: CatalogPackage[];
|
|
54
|
+
pageInfo: {
|
|
55
|
+
hasNextPage: boolean;
|
|
56
|
+
nextCursor: string | null;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export declare function listPackages(apiUrl: string, kind?: string, system?: string): Promise<CatalogList>;
|
|
60
|
+
export declare function getPackageManifest(apiUrl: string, slug: string, version?: string): Promise<Record<string, unknown>>;
|
|
61
|
+
export declare function authStatus(): {
|
|
62
|
+
loggedIn: boolean;
|
|
63
|
+
username?: string;
|
|
64
|
+
apiUrl?: string;
|
|
65
|
+
expiresAt?: string;
|
|
66
|
+
};
|
|
67
|
+
export type WhoAmI = {
|
|
68
|
+
id: string;
|
|
69
|
+
username: string;
|
|
70
|
+
};
|
|
71
|
+
export declare function whoAmI(api: HelixApi): Promise<WhoAmI>;
|
|
72
|
+
export declare function listMyWorlds(creds: CliCredentials): Promise<WorldSummary[]>;
|
|
73
|
+
export declare const TOOLCHAIN_PACKAGES: string[];
|
|
74
|
+
export type ToolchainStatus = {
|
|
75
|
+
name: string;
|
|
76
|
+
installed: string | null;
|
|
77
|
+
latest: string | null;
|
|
78
|
+
status: 'current' | 'update-available' | 'unknown';
|
|
79
|
+
updateHint: string;
|
|
80
|
+
};
|
|
81
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
82
|
+
export declare function cliVersion(): string;
|
|
83
|
+
export declare function installHint(slot: string, scope: string): string;
|
|
84
|
+
export declare function checkForUpdates(opts?: {
|
|
85
|
+
projectDir?: string;
|
|
86
|
+
installed?: Record<string, string>;
|
|
87
|
+
scope?: string;
|
|
88
|
+
}): Promise<ToolchainStatus[]>;
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Programmatic API for everything the `helix` bin does — also the surface an
|
|
3
|
+
// MCP server calls so AI agents run the exact same code paths as humans.
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
+
}) : function(o, v) {
|
|
18
|
+
o["default"] = v;
|
|
19
|
+
});
|
|
20
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
21
|
+
var ownKeys = function(o) {
|
|
22
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
23
|
+
var ar = [];
|
|
24
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
25
|
+
return ar;
|
|
26
|
+
};
|
|
27
|
+
return ownKeys(o);
|
|
28
|
+
};
|
|
29
|
+
return function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.TOOLCHAIN_PACKAGES = exports.initAbilityTemplate = exports.initTemplate = exports.jwtExpiresAtIso = exports.clearCredentials = exports.saveCredentials = exports.loadCredentials = exports.HELIX_SCOPE = exports.HELIX_ENV = exports.DEFAULT_WEB_URL = exports.DEFAULT_API_URL = exports.MODULES_DIR = exports.LOCKFILE = exports.INSTALLED_INDEX = exports.installWorld = exports.resolvePins = exports.normalizePinRange = exports.loadInstalledIndexValidator = exports.loadVendoredValidator = exports.installLocalAbility = exports.checkAbilityBundle = exports.checkPackageBundle = exports.MULTIPLAYER_CONFIG_FILENAME = exports.multiplayerConfigBundleFile = exports.checkBundle = exports.uploadToTicket = exports.HelixApi = exports.ApiError = void 0;
|
|
39
|
+
exports.importCharacter = importCharacter;
|
|
40
|
+
exports.publishWorld = publishWorld;
|
|
41
|
+
exports.publishPackage = publishPackage;
|
|
42
|
+
exports.listPackages = listPackages;
|
|
43
|
+
exports.getPackageManifest = getPackageManifest;
|
|
44
|
+
exports.authStatus = authStatus;
|
|
45
|
+
exports.whoAmI = whoAmI;
|
|
46
|
+
exports.listMyWorlds = listMyWorlds;
|
|
47
|
+
exports.compareVersions = compareVersions;
|
|
48
|
+
exports.cliVersion = cliVersion;
|
|
49
|
+
exports.installHint = installHint;
|
|
50
|
+
exports.checkForUpdates = checkForUpdates;
|
|
51
|
+
const node_fs_1 = require("node:fs");
|
|
52
|
+
const node_path_1 = require("node:path");
|
|
53
|
+
const api_1 = require("./api");
|
|
54
|
+
const bundle_1 = require("./bundle");
|
|
55
|
+
const package_1 = require("./package");
|
|
56
|
+
const ability_1 = require("./ability");
|
|
57
|
+
const config_1 = require("./config");
|
|
58
|
+
var api_2 = require("./api");
|
|
59
|
+
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return api_2.ApiError; } });
|
|
60
|
+
Object.defineProperty(exports, "HelixApi", { enumerable: true, get: function () { return api_2.HelixApi; } });
|
|
61
|
+
Object.defineProperty(exports, "uploadToTicket", { enumerable: true, get: function () { return api_2.uploadToTicket; } });
|
|
62
|
+
var bundle_2 = require("./bundle");
|
|
63
|
+
Object.defineProperty(exports, "checkBundle", { enumerable: true, get: function () { return bundle_2.checkBundle; } });
|
|
64
|
+
Object.defineProperty(exports, "multiplayerConfigBundleFile", { enumerable: true, get: function () { return bundle_2.multiplayerConfigBundleFile; } });
|
|
65
|
+
Object.defineProperty(exports, "MULTIPLAYER_CONFIG_FILENAME", { enumerable: true, get: function () { return bundle_2.MULTIPLAYER_CONFIG_FILENAME; } });
|
|
66
|
+
var package_2 = require("./package");
|
|
67
|
+
Object.defineProperty(exports, "checkPackageBundle", { enumerable: true, get: function () { return package_2.checkPackageBundle; } });
|
|
68
|
+
var ability_2 = require("./ability");
|
|
69
|
+
Object.defineProperty(exports, "checkAbilityBundle", { enumerable: true, get: function () { return ability_2.checkAbilityBundle; } });
|
|
70
|
+
Object.defineProperty(exports, "installLocalAbility", { enumerable: true, get: function () { return ability_2.installLocalAbility; } });
|
|
71
|
+
Object.defineProperty(exports, "loadVendoredValidator", { enumerable: true, get: function () { return ability_2.loadVendoredValidator; } });
|
|
72
|
+
Object.defineProperty(exports, "loadInstalledIndexValidator", { enumerable: true, get: function () { return ability_2.loadInstalledIndexValidator; } });
|
|
73
|
+
var resolve_1 = require("./resolve");
|
|
74
|
+
Object.defineProperty(exports, "normalizePinRange", { enumerable: true, get: function () { return resolve_1.normalizePinRange; } });
|
|
75
|
+
Object.defineProperty(exports, "resolvePins", { enumerable: true, get: function () { return resolve_1.resolvePins; } });
|
|
76
|
+
var install_1 = require("./install");
|
|
77
|
+
Object.defineProperty(exports, "installWorld", { enumerable: true, get: function () { return install_1.installWorld; } });
|
|
78
|
+
Object.defineProperty(exports, "INSTALLED_INDEX", { enumerable: true, get: function () { return install_1.INSTALLED_INDEX; } });
|
|
79
|
+
Object.defineProperty(exports, "LOCKFILE", { enumerable: true, get: function () { return install_1.LOCKFILE; } });
|
|
80
|
+
Object.defineProperty(exports, "MODULES_DIR", { enumerable: true, get: function () { return install_1.MODULES_DIR; } });
|
|
81
|
+
var config_2 = require("./config");
|
|
82
|
+
Object.defineProperty(exports, "DEFAULT_API_URL", { enumerable: true, get: function () { return config_2.DEFAULT_API_URL; } });
|
|
83
|
+
Object.defineProperty(exports, "DEFAULT_WEB_URL", { enumerable: true, get: function () { return config_2.DEFAULT_WEB_URL; } });
|
|
84
|
+
Object.defineProperty(exports, "HELIX_ENV", { enumerable: true, get: function () { return config_2.HELIX_ENV; } });
|
|
85
|
+
Object.defineProperty(exports, "HELIX_SCOPE", { enumerable: true, get: function () { return config_2.HELIX_SCOPE; } });
|
|
86
|
+
Object.defineProperty(exports, "loadCredentials", { enumerable: true, get: function () { return config_2.loadCredentials; } });
|
|
87
|
+
Object.defineProperty(exports, "saveCredentials", { enumerable: true, get: function () { return config_2.saveCredentials; } });
|
|
88
|
+
Object.defineProperty(exports, "clearCredentials", { enumerable: true, get: function () { return config_2.clearCredentials; } });
|
|
89
|
+
Object.defineProperty(exports, "jwtExpiresAtIso", { enumerable: true, get: function () { return config_2.jwtExpiresAtIso; } });
|
|
90
|
+
var init_1 = require("./init");
|
|
91
|
+
Object.defineProperty(exports, "initTemplate", { enumerable: true, get: function () { return init_1.initTemplate; } });
|
|
92
|
+
var initAbility_1 = require("./initAbility");
|
|
93
|
+
Object.defineProperty(exports, "initAbilityTemplate", { enumerable: true, get: function () { return initAbility_1.initAbilityTemplate; } });
|
|
94
|
+
// Character import (`helix character import`) as a programmatic API. The implementation pulls in
|
|
95
|
+
// gltf-transform + meshoptimizer (~165ms of require time), so it is loaded lazily at call time —
|
|
96
|
+
// requiring lib.js (and therefore `helix --help`) stays fast.
|
|
97
|
+
async function importCharacter(opts) {
|
|
98
|
+
const mod = await Promise.resolve().then(() => __importStar(require('./character/importCharacter')));
|
|
99
|
+
return mod.importCharacter(opts);
|
|
100
|
+
}
|
|
101
|
+
const UPLOAD_CONCURRENCY = 6;
|
|
102
|
+
// Validate + resolve-or-create world + upload + finalize. Throws ApiError /
|
|
103
|
+
// Error with human-readable messages on any failure.
|
|
104
|
+
async function publishWorld(root, creds, onProgress = () => undefined) {
|
|
105
|
+
const bundle = (0, bundle_1.checkBundle)(root);
|
|
106
|
+
if (bundle.errors.length) {
|
|
107
|
+
throw new Error(`Bundle is invalid:\n${bundle.errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
108
|
+
}
|
|
109
|
+
const manifest = bundle.manifest;
|
|
110
|
+
// Emit the runtime multiplayer config (multiplayer.json) into the bundle for multiplayer worlds. It's
|
|
111
|
+
// generated in-memory from the validated manifest — the authoritative copy — so drop any hand-placed
|
|
112
|
+
// one first, keeping exactly one entry. The backend signs its URL into the room credential (configUrl).
|
|
113
|
+
const multiplayerFile = (0, bundle_1.multiplayerConfigBundleFile)(root, manifest);
|
|
114
|
+
if (multiplayerFile) {
|
|
115
|
+
bundle.files = bundle.files.filter((f) => f.path !== bundle_1.MULTIPLAYER_CONFIG_FILENAME);
|
|
116
|
+
bundle.files.push(multiplayerFile);
|
|
117
|
+
}
|
|
118
|
+
const api = api_1.HelixApi.forCredentials(creds);
|
|
119
|
+
const mine = await api.request('GET', '/api/v1/instant-worlds/me');
|
|
120
|
+
let world = mine.data.find((w) => w.slug === manifest.slug);
|
|
121
|
+
if (!world) {
|
|
122
|
+
onProgress(`Creating world "${manifest.title}" (${manifest.slug})`);
|
|
123
|
+
world = await api.requestItem('POST', '/api/v1/instant-worlds', {
|
|
124
|
+
title: manifest.title,
|
|
125
|
+
slug: manifest.slug,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
onProgress(`Requesting upload for ${bundle.files.length} files`);
|
|
129
|
+
const build = await api.requestItem('POST', `/api/v1/instant-worlds/${world.id}/builds`, {
|
|
130
|
+
manifest,
|
|
131
|
+
files: bundle.files.map((f) => ({ path: f.path, size: f.size })),
|
|
132
|
+
});
|
|
133
|
+
let done = 0;
|
|
134
|
+
const queue = [...build.uploads];
|
|
135
|
+
await Promise.all(Array.from({ length: UPLOAD_CONCURRENCY }, async () => {
|
|
136
|
+
for (let ticket = queue.shift(); ticket; ticket = queue.shift()) {
|
|
137
|
+
const file = bundle.files.find((f) => f.path === ticket.path);
|
|
138
|
+
// Generated files (multiplayer.json) carry in-memory content; on-disk files are read by path.
|
|
139
|
+
await (0, api_1.uploadToTicket)(ticket.url, file.content ?? (0, node_fs_1.readFileSync)(file.absolutePath), ticket.contentType, ticket.cacheControl);
|
|
140
|
+
done += 1;
|
|
141
|
+
onProgress(`Uploaded ${done}/${build.uploads.length}`);
|
|
142
|
+
}
|
|
143
|
+
}));
|
|
144
|
+
onProgress('Finalizing');
|
|
145
|
+
await api.request('POST', `/api/v1/instant-worlds/${world.id}/builds/${build.buildId}/finalize`);
|
|
146
|
+
const detail = await api.requestItem('GET', `/api/v1/instant-worlds/${manifest.slug}`);
|
|
147
|
+
return {
|
|
148
|
+
slug: manifest.slug,
|
|
149
|
+
title: manifest.title,
|
|
150
|
+
buildId: build.buildId,
|
|
151
|
+
buildNumber: build.buildNumber,
|
|
152
|
+
playUrl: detail.playUrl,
|
|
153
|
+
worldUrl: `${creds.apiUrl}/api/v1/instant-worlds/${manifest.slug}`,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// Validate the bundle → create the version (presigned tickets per code/asset
|
|
157
|
+
// channel) → upload → finalize. Admin-only on the server.
|
|
158
|
+
async function publishPackage(root, creds, onProgress = () => undefined) {
|
|
159
|
+
const validator = await (0, ability_1.loadVendoredValidator)();
|
|
160
|
+
const check = (0, package_1.checkPackageBundle)(root, validator);
|
|
161
|
+
if (check.errors.length || !check.envelope) {
|
|
162
|
+
throw new Error(`Bundle is invalid:\n${check.errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
163
|
+
}
|
|
164
|
+
const envelope = check.envelope;
|
|
165
|
+
const api = api_1.HelixApi.forCredentials(creds);
|
|
166
|
+
onProgress(`Publishing ${envelope.kind} "${envelope.title}" (${envelope.slug}@${envelope.version}) — ${check.files.length} files`);
|
|
167
|
+
const created = await api.requestItem('POST', `/api/v1/instant-packages/${envelope.slug}/versions`, {
|
|
168
|
+
manifest: envelope,
|
|
169
|
+
payload: check.payload ?? undefined,
|
|
170
|
+
files: check.files.map((f) => ({ path: f.path, size: f.size })),
|
|
171
|
+
});
|
|
172
|
+
let done = 0;
|
|
173
|
+
const queue = [...created.uploads];
|
|
174
|
+
await Promise.all(Array.from({ length: UPLOAD_CONCURRENCY }, async () => {
|
|
175
|
+
for (let ticket = queue.shift(); ticket; ticket = queue.shift()) {
|
|
176
|
+
const file = check.files.find((f) => f.path === ticket.path);
|
|
177
|
+
await (0, api_1.uploadToTicket)(ticket.url, (0, node_fs_1.readFileSync)(file.absolutePath), ticket.contentType, ticket.cacheControl);
|
|
178
|
+
done += 1;
|
|
179
|
+
onProgress(`Uploaded ${done}/${created.uploads.length}`);
|
|
180
|
+
}
|
|
181
|
+
}));
|
|
182
|
+
onProgress('Finalizing');
|
|
183
|
+
const final = await api.requestItem('POST', `/api/v1/instant-packages/${envelope.slug}/versions/${encodeURIComponent(envelope.version)}/finalize`);
|
|
184
|
+
return {
|
|
185
|
+
kind: final.kind,
|
|
186
|
+
slug: final.slug,
|
|
187
|
+
version: final.version,
|
|
188
|
+
revision: final.revision,
|
|
189
|
+
codeBaseUrl: final.codeBaseUrl,
|
|
190
|
+
assetBaseUrl: final.assetBaseUrl,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
// Public discovery — no auth. List published systems/abilities/asset-packs.
|
|
194
|
+
function listPackages(apiUrl, kind, system) {
|
|
195
|
+
const api = new api_1.HelixApi(apiUrl);
|
|
196
|
+
const qs = new URLSearchParams();
|
|
197
|
+
if (kind)
|
|
198
|
+
qs.set('kind', kind);
|
|
199
|
+
if (system)
|
|
200
|
+
qs.set('system', system);
|
|
201
|
+
const query = qs.toString();
|
|
202
|
+
return api.request('GET', `/api/v1/instant-packages${query ? `?${query}` : ''}`);
|
|
203
|
+
}
|
|
204
|
+
// Public discovery — the full manifest + payload (the documentation an agent
|
|
205
|
+
// reads before configuring). `version` defaults to the highest active semver.
|
|
206
|
+
function getPackageManifest(apiUrl, slug, version = 'latest') {
|
|
207
|
+
const api = new api_1.HelixApi(apiUrl);
|
|
208
|
+
return api.requestItem('GET', `/api/v1/instant-packages/${slug}/versions/${encodeURIComponent(version)}`);
|
|
209
|
+
}
|
|
210
|
+
// Convenience for tools: current login state without throwing.
|
|
211
|
+
function authStatus() {
|
|
212
|
+
const creds = (0, config_1.loadCredentials)();
|
|
213
|
+
if (!creds)
|
|
214
|
+
return { loggedIn: false };
|
|
215
|
+
return {
|
|
216
|
+
loggedIn: true,
|
|
217
|
+
username: creds.username,
|
|
218
|
+
apiUrl: creds.apiUrl,
|
|
219
|
+
expiresAt: creds.expiresAt || undefined,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// Validates a token and returns the authenticated user (the CLI's whoami).
|
|
223
|
+
async function whoAmI(api) {
|
|
224
|
+
return api.requestItem('GET', '/api/v1/users/me');
|
|
225
|
+
}
|
|
226
|
+
async function listMyWorlds(creds) {
|
|
227
|
+
const api = api_1.HelixApi.forCredentials(creds);
|
|
228
|
+
const res = await api.request('GET', '/api/v1/instant-worlds/me');
|
|
229
|
+
return res.data;
|
|
230
|
+
}
|
|
231
|
+
// --- Toolchain version / update checks --------------------------------------
|
|
232
|
+
// The @helix packages an agent's toolchain is built from: the CLI + MCP (tools,
|
|
233
|
+
// ideally run via `npx -y <pkg>@latest`) and manifest + sdk (libs a
|
|
234
|
+
// world/ability project pins).
|
|
235
|
+
// TS imports always use the @hypersoniclabs keys (staging is npm-aliased UNDER
|
|
236
|
+
// those paths); the registry name / latest lookup / update hint use the scope THIS
|
|
237
|
+
// build ships under (HELIX_SCOPE) — so a staging build reports @helixdev/*.
|
|
238
|
+
const TOOLCHAIN_SLOTS = ['helix-cli', 'helix-manifest', 'helix-sdk', 'helix-mcp'];
|
|
239
|
+
const IMPORT_SCOPE = '@hypersoniclabs';
|
|
240
|
+
exports.TOOLCHAIN_PACKAGES = TOOLCHAIN_SLOTS.map((s) => `${IMPORT_SCOPE}/${s}`);
|
|
241
|
+
const REGISTRY = 'https://registry.npmjs.org';
|
|
242
|
+
const isLib = (slot) => slot === 'helix-manifest' || slot === 'helix-sdk';
|
|
243
|
+
// Order by semver core (major.minor.patch); on a tie, a release outranks a prerelease
|
|
244
|
+
// of the same core, and among prereleases the trailing run number breaks the tie
|
|
245
|
+
// (…-staging.14 < …-staging.15) so staging staleness is detectable.
|
|
246
|
+
function compareVersions(a, b) {
|
|
247
|
+
const core = (v) => v.split('-')[0].split('.').map((n) => Number(n) || 0);
|
|
248
|
+
const [pa, pb] = [core(a), core(b)];
|
|
249
|
+
for (let i = 0; i < 3; i++) {
|
|
250
|
+
if ((pa[i] ?? 0) !== (pb[i] ?? 0))
|
|
251
|
+
return (pa[i] ?? 0) < (pb[i] ?? 0) ? -1 : 1;
|
|
252
|
+
}
|
|
253
|
+
const pre = (v) => (v.includes('-') ? v.slice(v.indexOf('-') + 1) : null);
|
|
254
|
+
const [ra, rb] = [pre(a), pre(b)];
|
|
255
|
+
if (ra === rb)
|
|
256
|
+
return 0;
|
|
257
|
+
if (ra === null)
|
|
258
|
+
return 1;
|
|
259
|
+
if (rb === null)
|
|
260
|
+
return -1;
|
|
261
|
+
const run = (s) => {
|
|
262
|
+
const m = s.match(/(\d+)\s*$/);
|
|
263
|
+
return m ? Number(m[1]) : 0;
|
|
264
|
+
};
|
|
265
|
+
const [oa, ob] = [run(ra), run(rb)];
|
|
266
|
+
return oa === ob ? 0 : oa < ob ? -1 : 1;
|
|
267
|
+
}
|
|
268
|
+
// This CLI's own version, read from its package.json (dist/.. at runtime).
|
|
269
|
+
function cliVersion() {
|
|
270
|
+
try {
|
|
271
|
+
return JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, '..', 'package.json'), 'utf8')).version;
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return '0.0.0';
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async function latestOnNpm(name) {
|
|
278
|
+
try {
|
|
279
|
+
const res = await fetch(`${REGISTRY}/${name.replace('/', '%2f')}/latest`);
|
|
280
|
+
if (!res.ok)
|
|
281
|
+
return null;
|
|
282
|
+
return (await res.json()).version ?? null;
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
function installedVersion(name, projectDir) {
|
|
289
|
+
if (name === '@hypersoniclabs/helix-cli')
|
|
290
|
+
return cliVersion();
|
|
291
|
+
const candidates = [];
|
|
292
|
+
if (projectDir) {
|
|
293
|
+
candidates.push((0, node_path_1.join)(projectDir, 'node_modules', name, 'package.json'));
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
candidates.push(require.resolve(`${name}/package.json`));
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// not resolvable from here — fall through to the project-dir candidate
|
|
300
|
+
}
|
|
301
|
+
for (const p of candidates) {
|
|
302
|
+
try {
|
|
303
|
+
if ((0, node_fs_1.existsSync)(p)) {
|
|
304
|
+
return JSON.parse((0, node_fs_1.readFileSync)(p, 'utf8'))
|
|
305
|
+
.version;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
// unreadable / parse error — try the next candidate
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
// Compare each toolchain package's installed version against the latest on npm.
|
|
315
|
+
// `installed` overrides let the running tool report its own version.
|
|
316
|
+
// The exact command to bring a toolchain package to latest, in THIS build's scope.
|
|
317
|
+
// Tools (cli/mcp) install by their real scoped name (npx / global). Libs (manifest/sdk)
|
|
318
|
+
// are pinned in a project under the @hypersoniclabs import KEY: on prod that key IS the
|
|
319
|
+
// package (direct install); on staging it must be an npm ALIAS to the @helixdev package so
|
|
320
|
+
// the project's `@hypersoniclabs/*` import keeps resolving (matches the MCP's staging banner).
|
|
321
|
+
function installHint(slot, scope) {
|
|
322
|
+
const importKey = `${IMPORT_SCOPE}/${slot}`;
|
|
323
|
+
const registryName = `${scope}/${slot}`;
|
|
324
|
+
if (isLib(slot)) {
|
|
325
|
+
return importKey === registryName
|
|
326
|
+
? `npm i ${importKey}@latest`
|
|
327
|
+
: `npm i ${importKey}@npm:${registryName}@latest`;
|
|
328
|
+
}
|
|
329
|
+
return `run via "npx -y ${registryName}@latest" (always current), or update a global install: npm i -g ${registryName}@latest`;
|
|
330
|
+
}
|
|
331
|
+
async function checkForUpdates(opts = {}) {
|
|
332
|
+
const scope = opts.scope ?? config_1.HELIX_SCOPE;
|
|
333
|
+
return Promise.all(TOOLCHAIN_SLOTS.map(async (slot) => {
|
|
334
|
+
const importKey = `${IMPORT_SCOPE}/${slot}`;
|
|
335
|
+
const registryName = `${scope}/${slot}`;
|
|
336
|
+
const installed = opts.installed?.[importKey] ?? installedVersion(importKey, opts.projectDir);
|
|
337
|
+
const latest = await latestOnNpm(registryName);
|
|
338
|
+
const status = installed && latest
|
|
339
|
+
? compareVersions(installed, latest) < 0
|
|
340
|
+
? 'update-available'
|
|
341
|
+
: 'current'
|
|
342
|
+
: 'unknown';
|
|
343
|
+
const updateHint = installHint(slot, scope);
|
|
344
|
+
return { name: registryName, installed, latest, status, updateHint };
|
|
345
|
+
}));
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=lib.js.map
|