@tantawowa/hosanna-tools 3.18.0 → 3.18.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.
Files changed (39) hide show
  1. package/README.md +50 -0
  2. package/dist/build-info.json +3 -3
  3. package/dist/cli.js +52 -45
  4. package/dist/cli.js.map +1 -1
  5. package/dist/index.d.ts +11 -1
  6. package/dist/index.js +16 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/env-info.d.ts +11 -3
  9. package/dist/lib/env-info.js +79 -4
  10. package/dist/lib/env-info.js.map +1 -1
  11. package/dist/lib/hosanna-config.d.ts +3 -0
  12. package/dist/lib/hosanna-config.js +51 -117
  13. package/dist/lib/hosanna-config.js.map +1 -1
  14. package/dist/lib/project-dependencies.d.ts +70 -0
  15. package/dist/lib/project-dependencies.js +699 -0
  16. package/dist/lib/project-dependencies.js.map +1 -0
  17. package/dist/lib/project-file-safety.d.ts +7 -0
  18. package/dist/lib/project-file-safety.js +32 -0
  19. package/dist/lib/project-file-safety.js.map +1 -0
  20. package/dist/native/native-project.d.ts +1 -0
  21. package/dist/native/native-project.js +41 -9
  22. package/dist/native/native-project.js.map +1 -1
  23. package/dist/native/templates/android/gradle-wrapper.jar +0 -0
  24. package/dist/native/templates/android/gradle-wrapper.properties +2 -0
  25. package/dist/native/templates/android/gradlew +247 -7
  26. package/dist/native/templates/android/gradlew.bat +92 -10
  27. package/dist/updater/framework-installer.d.ts +7 -0
  28. package/dist/updater/framework-installer.js +77 -74
  29. package/dist/updater/framework-installer.js.map +1 -1
  30. package/dist/updater/local-sdk-manager.d.ts +9 -1
  31. package/dist/updater/local-sdk-manager.js +30 -3
  32. package/dist/updater/local-sdk-manager.js.map +1 -1
  33. package/dist/updater/project-install-transaction.d.ts +78 -0
  34. package/dist/updater/project-install-transaction.js +414 -0
  35. package/dist/updater/project-install-transaction.js.map +1 -0
  36. package/dist/updater/sdk-manager.d.ts +9 -1
  37. package/dist/updater/sdk-manager.js +78 -12
  38. package/dist/updater/sdk-manager.js.map +1 -1
  39. package/package.json +4 -1
package/README.md CHANGED
@@ -100,6 +100,8 @@ Common build-script replacements:
100
100
  | `npx hst capture ios --device 'iPhone 17 Pro'` | `await capture.start({ platform: 'ios', device: 'iPhone 17 Pro' })` |
101
101
  | `npx hst secrets:check` | `await secrets.check({ cwd: process.cwd() })` |
102
102
  | `npx hst env check` | `await env.check({ cwd: process.cwd() })` |
103
+ | `npx hst doctor` | `await env.check({ cwd: process.cwd() })` |
104
+ | `npx hst doctor --fix` | `await env.check({ cwd: process.cwd(), fix: true })` |
103
105
 
104
106
  Long-running APIs such as `dev.run`, `debugger.start`, `mcp.start`, and RASP-owned certification capture workflows keep the same operational behavior as the corresponding CLI commands: they start services, attach to debuggers, or wait for user/session activity. `mcp.start` and `dev.run` are wired for programmatic no-exit behavior through the top-level API.
105
107
 
@@ -449,10 +451,56 @@ npm run apple:build-code
449
451
  Shared options: `--file` (secrets path), `--template` (template path for `check` / `init` / `list --template`), `--format text|json`.
450
452
 
451
453
  ### Environment Commands (`env ...`) - Environment Management
454
+ - `doctor` - Run the same read-only checks as `env check`, including required app packages
455
+ - `doctor --fix` - Run the same repair path as `env fix`
452
456
  - `env check` - Print environment information and run checks
453
457
  - `env fix` - Check and repair environment issues
454
458
  - `env prepare-gitignore` - Ensure .gitignore contains required entries
455
459
 
