@lenso/cli 0.3.0 → 0.5.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 CHANGED
@@ -193,6 +193,23 @@ identity plus the expected `normal` or `restore` mode before committing durable
193
193
  evidence. A healthy process with the wrong workload mode is treated as a failed
194
194
  authority transfer and is fenced again.
195
195
 
196
+ For the complete local development path, start the generated Host, every
197
+ auto-start Service in `lenso.workspace.json`, and a connected Console with one
198
+ command:
199
+
200
+ ```sh
201
+ cd ./my-lenso-host
202
+ lenso dev up --console-root ../lenso-console
203
+ ```
204
+
205
+ The first run securely prompts for the local Operator password. Automation can
206
+ pass `--operator-password-file` with an owner-only regular file. The command
207
+ creates loopback-only enrollment evidence, starts and migrates both Stores,
208
+ builds the Console, configures or reuses the durable Operator, reconciles
209
+ Module-owned UI artifacts, and connects the exact topology. Ctrl-C stops the
210
+ Host, Console, and only the Services started by that invocation. Story is a
211
+ Console-owned linked surface; it does not require a separate Module install.
212
+
196
213
  After installing and starting the independent Lenso Console Service, create its
197
214
  first password user and bootstrap that user as the first Console Operator from
198
215
  outside the Service. In an interactive terminal, the CLI securely prompts for
@@ -218,6 +235,40 @@ existing identity with `--identifier` or `--user-id`. Restart the Console API
218
235
  and Worker after bootstrapping. Business Service users and Auth state are never
219
236
  modified.
220
237
 
238
+ After upgrading the CLI, reconcile an existing Operator with the current
239
+ minimum scopes idempotently:
240
+
241
+ ```sh
242
+ lenso console operator configure \
243
+ --console-root ../lenso-console \
244
+ --identifier admin@example.com
245
+ ```
246
+
247
+ Both commands persist the user in the Console Access administrator store and
248
+ maintain the compatibility Auth scope configuration. The first administrator
249
+ is the durable Console superadmin; later configured users are administrators.
250
+
251
+ This preserves unrelated operators and explicit extra scopes while adding the
252
+ System read/connect, artifact reconciliation, Surface Gateway, Auth, and Story
253
+ capabilities required by the current Console workflow.
254
+
255
+ Apply prepared signed connection evidence through one public, idempotent CLI
256
+ entrypoint instead of a sequence of custom HTTP calls:
257
+
258
+ ```sh
259
+ LENSO_CONSOLE_TOKEN='<operator-session-token>' \
260
+ lenso console connect \
261
+ --console-url http://127.0.0.1:3030 \
262
+ --bundle .lenso/console-connect.json
263
+ ```
264
+
265
+ The `lenso.console-connect.v1` bundle contains signed enrollment receipts, an
266
+ optional exact `console_composition` artifact effect, and the digest-bound
267
+ System Connection request. The command reuses existing enrollments, reconciles
268
+ artifacts, connects the System, and fails unless Console returns `connected`.
269
+ Use `--token-file` with a private regular file for non-interactive operation;
270
+ tokens and signing material are never printed or stored in the bundle.
271
+
221
272
  The generated host depends on the crates.io `lenso` crate with the `host`
222
273
  feature, which is the current narrow host API for booting API, worker, and
223
274
  migration entrypoints. See
@@ -228,7 +279,9 @@ for the host-facade roadmap.
228
279
  the template Postgres service, runs migrations, then keeps the API and worker
229
280
  running until Ctrl-C. New hosts run them in one local process; pass
230
281
  `--separate-worker` when you want two child processes. Use `--skip-db` or
231
- `--skip-migrate` when you already have those steps covered.
282
+ `--skip-migrate` when you already have those steps covered. `lenso dev up`
283
+ creates a missing private `.env`, choosing free loopback ports when the template
284
+ defaults are occupied; an existing `.env` remains authoritative.
232
285
 
233
286
  ## Scaffold a module
234
287
 
@@ -420,10 +473,34 @@ Workloads, move data, or change authority. Use `--repo-root` and
420
473
  `--modules-root` when the Module sources are not under the current repository's
421
474
  default `modules/` directory.
422
475
 
423
- Generated TS and Rust services also support `--check-release` to print the
424
- development module release descriptor before packaging.
425
- Before handing a service to another app or deployment pipeline, package-check
426
- the project and then emit a local service artifact:
476
+ Generated TypeScript services expose the current Provider contract directly:
477
+
478
+ ```sh
479
+ pnpm check
480
+ pnpm module:release > lenso.module-release.json
481
+ pnpm start
482
+ ```
483
+
484
+ `pnpm start` serves the exact `lenso.provider.v1` descriptor, invocation,
485
+ recovery, and acknowledgement endpoints. The descriptor digests are the same
486
+ ones emitted in `lenso.module-release.json`.
487
+
488
+ Install that release into the Host runtime inputs with the Provider URL, not
489
+ the legacy Service discovery URL:
490
+
491
+ ```sh
492
+ lenso module install ./lenso.module-release.json \
493
+ --base-url http://127.0.0.1:4100/lenso/provider/v1 \
494
+ --repo-root ../my-lenso-host
495
+ ```
496
+
497
+ This writes `lenso.modules.json`, `lenso.modules.lock.json`, the Module Planning
498
+ Context, and the local Service Installation Set consumed by Host startup. It
499
+ does not write `SERVICE_MODULES` or treat an old install ledger as runtime
500
+ truth.
501
+
502
+ Before handing a legacy Service manifest to another app or deployment
503
+ pipeline, package-check the project and emit a compatibility package:
427
504
 
