@tantawowa/hosanna-tools 3.5.1 → 3.6.1

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/README.md CHANGED
@@ -18,6 +18,22 @@ Note, if you are developing hosanna-tools, you will install the package locally.
18
18
  npm install . -g # path to the hosanna-tools directory
19
19
  ```
20
20
 
21
+ ## Hosanna source install modes
22
+
23
+ Client projects can switch between Keygen source tarballs, git checkouts, and a
24
+ local SDK checkout:
25
+
26
+ ```bash
27
+ hst config source # show current mode
28
+ hst config source keygen --fix # default: full + roku,web from @nightly
29
+ hst config source git --fix # use the configured git checkout again
30
+ hst config source local --fix # use LOCAL_SDK for framework development
31
+ ```
32
+
33
+ Keygen mode writes `distribution: "keygen"` to `hosanna.json` and installs
34
+ license-gated artifacts with `hst env fix` / `hst sdk:install`. Git mode keeps
35
+ the legacy clone/update path for developers who need it.
36
+
21
37
  ## Embedding as a library
22
38
 
23
39
  Hosanna Tools can also be imported by app build chains. The CLI remains available as `hst`, but package imports are library-safe and do not parse CLI arguments or call `process.exit` during import. Public wrappers for process-oriented commands use no-exit mode where supported, so API callers receive structured results or thrown errors instead of forced process termination.
@@ -124,6 +140,10 @@ npm run release -- minor # 2.14.0 → 2.15.0
124
140
  npm run release -- major # 2.14.0 → 3.0.0
125
141
  ```
126
142
 
143
+ For tokenless agent releases, dispatch **Release Patch** or **Release Minor**
144
+ in GitHub Actions. Both wrappers invoke the OIDC-trusted `release.yml`
145
+ workflow on `main`; agents do not need npm credentials.
146
+
127
147
  ## CLI: configure-hosanna-url
128
148
 
129
149
  - **purpose**: Updates `hosanna.json` with a new Hosanna UI Git URL under the `git-url` key.
@@ -1,6 +1,6 @@
1
1
  {
2
- "buildDate": "2026-07-07T14:16:34+01:00",
3
- "buildDateISO": "2026-07-07T13:16:34.976Z",
4
- "timeZone": "Europe/London",
5
- "gitHash": "6626b1f"
2
+ "buildDate": "2026-07-11T20:48:11+00:00",
3
+ "buildDateISO": "2026-07-11T20:48:11.158Z",
4
+ "timeZone": "UTC",
5
+ "gitHash": "aee354a"
6
6
  }
package/dist/cli.js CHANGED
@@ -211,6 +211,14 @@ function nativeFormatArg(args) {
211
211
  function stringArg(value) {
212
212
  return typeof value === 'string' && value.trim() ? value.trim() : undefined;
213
213
  }
214
+ function stringArrayArg(value) {
215
+ if (typeof value === 'string')
216
+ return [value];
217
+ if (Array.isArray(value)) {
218
+ return value.filter((item) => typeof item === 'string');
219
+ }
220
+ return undefined;
221
+ }
214
222
  function numberOrStringArg(value) {
215
223
  if (typeof value === 'number' && Number.isFinite(value))
216
224
  return value;
@@ -731,11 +739,16 @@ catch (err) {
731
739
  }
732
740
  })
733
741
  // remove old --env flag; env is now a subcommand