460
+ #### Hosanna consumer dependencies
461
+
462
+ The installed SDK owns its app dependency contract in
463
+ `hosanna-ui/hosanna-consumer-dependencies.json`:
464
+
465
+ ```json
466
+ {
467
+ "schemaVersion": 1,
468
+ "dependencies": { "lottie-web": "^5.13.0" },
469
+ "devDependencies": { "@types/crypto-js": "^4.2.2" }
470
+ }
471
+ ```
472
+
473
+ Both maps are required. `hst doctor` and `hst env check` validate the exact
474
+ manifest, the app's direct `package.json` declarations, and the versions
475
+ actually available through the app's Node resolution path (including a
476
+ workspace-hoisted install). An older SDK without the manifest is reported as a
477
+ supported legacy install with no requirements.
478
+
479
+ `hst doctor --fix` and `hst env fix` add missing requirements and run one
480
+ app-root `npm install`. The repair is additive to the app's dependency set: it
481
+ does not remove unrelated packages. It may move a compatible required package
482
+ out of `devDependencies` or `optionalDependencies` so a runtime requirement is
483
+ installed reliably. Existing compatible app ranges are preserved. An existing
484
+ range that can select versions outside the SDK's required range is reported as
485
+ a conflict and is not overwritten.
486
+
487
+ Projects that select another package manager or ship its lockfile are left for
488
+ that package manager to repair. Workspace members are audited, but automatic
489
+ repair is blocked so an ancestor lockfile is never changed without a matching
490
+ rollback snapshot; run the workspace's package manager from its root instead.
491
+ If `npm install` fails, or the installed
492
+ versions still fail the audit afterward, `package.json` and npm lockfiles
493
+ (`package-lock.json` and `npm-shrinkwrap.json`) are restored to their original
494
+ contents. SDK installs and updates—including
495
+ Git, Keygen, local, embedded, and shared source modes—run the same reconciliation
496
+ after the new SDK is ready, so a framework upgrade cannot leave new app
497
+ requirements undeclared.
498
+
499
+ Library callers can inspect or run the same focused operation through
500
+ `env.dependencies.audit({ projectRoot })` and
501
+ `env.dependencies.reconcile({ projectRoot })`; both return structured audit and
502
+ repair results without exiting the process.
503
+
456
504
  ### Framework Source Symlinks (semver-keyed registry)
457
505
 
458
506
  `hst` symlinks framework source folders from the `hosanna-ui/` checkout into the
@@ -679,6 +727,8 @@ hst secrets:exec -- npm run build
679
727
  hst secrets:init
680
728
 
681
729
  # Environment management
730
+ hst doctor # Read-only environment and package audit
731
+ hst doctor --fix # Repair issues and install missing requirements
682
732
  hst env fix # Check and fix environment issues
683
733
  hst env prepare-gitignore # Update .gitignore
684
734
 
@@ -1,6 +1,6 @@
1
1
  {
2
- "buildDate": "2026-08-14T06:25:48+00:00",
3
- "buildDateISO": "2026-08-14T06:25:48.573Z",
2
+ "buildDate": "2026-08-15T19:50:20+00:00",
3
+ "buildDateISO": "2026-08-15T19:50:20.748Z",
4
4
  "timeZone": "UTC",
5
- "gitHash": "ba52fa6"
5
+ "gitHash": "1be28fb"
6
6
  }