428
505
  ```sh
429
506
  cd ../services/support-suite-provider
@@ -437,38 +514,37 @@ The package artifact contains the canonical `lenso.service.json`,
437
514
  `modules/<module>/lenso.module-release.json` file for each provided module.
438
515
  The service package records the provider name, version, and provided module
439
516
  names; each module release is the business-module install entrypoint.
440
- Operators can install a provider directly. For a local package artifact, still
441
- pass the runtime service base URL:
517
+ Compatibility packages remain available for older Service discovery consumers:
442
518
 
443
519
  ```sh
444
520
  lenso service install dist/lenso-service/support-suite-provider/lenso.service-package.json \
445
521
  --base-url http://127.0.0.1:4100/lenso/service/v1
446
522
  ```
447
523
 
448
- Install and manage a Module through the stable lifecycle commands:
524
+ Install current Provider Modules from an exact release. The endpoint must end
525
+ in `/lenso/provider/v1`:
449
526
 
450
527
  ```sh
451
- lenso module install dist/lenso-service/support-suite-provider/modules/support-ticket/lenso.module-release.json \
452
- --base-url http://127.0.0.1:4100/lenso/service/v1
453
- lenso module disable support-ticket
454
- lenso module remove support-ticket
455
- lenso module doctor support-ticket
528
+ lenso module install ./lenso.module-release.json \
529
+ --base-url http://127.0.0.1:4100/lenso/provider/v1
456
530
  ```
457
531
 
458
- `lenso.module-release.v1` is the module release channel. It records the module
459
- name, version, capabilities, source, and optional provider pointer. V11 keeps
460
- `lenso module install` as the unified business-capability entrypoint:
532
+ `lenso.module-release.v1` is the current Module release channel. It records a
533
+ fully qualified Module ID, canonical Manifest digest, exact delivery, governing
534
+ contract digests, and optional release-bound `console_ui_esm` artifact.
461
535
 
462
- - `source: service` resolves to a provider service package or service manifest.
463
- - `source: linked` enables linked Rust code in the host.
464
- - `source: bundled` enables a host-bundled module.
536
+ - Service delivery resolves to a locked Provider export and Service Installation.
537
+ - Linked delivery resolves to an immutable crate release and Host binding.
538
+ - A Console Surface exists only when the same exact release carries a
539
+ `console_ui_esm` artifact and Console has reconciled its receipt.
465
540
 
466
541
  `lenso service install` remains the lower-level provider/process command. It
467
542
  connects a service, but it does not mean every module inside that service is
468
543
  the user-facing install target.
469
544
 
470
- The Service scaffold consumes `@lenso/service-kit` from the framework SDK when
471
- used in a sibling checkout. Outside that checkout it uses the published SDK.
545
+ The Service scaffold uses published `@lenso/service-kit` and `lenso-service`
546
+ dependencies by default. Framework contributors can opt into local checkout
547
+ dependencies explicitly with `lenso service create --local-framework-root PATH`.
472
548
 
473
549
  ### Console and Module UI development
474
550
 
@@ -478,6 +554,11 @@ Run the complete local Console Service from its repository:
478
554
  lenso console dev --console-root ../lenso-console
479
555
  ```
480
556
 
557
+ On first run, this command creates `service/.env` with available loopback ports,
558
+ installs missing workspace dependencies, starts an isolated Postgres Compose
559
+ project, applies migrations, and then serves the complete Console. Existing
560
+ `service/.env` files remain authoritative.
561
+
481
562
  Run the Console UI artifact owned by the current Module:
482
563
 
483
564
  ```sh
@@ -490,24 +571,13 @@ longer copies packages into a Console checkout or maintains extension registries
490
571
  ## Install a module
491
572
 
492
573
  ```sh
493
- lenso module install auth
494
- lenso module install auth-password
495
- lenso module install auth-oidc
496
- lenso module install auth-device
574
+ lenso module install ./releases/auth/lenso.module-release.json
575
+ lenso module install ./releases/auth-password/lenso.module-release.json
497
576
  ```
498
577
 
499
- `module install` reads `source` from the module descriptor when one is present.
500
- When the reference is a module name, the CLI resolves it from the official
501
- catalog at `https://catalog.lenso.dev/v1/modules.json` unless `--catalog-url`
502
- points at another registry. If the primary official catalog endpoint is
503
- temporarily blocked by edge security, the CLI falls back to the official
504
- workers.dev mirror at `https://lenso-catalog.lenso.workers.dev/v1/modules.json`.
505
- For V5 service-backed modules, `module install <name>` is the business-capability
506
- entrypoint: the catalog resolves the provider service, installs it when needed,
507
- then enables the requested module.
508
- For module releases, `module install <module-release.json>` resolves the
509
- release by source, then records `moduleRelease` provenance in
510
- `.lenso/module-installs.json` where the source supports a receipt.
578
+ Prefer an exact Module Release reference. Name-based catalog entries are accepted
579
+ only as a compatibility path and may describe a legacy linked install; they do
580
+ not prove that a current Console Surface artifact exists.
511
581
 