734
- .command('config [action]', 'Show or update hosanna.json configuration from a curated catalog', yargs => yargs
742
+ .command('config [action] [mode]', 'Show or update hosanna.json configuration from a curated catalog', yargs => yargs
735
743
  .positional('action', {
736
744
  type: 'string',
737
- choices: ['show', 'set', 'wizard'],
738
- describe: 'show prints current config, set writes values from flags, wizard runs the interactive setup',
745
+ choices: ['show', 'set', 'wizard', 'source'],
746
+ describe: 'show prints current config, set writes values from flags, wizard runs the interactive setup, source switches install mode',
747
+ })
748
+ .positional('mode', {
749
+ type: 'string',
750
+ choices: ['show', 'keygen', 'git', 'local'],
751
+ describe: 'Source install mode when action is source',
739
752
  })
740
753
  .option('git-url', { type: 'string', describe: 'Set hosanna.json git-url' })
741
754
  .option('sdk-version', { type: 'string', describe: 'Set hosanna.json sdk-version' })
@@ -743,12 +756,57 @@ catch (err) {
743
756
  .option('transpiler-version', { type: 'string', describe: 'Set hosanna.json transpiler-version' })
744
757
  .option('config-catalog-url', { type: 'string', describe: 'Persist a remote catalog URL into hosanna.json' })
745
758
  .option('catalog-url', { type: 'string', describe: 'Use a remote catalog URL for this run without writing it' })
759
+ .option('flavour', { type: 'string', choices: ['core', 'game', 'full'], describe: 'Keygen source flavour when action is source (default: full)' })
760
+ .option('platforms', { type: 'string', array: true, describe: 'Keygen platforms when action is source, comma-separated or repeatable (default: roku,web)' })
761
+ .option('install', { type: 'boolean', default: false, describe: 'Install the selected source mode atomically after updating config' })
762
+ .option('replace-existing', { type: 'boolean', default: false, describe: 'Allow --install to replace an existing hosanna-ui source root when switching modes' })
763
+ .option('force', { type: 'boolean', default: false, describe: 'Allow --install to replace a dirty git checkout when used with --replace-existing' })
746
764
  .option('fix', { type: 'boolean', default: false, describe: 'Run hst env fix after updating config' }), async (args) => {
747
765
  if (args.verbose) {
748
766
  process.env.HOSANNA_VERBOSE = '1';
749
767
  process.env.HOSANNA_UPDATER_VERBOSE = '1';
750
768
  }
751
769
  const actionArg = typeof args.action === 'string' ? args.action : undefined;
770
+ if (actionArg === 'source') {
771
+ try {
772
+ const result = await (0, hosanna_config_js_1.runHosannaSourceConfig)({
773
+ cwd: process.cwd(),
774
+ mode: (typeof args.mode === 'string' ? args.mode : 'show'),
775
+ flavour: args.flavour,
776
+ platforms: (0, hosanna_config_js_1.parsePlatformList)(stringArrayArg(args.platforms)),
777
+ sdkVersion: typeof args.sdkVersion === 'string' ? args.sdkVersion : undefined,
778
+ gitUrl: typeof args.gitUrl === 'string' ? args.gitUrl : undefined,
779
+ branch: typeof args.branch === 'string' ? args.branch : undefined,
780
+ install: Boolean(args.install),
781
+ replaceExisting: Boolean(args.replaceExisting),
782
+ force: Boolean(args.force),
783
+ writeStdout: text => console.info(text),
784
+ });
785
+ if (args.fix && result.updated) {
786
+ const { fixAllEnvironmentIssues } = await Promise.resolve().then(() => __importStar(require('./lib/env-info.js')));
787
+ const fixResult = await fixAllEnvironmentIssues(process.cwd());
788
+ console.info(`\n${fixResult.message}`);
789
+ if (fixResult.remainingIssues.length > 0) {
790
+ console.info('\n❌ Remaining issues:');
791
+ for (const issue of fixResult.remainingIssues) {
792
+ console.info(` • ${issue}`);
793
+ }
794
+ }
795
+ if (!process.env.VITEST)
796
+ process.exit(fixResult.success ? 0 : 1);
797
+ return;
798
+ }
799
+ if (!process.env.VITEST)
800
+ process.exit(0);
801
+ return;
802
+ }
803
+ catch (err) {
804
+ console.error('❌ Failed to configure source install mode:', err instanceof Error ? err.message : err);
805
+ if (!process.env.VITEST)
806
+ process.exit(1);
807
+ return;
808
+ }
809
+ }
752
810
  const action = actionArg === 'show' || actionArg === 'set' ? actionArg : 'wizard';
753
811
  const updates = {};
754
812
  if (typeof args.gitUrl === 'string')
@@ -1297,7 +1355,7 @@ catch (err) {
1297
1355
  const key = String(args.key).trim();
1298
1356
  const validation = await mod.validateLicense(key);
1299
1357
  if (!validation.valid) {
1300
- console.error(`❌ License is not valid: ${validation.code} ${validation.detail}`.trim());
1358
+ console.error(`❌ License is not valid for the Hosanna source product: ${validation.code} ${validation.detail}`.trim());
1301
1359
  process.exit(1);
1302
1360
  }
1303
1361
  const filePath = mod.storeLicenseKey(key);