@tantawowa/hosanna-tools 4.0.0 → 5.0.0
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 +85 -76
- package/dist/build-info.json +3 -3
- package/dist/cli.js +27 -191
- package/dist/cli.js.map +1 -1
- package/dist/generation/emitters/RuntimeEmitter.js +1 -12
- package/dist/generation/emitters/RuntimeEmitter.js.map +1 -1
- package/dist/generation/import-utils.js +2 -11
- package/dist/generation/import-utils.js.map +1 -1
- package/dist/index.d.ts +4 -12
- package/dist/index.js +5 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/env-info.d.ts +9 -16
- package/dist/lib/env-info.js +117 -386
- package/dist/lib/env-info.js.map +1 -1
- package/dist/lib/hosanna-config.d.ts +1 -31
- package/dist/lib/hosanna-config.js +8 -367
- package/dist/lib/hosanna-config.js.map +1 -1
- package/dist/support-tools/mcp-server/rasp-exporter.js +1 -1
- package/dist/testing/client.js +2 -3
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/config.d.ts +1 -0
- package/dist/testing/config.js +8 -0
- package/dist/testing/config.js.map +1 -1
- package/dist/testing/launcher.js +26 -29
- package/dist/testing/launcher.js.map +1 -1
- package/dist/testing/types.d.ts +5 -0
- package/dist/updater/framework-script-migration.d.ts +6 -0
- package/dist/updater/framework-script-migration.js +55 -0
- package/dist/updater/framework-script-migration.js.map +1 -0
- package/dist/updater/license-manager.d.ts +1 -80
- package/dist/updater/license-manager.js +4 -329
- package/dist/updater/license-manager.js.map +1 -1
- package/dist/updater/npm-framework.d.ts +19 -0
- package/dist/updater/npm-framework.js +214 -0
- package/dist/updater/npm-framework.js.map +1 -0
- package/dist/updater/sdk-manager.d.ts +2 -31
- package/dist/updater/sdk-manager.js +53 -804
- package/dist/updater/sdk-manager.js.map +1 -1
- package/dist/updater/symlink-manager.js +2 -21
- package/dist/updater/symlink-manager.js.map +1 -1
- package/dist/vite.d.ts +8 -0
- package/dist/vite.js +22 -6
- package/dist/vite.js.map +1 -1
- package/package.json +4 -2
- package/dist/lib/cli.configure-hosanna-url.d.ts +0 -11
- package/dist/lib/cli.configure-hosanna-url.js +0 -51
- package/dist/lib/cli.configure-hosanna-url.js.map +0 -1
- package/dist/lib/local-source-override.d.ts +0 -22
- package/dist/lib/local-source-override.js +0 -141
- package/dist/lib/local-source-override.js.map +0 -1
- package/dist/support-tools/framework-sync.d.ts +0 -75
- package/dist/support-tools/framework-sync.js +0 -348
- package/dist/support-tools/framework-sync.js.map +0 -1
- package/dist/updater/framework-installer.d.ts +0 -57
- package/dist/updater/framework-installer.js +0 -492
- package/dist/updater/framework-installer.js.map +0 -1
- package/dist/updater/local-sdk-manager.d.ts +0 -16
- package/dist/updater/local-sdk-manager.js +0 -225
- package/dist/updater/local-sdk-manager.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# hosanna-tools
|
|
2
2
|
|
|
3
|
+
This package lives in `packages/tools` in the Hosanna UI monorepo. It retains its
|
|
4
|
+
own package name, version, and lockfile. Run its development commands from this
|
|
5
|
+
directory; framework source remains at the repository root.
|
|
6
|
+
|
|
3
7
|
## Agent skills
|
|
4
8
|
|
|
5
9
|
The repository instructions use TantaWowa's ClickUp workflow skills, Matt
|
|
@@ -7,7 +11,7 @@ Pocock's engineering skills, and pstack's `unslop` skill. Install them once on
|
|
|
7
11
|
each developer machine:
|
|
8
12
|
|
|
9
13
|
```sh
|
|
10
|
-
npx -y skills add TantaWowa/hosanna-tools --global --skill work-on-ticket
|
|
14
|
+
npx -y skills add TantaWowa/hosanna-tools --global --skill work-on-ticket --agent '*' --full-depth --yes
|
|
11
15
|
npx -y skills add mattpocock/skills --global --all
|
|
12
16
|
npx -y skills add cursor/plugins --global --skill unslop --agent '*' --full-depth --yes
|
|
13
17
|
```
|
|
@@ -24,7 +28,7 @@ Run `npx -y skills update --global --yes` to update the installed skills later.
|
|
|
24
28
|
- **[Video capture](docs/video-capture.md)** — standalone, agent-driven, and test-run recording for Roku capture cards and browser emulator windows.
|
|
25
29
|
- **[Roku and browser emulation](docs/roku-browser-emulation.md)** — supported launch commands, device selection, and emulator configuration.
|
|
26
30
|
- **[docs/README.md](docs/README.md)** — index of docs in this repo (MCP + source-map note).
|
|
27
|
-
- **
|
|
31
|
+
- **[Hosanna UI framework](../../docs/README.md)** for agentic debugging and framework documentation.
|
|
28
32
|
|
|
29
33
|
## To use the tool
|
|
30
34
|
|
|
@@ -38,46 +42,68 @@ Note, if you are developing hosanna-tools, you will install the package locally.
|
|
|
38
42
|
npm install . -g # path to the hosanna-tools directory
|
|
39
43
|
```
|
|
40
44
|
|
|
41
|
-
##
|
|
45
|
+
## Install the framework
|
|
46
|
+
|
|
47
|
+
The framework is an npm dependency. Install it with the tools in each app:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install --save-dev --save-exact @tantawowa/hosanna-tools@5 @tantawowa/hosanna-ui@2 @tantawowa/hosanna-eslint-plugin@2
|
|
51
|
+
npx hst sdk:install
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Commit `package.json` and `package-lock.json`. A fresh checkout runs `npm ci`
|
|
55
|
+
followed by `npx hst sdk:install`. The command validates the installed package
|
|
56
|
+
and maintains these app paths:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
hosanna-ui -> node_modules/@tantawowa/hosanna-ui
|
|
60
|
+
src/hosanna-ui -> ../hosanna-ui/src/hosanna-ui
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The other framework source folders use the same links. Existing `@hs-src`
|
|
64
|
+
imports, generated app files and compiler paths continue to work. Update the
|
|
65
|
+
framework with npm, then run `hst sdk:install` again. The command also reconciles
|
|
66
|
+
the framework's declared app dependencies. Use `--skip-consumer-dependencies`
|
|
67
|
+
when the app package manager has already installed them. Tools 5 requires
|
|
68
|
+
Vitest `>=3.2.0 <5`; update an older app test dependency during the npm upgrade.
|
|
69
|
+
|
|
70
|
+
For an app using the previous framework installer, install the npm packages
|
|
71
|
+
with `--ignore-scripts` first so old install hooks cannot run removed commands,
|
|
72
|
+
then run:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm install --ignore-scripts --save-dev --save-exact @tantawowa/hosanna-tools@5 @tantawowa/hosanna-ui@2 @tantawowa/hosanna-eslint-plugin@2
|
|
76
|
+
npx hst sdk:migrate --replace-existing
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Migration removes the old framework version/source settings and private source
|
|
80
|
+
override, preserves compiler and app settings, and replaces the old SDK folder
|
|
81
|
+
with the npm compatibility link. The previous real SDK folder and its Git
|
|
82
|
+
history remain in `hosanna-ui.before-npm`. It requires explicit replacement
|
|
83
|
+
and refuses to discard changes in a Git checkout. Move or commit those changes first.
|
|
84
|
+
Migration also updates exact known install, update, generation and cleanup
|
|
85
|
+
scripts. Custom scripts that select a framework source or generate inside the
|
|
86
|
+
SDK must be updated manually before migration; the command names them before
|
|
87
|
+
changing files. A failed migration restores app configuration, dependency
|
|
88
|
+
manifests, links and the previous SDK folder. After migration, run `npm rebuild`
|
|
89
|
+
if dependencies need their install scripts.
|
|
42
90
|
|
|
43
|
-
|
|
44
|
-
copy, a shared local checkout, and the legacy git/local modes:
|
|
91
|
+
For local framework development, use npm's normal local package support:
|
|
45
92
|
|
|
46
93
|
```bash
|
|
47
|
-
|
|
48
|
-
hst
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
remains the development-lane alias. Exact versions are immutable pins.
|
|
61
|
-
The same `HSC_LICENSE_KEY` used by the compiler authorizes source installation;
|
|
62
|
-
there is no separate Hosanna source-license environment variable.
|
|
63
|
-
|
|
64
|
-
Local `shared`, `embedded`, and `local` selections are private developer
|
|
65
|
-
overrides. They do not rewrite `hosanna.json`: Git projects store the selection
|
|
66
|
-
in worktree-specific Git metadata, so activating a local checkout cannot dirty
|
|
67
|
-
the project or leak a machine path into a commit. `hst config source` and
|
|
68
|
-
`hst env check` prominently report the active override, resolved checkout, and
|
|
69
|
-
the committed distribution/version it temporarily supersedes. Running
|
|
70
|
-
`hst sdk:install` or `hst framework:update` while an override is active preserves
|
|
71
|
-
the local checkout. Select `keygen` or `git` with `--install
|
|
72
|
-
--replace-existing` to clear the override and return to the committed source.
|
|
73
|
-
|
|
74
|
-
Use `--replace-existing` with `--install` when switching an existing project
|
|
75
|
-
between modes. Replacement is refused for an unrecognized or modified source
|
|
76
|
-
root; `--force` is required for a dirty git checkout. Embedded installs exclude
|
|
77
|
-
repository/build/secret state, write a content-hash manifest, and never modify
|
|
78
|
-
the source checkout. Shared installs validate the source and create a relative
|
|
79
|
-
symlink. Granular flavours and platform subsets are deliberately rejected with
|
|
80
|
-
`NOT SUPPORTED YET — use flavour "fullSource"`.
|
|
94
|
+
npm install --save-dev ../hosanna-ui
|
|
95
|
+
npx hst sdk:install
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
A declared dependency can also be redirected with `npm link`; the installer
|
|
99
|
+
resolves the linked package through the same npm path. To return to a release,
|
|
100
|
+
install the desired npm version and rerun `hst sdk:install`.
|
|
101
|
+
|
|
102
|
+
`hosanna.json` retains `transpiler-version` and app integration settings such as
|
|
103
|
+
`symlink-extra-folders`. Compiler installation and licensing are unchanged.
|
|
104
|
+
`config source`, `framework:update`, `framework:sync` and `framework:doctor`
|
|
105
|
+
were removed in tools 5. Framework delivery no longer uses Git clones, Keygen
|
|
106
|
+
source artifacts or private source overrides.
|
|
81
107
|
|
|
82
108
|
## Embedding as a library
|
|
83
109
|
|
|
@@ -295,25 +321,15 @@ See [RELEASE.md](RELEASE.md) for the full release process.
|
|
|
295
321
|
|
|
296
322
|
Quick reference:
|
|
297
323
|
```bash
|
|
298
|
-
npm run release -- patch
|
|
299
|
-
npm run release -- minor
|
|
300
|
-
npm run release -- major
|
|
324
|
+
npm run release -- patch --dry-run
|
|
325
|
+
npm run release -- minor --dry-run
|
|
326
|
+
npm run release -- major --dry-run
|
|
301
327
|
```
|
|
302
328
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
## CLI: configure-hosanna-url
|
|
308
|
-
|
|
309
|
-
- **purpose**: Updates `hosanna.json` with a new Hosanna UI Git URL under the `git-url` key.
|
|
310
|
-
- **usage**:
|
|
311
|
-
- `hst configure-hosanna-url https://github.com/YourOrg/hosanna-ui.git`
|
|
312
|
-
- `HOSANNA_UI_GIT_URL=https://github.com/YourOrg/hosanna-ui.git hst configure-hosanna-url`
|
|
313
|
-
- **behavior**:
|
|
314
|
-
- If no positional `gitUrl` is provided, the command falls back to the `HOSANNA_UI_GIT_URL` environment variable.
|
|
315
|
-
- If neither is provided, it prints a message and leaves `hosanna.json` unchanged.
|
|
316
|
-
- On success, it prints a sanitized URL (protocol + host + path) for logs.
|
|
329
|
+
The wrapper delegates to the root monorepo release command. Publication uses the
|
|
330
|
+
central `monorepo-release.yml` workflow after this package's npm trusted publisher
|
|
331
|
+
has been migrated. See [RELEASE.md](RELEASE.md) for the configuration and validation
|
|
332
|
+
requirements.
|
|
317
333
|
|
|
318
334
|
# Hosanna Tools CLI
|
|
319
335
|
|
|
@@ -337,12 +353,12 @@ Hosanna launches native Roku or Roku emulated in the browser. Other platform lau
|
|
|
337
353
|
```bash
|
|
338
354
|
hst run
|
|
339
355
|
hst run --last
|
|
340
|
-
hst run roku dev device --device 192.
|
|
356
|
+
hst run roku dev device --device 192.0.2.50
|
|
341
357
|
hst run roku dev emulator
|
|
342
358
|
hst run browser dev emulator
|
|
343
359
|
hst build roku dev device
|
|
344
360
|
hst target:list --json
|
|
345
|
-
hst launch roku --app-id dev --device 192.
|
|
361
|
+
hst launch roku --app-id dev --device 192.0.2.50
|
|
346
362
|
```
|
|
347
363
|
|
|
348
364
|
`web` aliases `browser`. Browser launches default to the `rokufhd` device preset. Existing development sessions are reused only when the requested app and port match. Configured run defaults live in `.hosanna-tools/run.json`.
|
|
@@ -430,10 +446,9 @@ npm run roku:build
|
|
|
430
446
|
### CI Commands (`ci:*`) - Continuous Integration
|
|
431
447
|
- `ci:project-actions --base <ref> [--head <ref>]` - Select `hst.json` `prScopeRules` actions for changed files; add `--run` to execute matched npm scripts
|
|
432
448
|
- `ci:extract-pkg-key` - Extract signing key from an existing signed Roku package as base64
|
|
433
|
-
- `config set --git-url` - Configure hosanna.json git-url from argument or environment
|
|
434
449
|
|
|
435
|
-
Project-specific PR rules belong in `hst.json
|
|
436
|
-
|
|
450
|
+
Project-specific PR rules belong in `hst.json`. The framework dependency and
|
|
451
|
+
version belong in `package.json` and `package-lock.json`:
|
|
437
452
|
|
|
438
453
|
```json
|
|
439
454
|
{
|
|
@@ -490,8 +505,8 @@ The installed SDK owns its app dependency contract in
|
|
|
490
505
|
Both maps are required. `hst doctor` and `hst env check` validate the exact
|
|
491
506
|
manifest, the app's direct `package.json` declarations, and the versions
|
|
492
507
|
actually available through the app's Node resolution path (including a
|
|
493
|
-
workspace-hoisted install).
|
|
494
|
-
|
|
508
|
+
workspace-hoisted install). The npm SDK must include this manifest; an
|
|
509
|
+
incomplete package fails the environment check.
|
|
495
510
|
|
|
496
511
|
`hst doctor --fix` and `hst env fix` add missing requirements and run one
|
|
497
512
|
app-root `npm install`. The repair is additive to the app's dependency set: it
|
|
@@ -508,10 +523,8 @@ rollback snapshot; run the workspace's package manager from its root instead.
|
|
|
508
523
|
If `npm install` fails, or the installed
|
|
509
524
|
versions still fail the audit afterward, `package.json` and npm lockfiles
|
|
510
525
|
(`package-lock.json` and `npm-shrinkwrap.json`) are restored to their original
|
|
511
|
-
contents.
|
|
512
|
-
|
|
513
|
-
after the new SDK is ready, so a framework upgrade cannot leave new app
|
|
514
|
-
requirements undeclared.
|
|
526
|
+
contents. `sdk:install` and `sdk:migrate` run the same reconciliation after
|
|
527
|
+
resolving the npm package, so framework requirements remain declared in the app.
|
|
515
528
|
|
|
516
529
|
Library callers can inspect or run the same focused operation through
|
|
517
530
|
`env.dependencies.audit({ projectRoot })` and
|
|
@@ -520,13 +533,12 @@ repair results without exiting the process.
|
|
|
520
533
|
|
|
521
534
|
### Framework Source Symlinks (semver-keyed registry)
|
|
522
535
|
|
|
523
|
-
`hst` symlinks framework source folders
|
|
536
|
+
`hst` symlinks framework source folders through the `hosanna-ui/` npm compatibility link into the
|
|
524
537
|
project (`src/hosanna-ui -> ../hosanna-ui/src/hosanna-ui`, etc.). Which folders
|
|
525
538
|
get linked is decided by a **semver-keyed registry**: an entry applies when the
|
|
526
539
|
installed framework version is **>=** its key, and the highest applicable key
|
|
527
540
|
wins. The installed version is read from `hosanna-ui/package.json` (prerelease
|
|
528
|
-
suffixes are ignored, so `
|
|
529
|
-
tags, branches, `@latest`, and `LOCAL_SDK` alike.
|
|
541
|
+
suffixes are ignored, so `2.0.0-next` counts as `2.0.0`).
|
|
530
542
|
|
|
531
543
|
**Built-in defaults** (`src/updater/symlink-registry.ts`):
|
|
532
544
|
|
|
@@ -534,10 +546,7 @@ tags, branches, `@latest`, and `LOCAL_SDK` alike.
|
|
|
534
546
|
|---|---|
|
|
535
547
|
| >= 1.0.0 | `hosanna-bridge-core`, `hosanna-bridge-http`, `hosanna-bridge-lib`, `hosanna-bridge-targets`, `hosanna-list`, `hosanna-ui` |
|
|
536
548
|
|
|
537
|
-
|
|
538
|
-
checkout's `package.json` version can lag the tag it was cut from (hosanna-ui
|
|
539
|
-
`v1.28.3` reads `1.28.1-next`), and folders absent from a checkout are already
|
|
540
|
-
skipped safely at sync time.
|
|
549
|
+
Folders absent from the installed package are skipped when syncing links.
|
|
541
550
|
|
|
542
551
|
`hst env check` always prints the active set, the matched registry version, and the
|
|
543
552
|
source (`built-in`, `hosanna.json override`, `+ N extra`). `hst env fix`
|
|
@@ -551,8 +560,6 @@ to the resolved defaults; cannot break them. Folder names are forgiving
|
|
|
551
560
|
|
|
552
561
|
```json
|
|
553
562
|
{
|
|
554
|
-
"git-url": "git@github.com:TantaWowa/hosanna-ui.git",
|
|
555
|
-
"sdk-version": "v1.31.0",
|
|
556
563
|
"symlink-extra-folders": ["hosanna-game/", "hosanna-game-examples/"]
|
|
557
564
|
}
|
|
558
565
|
```
|
|
@@ -599,6 +606,8 @@ silently break an install.
|
|
|
599
606
|
|
|
600
607
|
Applications own regular Vitest suites. Global setup comes from `@tantawowa/hosanna-tools/testing/vitest`; worker fixtures and matchers come from `@tantawowa/hosanna-tools/testing/vitest/fixture`; shared lifecycle, types, and helpers come from `@tantawowa/hosanna-tools/testing`. There is no HST test CLI or recording/replay format.
|
|
601
608
|
|
|
609
|
+
`timeoutMs` sets the limit for each launch/readiness stage and browser navigation during initial launch, runtime relaunch, and `hs.app.deepLink(...)`. Navigation still waits for the page's `load` event. The default is 60 seconds; a positive, finite `HS_TEST_TIMEOUT_MS` overrides the config. This is a per-stage limit, not a deadline for the whole test. Vitest's `testTimeout` and `hookTimeout`, and timeouts passed to individual assertion waits, remain separate.
|
|
610
|
+
|
|
602
611
|
Add `createHosannaReporter(config)` from `@tantawowa/hosanna-tools/testing/vitest/reporter` to the application's Vitest reporters. Every run then writes a self-contained JSON and HTML report under `test-results/<testRunId>/`, updates `test-results/latest.json` and `test-results/latest.html`, and includes every Vitest result plus any named visual proofs captured by the tests.
|
|
603
612
|
|
|
604
613
|
Tests can record a complete browser emulator or Roku device run:
|
package/dist/build-info.json
CHANGED
package/dist/cli.js
CHANGED
|
@@ -243,14 +243,6 @@ const RUN_PLATFORM_CHOICES = ['browser', 'web', 'roku'];
|
|
|
243
243
|
function stringArg(value) {
|
|
244
244
|
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
245
245
|
}
|
|
246
|
-
function stringArrayArg(value) {
|
|
247
|
-
if (typeof value === 'string')
|
|
248
|
-
return [value];
|
|
249
|
-
if (Array.isArray(value)) {
|
|
250
|
-
return value.filter((item) => typeof item === 'string');
|
|
251
|
-
}
|
|
252
|
-
return undefined;
|
|
253
|
-
}
|
|
254
246
|
function parseVideoCaptureRect(value) {
|
|
255
247
|
if (value === undefined)
|
|
256
248
|
return undefined;
|
|
@@ -391,7 +383,7 @@ async function runEnvironmentCommand(action, verbose) {
|
|
|
391
383
|
// Let yargs handle all commands including env
|
|
392
384
|
(0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
393
385
|
.version(`${buildVersion}\n git: ${buildGitHash}\n built: ${buildDate}`)
|
|
394
|
-
.usage(`Hosanna Tools CLI\nVersion: ${buildVersion}\nBuild Date: ${buildDate}\n\nCommand Groups:\n compiler:* Compiler lifecycle (install, status, list)\n config hosanna.json management (wizard, show, set)\n doctor Friendly environment/package check (use --fix to repair)\n env Environment checks and repair (check, fix, prepare-gitignore)\n dev:* Local development execution\n debugger:* Command debugger control\n mcp:* Hosanna MCP server control\n build Roku and Roku browser emulator builds\n run Roku and Roku browser emulator launches\n capture Standalone scenario video capture\n target:* Run target discovery and inventory\n roku:* Roku deployment, commands & packaging (run, command, package, map-stack)\n device:* Device discovery and run workflows\n generate:* Code and asset generation\n sdk:* Hosanna SDK/framework installation\n build-config:* Build/runtime configuration resolution\n ci:* Continuous integration helpers\n
|
|
386
|
+
.usage(`Hosanna Tools CLI\nVersion: ${buildVersion}\nBuild Date: ${buildDate}\n\nCommand Groups:\n compiler:* Compiler lifecycle (install, status, list)\n config hosanna.json management (wizard, show, set)\n doctor Friendly environment/package check (use --fix to repair)\n env Environment checks and repair (check, fix, prepare-gitignore)\n dev:* Local development execution\n debugger:* Command debugger control\n mcp:* Hosanna MCP server control\n build Roku and Roku browser emulator builds\n run Roku and Roku browser emulator launches\n capture Standalone scenario video capture\n target:* Run target discovery and inventory\n roku:* Roku deployment, commands & packaging (run, command, package, map-stack)\n device:* Device discovery and run workflows\n generate:* Code and asset generation\n sdk:* Hosanna SDK/framework installation\n build-config:* Build/runtime configuration resolution\n ci:* Continuous integration helpers\n license:* Hosanna compiler licensing\n secrets:* Portable .secrets files\n rasp:* RASP cert scripts`)
|
|
395
387
|
.option('verbose', {
|
|
396
388
|
type: 'boolean',
|
|
397
389
|
default: false,
|
|
@@ -962,84 +954,23 @@ async function runEnvironmentCommand(action, verbose) {
|
|
|
962
954
|
}
|
|
963
955
|
})
|
|
964
956
|
// remove old --env flag; env is now a subcommand
|
|
965
|
-
.command('config [action]
|
|
957
|
+
.command('config [action]', 'Show or update hosanna.json configuration from a curated catalog', yargs => yargs
|
|
966
958
|
.positional('action', {
|
|
967
959
|
type: 'string',
|
|
968
|
-
choices: ['show', 'set', 'wizard'
|
|
969
|
-
describe: 'show prints
|
|
960
|
+
choices: ['show', 'set', 'wizard'],
|
|
961
|
+
describe: 'show prints compiler config, set writes values from flags, wizard runs compiler setup',
|
|
970
962
|
})
|
|
971
|
-
.positional('mode', {
|
|
972
|
-
type: 'string',
|
|
973
|
-
choices: ['show', 'keygen', 'git', 'local', 'embedded', 'shared'],
|
|
974
|
-
describe: 'Source install mode when action is source',
|
|
975
|
-
})
|
|
976
|
-
.option('git-url', { type: 'string', describe: 'Set hosanna.json git-url' })
|
|
977
|
-
.option('sdk-version', { type: 'string', describe: 'Set hosanna.json sdk-version' })
|
|
978
|
-
.option('branch', { type: 'string', describe: 'Set hosanna.json branch; use an empty string to prefer sdk-version' })
|
|
979
963
|
.option('transpiler-version', { type: 'string', describe: 'Set hosanna.json transpiler-version' })
|
|
980
964
|
.option('config-catalog-url', { type: 'string', describe: 'Persist a remote catalog URL into hosanna.json' })
|
|
981
965
|
.option('catalog-url', { type: 'string', describe: 'Use a remote catalog URL for this run without writing it' })
|
|
982
|
-
.option('flavour', { type: 'string', choices: ['fullSource', 'core', 'game', 'full'], describe: 'Keygen source flavour when action is source (supported: fullSource)' })
|
|
983
|
-
.option('platforms', { type: 'string', array: true, describe: 'Future split-platform selection; omit for fullSource' })
|
|
984
|
-
.option('source-path', { type: 'string', describe: 'Hosanna UI checkout to copy for embedded mode or link for shared mode' })
|
|
985
|
-
.option('install', { type: 'boolean', default: false, describe: 'Install the selected source mode atomically after updating config' })
|
|
986
|
-
.option('replace-existing', { type: 'boolean', default: false, describe: 'Allow --install to replace an existing hosanna-ui source root when switching modes' })
|
|
987
|
-
.option('force', { type: 'boolean', default: false, describe: 'Allow --install to replace a dirty git checkout when used with --replace-existing' })
|
|
988
966
|
.option('fix', { type: 'boolean', default: false, describe: 'Run hst env fix after updating config' }), async (args) => {
|
|
989
967
|
if (args.verbose) {
|
|
990
968
|
process.env.HOSANNA_VERBOSE = '1';
|
|
991
969
|
process.env.HOSANNA_UPDATER_VERBOSE = '1';
|
|
992
970
|
}
|
|
993
971
|
const actionArg = typeof args.action === 'string' ? args.action : undefined;
|
|
994
|
-
if (actionArg === 'source') {
|
|
995
|
-
try {
|
|
996
|
-
const result = await (0, hosanna_config_js_1.runHosannaSourceConfig)({
|
|
997
|
-
cwd: process.cwd(),
|
|
998
|
-
mode: (typeof args.mode === 'string' ? args.mode : 'show'),
|
|
999
|
-
flavour: args.flavour,
|
|
1000
|
-
platforms: (0, hosanna_config_js_1.parsePlatformList)(stringArrayArg(args.platforms)),
|
|
1001
|
-
sourcePath: typeof args.sourcePath === 'string' ? args.sourcePath : undefined,
|
|
1002
|
-
sdkVersion: typeof args.sdkVersion === 'string' ? args.sdkVersion : undefined,
|
|
1003
|
-
gitUrl: typeof args.gitUrl === 'string' ? args.gitUrl : undefined,
|
|
1004
|
-
branch: typeof args.branch === 'string' ? args.branch : undefined,
|
|
1005
|
-
install: Boolean(args.install),
|
|
1006
|
-
replaceExisting: Boolean(args.replaceExisting),
|
|
1007
|
-
force: Boolean(args.force),
|
|
1008
|
-
writeStdout: text => console.info(text),
|
|
1009
|
-
});
|
|
1010
|
-
if (args.fix && result.updated) {
|
|
1011
|
-
const { fixAllEnvironmentIssues } = await Promise.resolve().then(() => __importStar(require('./lib/env-info.js')));
|
|
1012
|
-
const fixResult = await fixAllEnvironmentIssues(process.cwd());
|
|
1013
|
-
console.info(`\n${fixResult.message}`);
|
|
1014
|
-
if (fixResult.remainingIssues.length > 0) {
|
|
1015
|
-
console.info('\n❌ Remaining issues:');
|
|
1016
|
-
for (const issue of fixResult.remainingIssues) {
|
|
1017
|
-
console.info(` • ${issue}`);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
if (!process.env.VITEST)
|
|
1021
|
-
process.exit(fixResult.success ? 0 : 1);
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
|
-
if (!process.env.VITEST)
|
|
1025
|
-
process.exit(0);
|
|
1026
|
-
return;
|
|
1027
|
-
}
|
|
1028
|
-
catch (err) {
|
|
1029
|
-
console.error('❌ Failed to configure source install mode:', err instanceof Error ? err.message : err);
|
|
1030
|
-
if (!process.env.VITEST)
|
|
1031
|
-
process.exit(1);
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
972
|
const action = actionArg === 'show' || actionArg === 'set' ? actionArg : 'wizard';
|
|
1036
973
|
const updates = {};
|
|
1037
|
-
if (typeof args.gitUrl === 'string')
|
|
1038
|
-
updates['git-url'] = args.gitUrl;
|
|
1039
|
-
if (typeof args.sdkVersion === 'string')
|
|
1040
|
-
updates['sdk-version'] = args.sdkVersion;
|
|
1041
|
-
if (typeof args.branch === 'string')
|
|
1042
|
-
updates.branch = args.branch;
|
|
1043
974
|
if (typeof args.transpilerVersion === 'string')
|
|
1044
975
|
updates['transpiler-version'] = args.transpilerVersion;
|
|
1045
976
|
if (typeof args.configCatalogUrl === 'string')
|
|
@@ -1447,124 +1378,33 @@ async function runEnvironmentCommand(action, verbose) {
|
|
|
1447
1378
|
process.exit(1);
|
|
1448
1379
|
}
|
|
1449
1380
|
})
|
|
1450
|
-
.command('sdk:install', '
|
|
1451
|
-
.option('force', { type: 'boolean', default: false, describe: 'Reinstall even if the requested version is already installed (keygen mode)' })
|
|
1452
|
-
.option('skip-consumer-dependencies', { type: 'boolean', default: false, describe: 'Install the SDK without changing the app dependency manifest or installing app dependencies' }), async (args) => {
|
|
1453
|
-
if (args.verbose) {
|
|
1454
|
-
process.env.HOSANNA_VERBOSE = '1';
|
|
1455
|
-
process.env.HOSANNA_UPDATER_VERBOSE = '1';
|
|
1456
|
-
}
|
|
1457
|
-
console.info('Running sdk:install command...');
|
|
1458
|
-
try {
|
|
1459
|
-
const skipConsumerDependencyReconciliation = Boolean(args['skip-consumer-dependencies']);
|
|
1460
|
-
const { assertLocalSourceOverrideInstalled, readLocalSourceOverride } = await Promise.resolve().then(() => __importStar(require('./lib/local-source-override.js')));
|
|
1461
|
-
const localOverride = readLocalSourceOverride(process.cwd());
|
|
1462
|
-
if (localOverride) {
|
|
1463
|
-
assertLocalSourceOverrideInstalled(process.cwd(), localOverride);
|
|
1464
|
-
const { prepareLocalSdkIntegration } = await Promise.resolve().then(() => __importStar(require('./updater/local-sdk-manager.js')));
|
|
1465
|
-
prepareLocalSdkIntegration(process.cwd(), { skipConsumerDependencyReconciliation });
|
|
1466
|
-
console.info(`Private ${localOverride.mode} Hosanna source override is active; preserved the local SDK and skipped the committed distribution install.`);
|
|
1467
|
-
console.info('sdk:install command completed.');
|
|
1468
|
-
process.exit(0);
|
|
1469
|
-
return;
|
|
1470
|
-
}
|
|
1471
|
-
// Keygen-distributed projects bypass the git flow entirely.
|
|
1472
|
-
const hosannaJsonPath = path.resolve(process.cwd(), 'hosanna.json');
|
|
1473
|
-
let distribution;
|
|
1474
|
-
if (fs.existsSync(hosannaJsonPath)) {
|
|
1475
|
-
try {
|
|
1476
|
-
distribution = JSON.parse(fs.readFileSync(hosannaJsonPath, 'utf-8')).distribution;
|
|
1477
|
-
}
|
|
1478
|
-
catch ( /* fall through to git flow which reports config errors */_a) { /* fall through to git flow which reports config errors */ }
|
|
1479
|
-
}
|
|
1480
|
-
if (distribution === 'keygen') {
|
|
1481
|
-
const mod = await Promise.resolve().then(() => __importStar(require('./updater/framework-installer.js')));
|
|
1482
|
-
await mod.installFrameworkFromKeygen({ force: Boolean(args.force), skipConsumerDependencyReconciliation });
|
|
1483
|
-
}
|
|
1484
|
-
else {
|
|
1485
|
-
await (0, sdk_manager_js_1.installSdk)(false, false, true, { skipConsumerDependencyReconciliation });
|
|
1486
|
-
}
|
|
1487
|
-
console.info('sdk:install command completed.');
|
|
1488
|
-
process.exit(0); // Exit after successful completion
|
|
1489
|
-
}
|
|
1490
|
-
catch (err) {
|
|
1491
|
-
console.error('An error occurred during the install process:', err);
|
|
1492
|
-
process.exit(1); // Exit with error code on failure
|
|
1493
|
-
}
|
|
1494
|
-
})
|
|
1495
|
-
.command('framework:update', 'Update the keygen-distributed hosanna-ui folder to the version in hosanna.json (no-op when already current)', yargs => yargs
|
|
1496
|
-
.option('force', { type: 'boolean', default: false, describe: 'Reinstall even if the requested version is already installed' }), async (args) => {
|
|
1497
|
-
if (args.verbose) {
|
|
1498
|
-
process.env.HOSANNA_VERBOSE = '1';
|
|
1499
|
-
process.env.HOSANNA_UPDATER_VERBOSE = '1';
|
|
1500
|
-
}
|
|
1381
|
+
.command('sdk:install', 'Integrate the npm-installed @tantawowa/hosanna-ui package and repair its source links', yargs => yargs.option('skip-consumer-dependencies', { type: 'boolean', default: false, describe: 'Repair links without changing app dependency declarations' }), async (args) => {
|
|
1501
1382
|
try {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
if (localOverride) {
|
|
1505
|
-
assertLocalSourceOverrideInstalled(process.cwd(), localOverride);
|
|
1506
|
-
const { prepareLocalSdkIntegration } = await Promise.resolve().then(() => __importStar(require('./updater/local-sdk-manager.js')));
|
|
1507
|
-
prepareLocalSdkIntegration(process.cwd());
|
|
1508
|
-
console.info(`Private ${localOverride.mode} Hosanna source override is active; preserved the local SDK and skipped framework:update.`);
|
|
1383
|
+
await (0, sdk_manager_js_1.installSdk)({ skipConsumerDependencyReconciliation: Boolean(args['skip-consumer-dependencies']) });
|
|
1384
|
+
if (!process.env.VITEST)
|
|
1509
1385
|
process.exit(0);
|
|
1510
|
-
return;
|
|
1511
|
-
}
|
|
1512
|
-
const mod = await Promise.resolve().then(() => __importStar(require('./updater/framework-installer.js')));
|
|
1513
|
-
await mod.installFrameworkFromKeygen({ force: Boolean(args.force) });
|
|
1514
|
-
process.exit(0);
|
|
1515
1386
|
}
|
|
1516
|
-
catch (
|
|
1517
|
-
console.error(
|
|
1518
|
-
process.
|
|
1387
|
+
catch (error) {
|
|
1388
|
+
console.error(error instanceof Error ? error.message : error);
|
|
1389
|
+
if (!process.env.VITEST)
|
|
1390
|
+
process.exit(1);
|
|
1519
1391
|
}
|
|
1520
1392
|
})
|
|
1521
|
-
.command('
|
|
1522
|
-
.option('
|
|
1523
|
-
.option('
|
|
1524
|
-
.option('dry-run', { type: 'boolean', default: false, describe: 'Show what would be pushed without pushing' })
|
|
1525
|
-
.option('init', { type: 'boolean', default: false, describe: 'Create a template registry file and exit' })
|
|
1526
|
-
.example('$0 framework:sync', 'Sync all registered client forks')
|
|
1527
|
-
.example('$0 framework:sync --client ewtn --dry-run', 'Preview a sync for one client'), async (args) => {
|
|
1393
|
+
.command('sdk:migrate', 'Migrate an existing app to its npm-installed framework, preserving compiler configuration', yargs => yargs
|
|
1394
|
+
.option('replace-existing', { type: 'boolean', default: false, describe: 'Replace the old SDK folder or link; dirty Git checkouts are always protected' })
|
|
1395
|
+
.option('skip-consumer-dependencies', { type: 'boolean', default: false, describe: 'Migrate config and links without changing app dependency declarations' }), async (args) => {
|
|
1528
1396
|
try {
|
|
1529
|
-
|
|
1530
|
-
if (
|
|
1531
|
-
const filePath = mod.initRegistry(args.registry);
|
|
1532
|
-
console.info(`✅ Created sync registry template: ${filePath}`);
|
|
1533
|
-
console.info('Edit it to add your clients, then run: hst framework:sync');
|
|
1397
|
+
await (0, sdk_manager_js_1.migrateSdk)({ replaceExisting: Boolean(args['replace-existing']), skipConsumerDependencyReconciliation: Boolean(args['skip-consumer-dependencies']) });
|
|
1398
|
+
if (!process.env.VITEST)
|
|
1534
1399
|
process.exit(0);
|
|
1535
|
-
}
|
|
1536
|
-
const results = await mod.syncFrameworkForks({
|
|
1537
|
-
registryPath: args.registry,
|
|
1538
|
-
client: args.client,
|
|
1539
|
-
dryRun: Boolean(args['dry-run']),
|
|
1540
|
-
});
|
|
1541
|
-
const ok = mod.printSyncSummary(results, Boolean(args['dry-run']));
|
|
1542
|
-
process.exit(ok ? 0 : 1);
|
|
1543
|
-
}
|
|
1544
|
-
catch (err) {
|
|
1545
|
-
console.error('❌ framework:sync failed:', err instanceof Error ? err.message : err);
|
|
1546
|
-
process.exit(1);
|
|
1547
|
-
}
|
|
1548
|
-
})
|
|
1549
|
-
.command('framework:doctor', 'Maintainer: validate tier-1 client forks (reachability, hosanna.json git-url/schema, sdk-version tags)', yargs => yargs
|
|
1550
|
-
.option('client', { type: 'string', describe: 'Check a single named client from the registry (default: all clients)' })
|
|
1551
|
-
.option('registry', { type: 'string', describe: 'Path to the sync registry (default: ~/.hosanna/sync-clients.json)' })
|
|
1552
|
-
.example('$0 framework:doctor', 'Validate all registered client forks'), async (args) => {
|
|
1553
|
-
try {
|
|
1554
|
-
const mod = await Promise.resolve().then(() => __importStar(require('./support-tools/framework-sync.js')));
|
|
1555
|
-
const issues = await mod.doctorFrameworkForks({
|
|
1556
|
-
registryPath: args.registry,
|
|
1557
|
-
client: args.client,
|
|
1558
|
-
});
|
|
1559
|
-
const ok = mod.printDoctorSummary(issues);
|
|
1560
|
-
process.exit(ok ? 0 : 1);
|
|
1561
1400
|
}
|
|
1562
|
-
catch (
|
|
1563
|
-
console.error(
|
|
1564
|
-
process.
|
|
1401
|
+
catch (error) {
|
|
1402
|
+
console.error(error instanceof Error ? error.message : error);
|
|
1403
|
+
if (!process.env.VITEST)
|
|
1404
|
+
process.exit(1);
|
|
1565
1405
|
}
|
|
1566
1406
|
})
|
|
1567
|
-
.command('license:activate <key>', 'Store your Hosanna
|
|
1407
|
+
.command('license:activate <key>', 'Store your Hosanna compiler license key (~/.hosanna/license.key) after validating it', yargs => yargs
|
|
1568
1408
|
.positional('key', { type: 'string', demandOption: true, describe: 'License key issued for your organization' }), async (args) => {
|
|
1569
1409
|
try {
|
|
1570
1410
|
const mod = await Promise.resolve().then(() => __importStar(require('./updater/license-manager.js')));
|
|
@@ -1591,7 +1431,7 @@ async function runEnvironmentCommand(action, verbose) {
|
|
|
1591
1431
|
process.exit(1);
|
|
1592
1432
|
}
|
|
1593
1433
|
})
|
|
1594
|
-
.command('license:status', 'Validate the stored license and print its entitlements
|
|
1434
|
+
.command('license:status', 'Validate the stored compiler license and print its entitlements', yargs => yargs, async () => {
|
|
1595
1435
|
try {
|
|
1596
1436
|
const mod = await Promise.resolve().then(() => __importStar(require('./updater/license-manager.js')));
|
|
1597
1437
|
const credential = mod.requireLicenseCredential();
|
|
@@ -1607,10 +1447,6 @@ async function runEnvironmentCommand(action, verbose) {
|
|
|
1607
1447
|
if (info.validation.expiry)
|
|
1608
1448
|
console.info(` Expires: ${info.validation.expiry}`);
|
|
1609
1449
|
console.info(` Credential: ${credential.source === 'environment' ? 'HSC_LICENSE_KEY' : credential.filePath}`);
|
|
1610
|
-
const flavours = mod.entitledFlavours(info.entitlements);
|
|
1611
|
-
const platforms = mod.entitledPlatforms(info.entitlements);
|
|
1612
|
-
console.info(` Flavour: ${flavours.length ? flavours[flavours.length - 1] : '(none)'}`);
|
|
1613
|
-
console.info(` Platforms: ${platforms.length ? platforms.join(', ') : '(none)'}`);
|
|
1614
1450
|
console.info(` Entitlements: ${info.entitlements.join(', ') || '(none)'}`);
|
|
1615
1451
|
for (const warning of mod.getLicenseConfigurationWarnings()) {
|
|
1616
1452
|
console.warn(` ⚠ ${warning}`);
|
|
@@ -1943,8 +1779,8 @@ async function runEnvironmentCommand(action, verbose) {
|
|
|
1943
1779
|
.example('$0 run --last', 'Immediately run on the last selected destination')
|
|
1944
1780
|
.example('$0 run --platform roku --target emulator', 'Start/reuse the Roku TV web emulator')
|
|
1945
1781
|
.example('$0 run --platform roku --target device --device "living room"', 'Build, deploy, launch, and stream logs on a Roku device')
|
|
1946
|
-
.example('$0 run roku dev device --app
|
|
1947
|
-
.example('$0 run roku prod device --hsc-project platforms/hsconfig.
|
|
1782
|
+
.example('$0 run roku dev device --app client2', 'Run a configured monorepo app/flavor')
|
|
1783
|
+
.example('$0 run roku prod device --hsc-project platforms/hsconfig.client2.prod.json', 'Override the Roku HSC project file'), async (args) => {
|
|
1948
1784
|
await runRunPlanCommand('run', args);
|
|
1949
1785
|
})
|
|
1950
1786
|
.command('device:run', 'Build, deploy, launch, and stream logs for a device', yargs => yargs
|
|
@@ -2519,9 +2355,9 @@ async function runEnvironmentCommand(action, verbose) {
|
|
|
2519
2355
|
default: false,
|
|
2520
2356
|
describe: 'Keep the temporary RASP capture JSON/screenshots after the script is written.',
|
|
2521
2357
|
})
|
|
2522
|
-
.example('$0 rasp:capture login --channel-name "
|
|
2523
|
-
.example('$0 rasp:capture login --channel-name "
|
|
2524
|
-
.example('$0 rasp:capture login --channel-name "
|
|
2358
|
+
.example('$0 rasp:capture login --channel-name "Client2"', 'Record and export to rasp-scripts/login.rasp')
|
|
2359
|
+
.example('$0 rasp:capture login --channel-name "Client2" --login-text "user@example.com" --password-text "MyPass1!"', 'Default credential flow with custom text')
|
|
2360
|
+
.example('$0 rasp:capture login --channel-name "Client2" --credential-flow ./flow.rasp --login-text U --password-text P', 'Override flow via YAML file'), async (args) => {
|
|
2525
2361
|
var _a, _b;
|
|
2526
2362
|
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
2527
2363
|
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|