512
582
  Install a service directly when you have a workspace service name or manifest
513
583
  reference:
@@ -525,12 +595,11 @@ also infer `--base-url`; package artifacts outside that workspace still need
525
595
  `--base-url` so the host records the runtime service endpoint rather than the
526
596
  file path.
527
597
 
528
- Service installs update `SERVICE_MODULES` and record `.lenso/module-installs.json`
529
- in one step. Console UI artifacts remain immutable members of their Module
530
- Release and are bound only by an applied Console Service Composition. Linked modules update the
531
- host `Cargo.toml`, `src/lib.rs`, `.env` toggle, and the same install receipt
532
- from the descriptor's `linked` section. `module add` remains a compatibility
533
- alias for service installs.
598
+ Exact Provider installs update the App Module lock and local Service
599
+ Installation Set in one step. Console UI artifacts remain immutable members of
600
+ their Module Release and are bound only by an applied Console composition.
601
+ Legacy linked descriptors still update host source and their compatibility
602
+ receipt, but that receipt is not an App Composition or a Surface grant.
534
603
 
535
604
  Legacy `lenso module install <manifest-url>` still works for one compatibility
536
605
  window, but prints a deprecation warning. Use `lenso service install <manifest>`
@@ -631,11 +700,9 @@ lenso service doctor billing --json
631
700
  lenso service check billing --json
632
701
  ```
633
702
 
634
- The doctor reads `SERVICE_MODULES`, `.lenso/module-installs.json`, and
635
- `.lenso/module-services.json`. It reports whether the service is
636
- installed, configured, whether an HTTP manifest is reachable, whether managed
637
- service `readyUrl` endpoints are ready, and which stale `.lock`/`.pid` files
638
- may be blocking a host-started service.
703
+ The legacy doctor still reports compatibility Service discovery state. For a
704
+ current Provider, verify `lenso.modules.lock.json`, the local Service
705
+ Installation Set, and the live `/lenso/provider/v1` descriptor at Host startup.
639
706
 
640
707
  Export declared service processes as a Compose fragment when handing the
641
708
  service to deployment tooling:
package/bin/lenso.js CHANGED
@@ -6,8 +6,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.platformTag = platformTag;
8
8
  exports.binaryPath = binaryPath;
9
+ exports.ensureExecutableBinary = ensureExecutableBinary;
9
10
  exports.forwardTerminationSignals = forwardTerminationSignals;
10
11
  const node_child_process_1 = require("node:child_process");
12
+ const node_fs_1 = require("node:fs");
11
13
  const node_path_1 = __importDefault(require("node:path"));
12
14
  const SUPPORTED_PLATFORMS = new Set(["darwin", "linux", "win32"]);
13
15
  const SUPPORTED_ARCHES = new Set(["arm64", "x64"]);
@@ -25,6 +27,15 @@ function binaryPath(baseDir = node_path_1.default.join(__dirname, ".."), platfor
25
27
  const exe = platform === "win32" ? "lenso.exe" : "lenso";
26
28
  return node_path_1.default.join(baseDir, "vendor", tag, exe);
27
29
  }
30
+ function ensureExecutableBinary(executable, platform = process.platform) {
31
+ if (platform === "win32") {
32
+ return;
33
+ }
34
+ const mode = (0, node_fs_1.statSync)(executable).mode;
35
+ if ((mode & 0o111) === 0) {
36
+ (0, node_fs_1.chmodSync)(executable, mode | 0o111);
37
+ }
38
+ }
28
39
  function forwardTerminationSignals(parent, child, signals = ["SIGINT", "SIGTERM"]) {
29
40
  const handlers = new Map(signals.map((signal) => [
30
41
  signal,
@@ -49,6 +60,14 @@ function run() {
49
60
  console.error(`lenso: unsupported platform ${process.platform}/${process.arch}`);
50
61
  process.exit(1);
51
62
  }
63
+ try {
64
+ ensureExecutableBinary(exe);
65
+ }
66
+ catch (error) {
67
+ const message = error instanceof Error ? error.message : String(error);
68
+ console.error(`lenso: bundled binary is not executable: ${message}`);
69
+ process.exit(1);
70
+ }
52
71
  const child = (0, node_child_process_1.spawn)(exe, process.argv.slice(2), { stdio: "inherit" });
53
72
  const stopForwardingSignals = forwardTerminationSignals(process, child);
54
73
  child.on("error", (error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenso/cli",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Lenso command-line interface for scaffolding and operating Lenso backend projects.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/LioRael/lenso-cli",
Binary file
Binary file
Binary file
Binary file