package/dist/cli.js CHANGED
@@ -399,10 +399,49 @@ catch (err) {
399
399
  /*******************************************************************
400
400
  * CLI Handling
401
401
  *******************************************************************/
402
+ async function runEnvironmentCommand(action, verbose) {
403
+ if (verbose) {
404
+ process.env.HOSANNA_VERBOSE = '1';
405
+ process.env.HOSANNA_UPDATER_VERBOSE = '1';
406
+ }
407
+ const info = (0, env_info_js_1.collectEnvInfo)(process.cwd());
408
+ console.info((0, env_info_js_1.formatEnvReportWithChecks)(info));
409
+ const ok = (0, env_info_js_1.allEnvChecksPass)(info);
410
+ if (action === 'check') {
411
+ if (!process.env.VITEST)
412
+ process.exit(ok ? 0 : 1);
413
+ return;
414
+ }
415
+ if (ok) {
416
+ console.info('\n✅ All environment checks passed - no fixes needed.');
417
+ if (!process.env.VITEST)
418
+ process.exit(0);
419
+ return;
420
+ }
421
+ const { fixAllEnvironmentIssues } = await Promise.resolve().then(() => __importStar(require('./lib/env-info.js')));
422
+ console.info('');
423
+ const fixResult = await fixAllEnvironmentIssues(process.cwd());
424
+ console.info(`\n${fixResult.message}`);
425
+ if (fixResult.remainingIssues.length > 0) {
426
+ console.info('\n❌ Remaining issues:');
427
+ for (const issue of fixResult.remainingIssues) {
428
+ console.info(` • ${issue}`);
429
+ }
430
+ }
431
+ if (fixResult.success && fixResult.remainingIssues.length === 0) {
432
+ if (!process.env.VITEST)
433
+ process.exit(0);
434
+ return;
435
+ }
436
+ const updatedInfo = (0, env_info_js_1.collectEnvInfo)(process.cwd());
437
+ const updatedOk = (0, env_info_js_1.allEnvChecksPass)(updatedInfo);
438
+ if (!process.env.VITEST)
439
+ process.exit(updatedOk ? 0 : 1);
440
+ }
402
441
  // Let yargs handle all commands including env
403
442
  (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
404
443
  .version(`${buildVersion}\n git: ${buildGitHash}\n built: ${buildDate}`)
405
- .usage('$0 [command] [options]', `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 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 Cross-platform build orchestration\n run Cross-platform launch orchestration\n capture Standalone scenario video capture\n native:* Native platform bootstrap and validation\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 framework:* Framework distribution helpers\n license:* Hosanna framework licensing\n secrets:* Portable .secrets files\n rasp:* RASP cert scripts`)
444
+ .usage('$0 [command] [options]', `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 Cross-platform build orchestration\n run Cross-platform launch orchestration\n capture Standalone scenario video capture\n native:* Native platform bootstrap and validation\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 framework:* Framework distribution helpers\n license:* Hosanna framework licensing\n secrets:* Portable .secrets files\n rasp:* RASP cert scripts`)
406
445
  .option('verbose', {
407
446
  type: 'boolean',
408
447
  default: false,
@@ -1180,56 +1219,24 @@ catch (err) {
1180
1219
  choices: ['check', 'fix', 'prepare-gitignore'],
1181
1220
  describe: 'check prints environment status, fix repairs version mismatches, prepare-gitignore updates .gitignore',
1182
1221
  }), async (args) => {
1183
- if (args.verbose) {
1184
- process.env.HOSANNA_VERBOSE = '1';
1185
- process.env.HOSANNA_UPDATER_VERBOSE = '1';
1186
- }
1187
1222
  if (args.action === 'prepare-gitignore') {
1223
+ if (args.verbose) {
1224
+ process.env.HOSANNA_VERBOSE = '1';
1225
+ process.env.HOSANNA_UPDATER_VERBOSE = '1';
1226
+ }
1188
1227
  console.info('Preparing .gitignore...');
1189
1228
  (0, sdk_manager_js_1.prepareGitIgnore)();
1190
1229
  console.info('.gitignore preparation completed.');
1191
1230
  return;
1192
1231
  }
1193
- const info = (0, env_info_js_1.collectEnvInfo)(process.cwd());
1194
- const report = (0, env_info_js_1.formatEnvReportWithChecks)(info);
1195
- console.info(report);
1196
- const ok = (0, env_info_js_1.allEnvChecksPass)(info);
1197
- if (args.action === 'check') {
1198
- if (!process.env.VITEST) {
1199
- process.exit(ok ? 0 : 1);
1200
- }
1201
- return;
1202
- }
1203
- if (ok) {
1204
- console.info('\n✅ All environment checks passed - no fixes needed.');
1205
- }
1206
- else {
1207
- const { fixAllEnvironmentIssues } = await Promise.resolve().then(() => __importStar(require('./lib/env-info.js')));
1208
- console.info('');
1209
- const fixResult = await fixAllEnvironmentIssues(process.cwd());
1210
- console.info(`\n${fixResult.message}`);
1211
- if (fixResult.remainingIssues.length > 0) {
1212
- console.info('\n❌ Remaining issues:');
1213
- for (const issue of fixResult.remainingIssues) {
1214
- console.info(` • ${issue}`);
1215
- }
1216
- }
1217
- if (fixResult.success && fixResult.remainingIssues.length === 0) {
1218
- if (!process.env.VITEST) {
1219
- process.exit(0);
1220
- }
1221
- return;
1222
- }
1223
- const updatedInfo = (0, env_info_js_1.collectEnvInfo)(process.cwd());
1224
- const updatedOk = (0, env_info_js_1.allEnvChecksPass)(updatedInfo);
1225
- if (!process.env.VITEST) {
1226
- process.exit(updatedOk ? 0 : 1);
1227
- }
1228
- return;
1229
- }
1230
- if (!process.env.VITEST) {
1231
- process.exit(0);
1232
- }
1232
+ await runEnvironmentCommand(args.action, Boolean(args.verbose));
1233
+ })
1234
+ .command('doctor', 'Check the local Hosanna environment and required consumer packages', yargs => yargs.option('fix', {
1235
+ type: 'boolean',
1236
+ default: false,
1237
+ describe: 'Repair environment issues and install missing consumer packages',
1238
+ }), async (args) => {
1239
+ await runEnvironmentCommand(args.fix ? 'fix' : 'check', Boolean(args.verbose));
1233
1240
  })
1234
1241
  .command('debugger:start', 'Start the command debugger WebSocket proxy', yargs => yargs
1235
1242
  .option('webAppPort', { type: 'number', description: 'Port for web app client', default: 59151 })