nylorun 0.1.1-beta → 0.2.0-beta

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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # nylorun
2
2
 
3
+ ## 0.2.0-beta
4
+
5
+ ### Minor Changes
6
+
7
+ - c82aa6f: `nylorun up` prints Studio as `http://localhost:<port>`, with no login token in it, and in a terminal opens Studio in the browser already signed in (`--no-open` keeps the browser closed). The Studio sign-in lasts 30 days and survives Studio restarts: the session cookie is signed with a key derived from the admin key instead of being held in memory. `nylorun studio` prints the plain URL when it opens the browser; `nylorun studio --no-open` still prints the single-use login URL.
8
+
9
+ ### Patch Changes
10
+
11
+ - 5e4947a: `nylorun up` no longer says a Tenant can be created in Studio, which has no way to create one. While the Host has no Tenant, it names `npx @nylorun/cli tenant create` alone.
12
+ - Pin studio to the tested release.
13
+
14
+ ## 0.1.2-beta
15
+
16
+ ### Patch Changes
17
+
18
+ - Pin core to the tested release.
19
+ - Pin runtime to the tested release.
20
+ - Pin studio to the tested release.
21
+ - Updated dependencies [e537a82]
22
+ - Updated dependencies [5278b4e]
23
+ - Updated dependencies [426fd27]
24
+ - Updated dependencies [8cda500]
25
+ - @nylorun/core@0.8.0-beta
26
+
3
27
  ## 0.1.1-beta
4
28
 
5
29
  ### Patch Changes
package/README.md CHANGED
@@ -29,11 +29,11 @@ npx nylorun doctor # Node 24+, Docker, Compose v2, and the stack
29
29
  ## Commands
30
30
 
31
31
  ```sh
32
- nylorun up|start [--no-studio] # set up (first run) and start the stack; print the Runtime URL and a Studio login URL
32
+ nylorun up|start [--no-studio] [--no-open] # set up (first run) and start the stack; print the Runtime and Studio URLs; open Studio signed in
33
33
  nylorun down|stop # stop the containers; keep volumes
34
34
  nylorun status [--json] # services, endpoints, Runtime health
35
35
  nylorun logs [service] [-f] [--tail <n>] # postgres, restate, s2, runtime, studio
36
- nylorun studio [--no-open] # fresh Studio login (on the linked Project's Tenant); starts the stack if needed
36
+ nylorun studio [--no-open] # sign a browser in to Studio (on the linked Project's Tenant); starts the stack if needed
37
37
  nylorun reset [--yes] # delete the stack's volumes and every Tenant
38
38
  nylorun doctor [--json] # prerequisites and stack health
39
39
  ```
@@ -57,12 +57,16 @@ CI). Ports publish on loopback only: the Runtime on `8787`, Studio on `4161`
57
57
  and the Restate UI on `9070`, or free ports chosen on the first start and kept
58
58
  in `.env`. While the Host has no Tenant, `up` says how to create one.
59
59
 
60
- Studio has no password: nylorun asks the Studio container for a single-use
61
- login token with the admin key (`POST /_studio/login-tokens`) and opens
62
- `http://localhost:<port>/login?token=…`, which sets a session cookie. The
63
- token expires after two minutes; `nylorun studio` mints a fresh one. Inside a
64
- linked project, `nylorun studio` reads `.nylorun/link.json` (never writes it)
65
- and lands on that project's Tenant.
60
+ `up` prints Studio as `http://localhost:<port>`. Studio has no password: in a
61
+ terminal (not in CI, and not with `--no-open`), `up` asks the Studio container
62
+ for a single-use login token with the admin key (`POST /_studio/login-tokens`)
63
+ and opens `http://localhost:<port>/login?token=…` in the browser. That sets a
64
+ session cookie for 30 days, which survives Studio restarts, so the printed URL
65
+ keeps working in that browser. The token itself is never printed unless no
66
+ browser starts. Otherwise `up` says to run `nylorun studio`, which signs a
67
+ browser in the same way; `nylorun studio --no-open` prints the login URL (it
68
+ works once, for two minutes) instead. Inside a linked project, `nylorun studio`
69
+ reads `.nylorun/link.json` (never writes it) and lands on that project's Tenant.
66
70
 
67
71
  ## Host root
68
72
 
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ const usage = `nylorun <up|down|start|stop|status|logs|studio|reset|doctor>
8
8
 
9
9
  Local stack (Docker Compose):
10
10
  ${stackUsage}
11
- doctor [--json] check Node, Docker and Compose v2, and the stack's health
11
+ doctor [--json] check Node, Docker and Compose v2, and the stack's health
12
12
 
13
13
  nylorun sets up and runs the local stack. Tenants, Project links and model
14
14
  providers belong to the Runtime client: npx @nylorun/cli --help`;
@@ -17,7 +17,10 @@ export interface StackDeps {
17
17
  err(line: string): void;
18
18
  /** Ask a yes/no question on the terminal; undefined when not interactive. */
19
19
  confirm?(question: string): Promise<boolean>;
20
- openBrowser(url: string): Promise<void>;
20
+ /** A developer is at a terminal: `start` may open a browser. */
21
+ interactive?: boolean;
22
+ /** Open `url` in a browser; false when no browser could be started. */
23
+ openBrowser(url: string): Promise<boolean>;
21
24
  /** Is this process id alive? (launcher-managed Runtime detection) */
22
25
  pidAlive(pid: number): boolean;
23
26
  /** Delay between health polls; tests shorten it. */
@@ -38,8 +41,10 @@ export declare function parseStackFlags(args: readonly string[], allowed: {
38
41
  values?: readonly string[];
39
42
  aliases?: Record<string, string>;
40
43
  }, usage: string): Flags;
44
+ /** Printed by `start` when it does not open Studio itself. */
45
+ export declare const STUDIO_SIGN_IN_HINT = "To sign a browser in to Studio, run \"npx nylorun studio\".";
41
46
  /** Printed by `start` while the Host has no Tenant: nylorun never creates one. */
42
- export declare const TENANT_HINT = "No Tenant yet. Create one in Studio, or run `npx @nylorun/cli tenant create` in your project.";
47
+ export declare const TENANT_HINT = "No Tenant yet. In your project, run `npx @nylorun/cli tenant create`.";
43
48
  export interface StackStatus {
44
49
  project: string;
45
50
  home: string;
@@ -12,12 +12,12 @@ import { mintStudioLogin, studioOrigin } from "./studio-login.js";
12
12
  export const STACK_SERVICES = ["postgres", "restate", "s2", "runtime", "studio"];
13
13
  const CORE_SERVICES = ["postgres", "restate", "s2", "runtime"];
14
14
  const DEFAULT_PROJECT = "nylorun";
15
- export const stackUsage = ` up|start [--no-studio] set up the stack on first run, then start it; print the Runtime URL and a Studio login URL
16
- down|stop stop the stack's containers; keep volumes
17
- status [--json] [--env] services, endpoints and Runtime health (--env: the linked Project's variables)
18
- logs [service] [-f] [--tail <n>] stack logs (${STACK_SERVICES.join(", ")})
19
- studio [--no-open] open a fresh Studio login (on the linked Project's Tenant); start the stack if it is stopped
20
- reset [--yes] delete the stack's volumes and Tenant directories`;
15
+ export const stackUsage = ` up|start [--no-studio] [--no-open] set up the stack on first run, then start it; print the Runtime and Studio URLs and open Studio signed in (in a terminal)
16
+ down|stop stop the stack's containers; keep volumes
17
+ status [--json] [--env] services, endpoints and Runtime health (--env: the linked Project's variables)
18
+ logs [service] [-f] [--tail <n>] stack logs (${STACK_SERVICES.join(", ")})
19
+ studio [--no-open] sign a browser in to Studio (on the linked Project's Tenant); --no-open prints the login URL; start the stack if it is stopped
20
+ reset [--yes] delete the stack's volumes and Tenant directories`;
21
21
  const usageError = (message) => new CliError(message, 2);
22
22
  export function stackProject(env) {
23
23
  const project = env.NYLORUN_STACK_PROJECT?.trim() || DEFAULT_PROJECT;
@@ -188,19 +188,39 @@ async function tryStudioLogin(ctx, studioPort, adminKey) {
188
188
  ctx.deps.err(`Warning: Studio at ${studioOrigin(studioPort)} is not reachable for a login (${lastError}).`);
189
189
  return undefined;
190
190
  }
191
+ /** Printed by `start` when it does not open Studio itself. */
192
+ export const STUDIO_SIGN_IN_HINT = 'To sign a browser in to Studio, run "npx nylorun studio".';
193
+ /** `start` opens Studio only for a developer at a terminal, outside CI. */
194
+ function opensBrowser(deps, flags) {
195
+ return Boolean(deps.interactive) && !deps.env.CI && !flags.booleans.has("--no-open");
196
+ }
197
+ /**
198
+ * Open a Studio login in the browser, or print it when no browser starts.
199
+ * The login URL carries a single-use token, so it is printed only as a fallback.
200
+ */
201
+ async function openLogin(ctx, login) {
202
+ if (!(await ctx.deps.openBrowser(login)))
203
+ ctx.deps.out(`Sign in ${login}`);
204
+ }
191
205
  /** Printed by `start` while the Host has no Tenant: nylorun never creates one. */
192
- export const TENANT_HINT = "No Tenant yet. Create one in Studio, or run `npx @nylorun/cli tenant create` in your project.";
206
+ export const TENANT_HINT = "No Tenant yet. In your project, run `npx @nylorun/cli tenant create`.";
193
207
  async function start(ctx, args) {
194
- const flags = parseStackFlags(args, { booleans: ["--no-studio"] }, "nylorun start [--no-studio]");
208
+ const usage = "nylorun start [--no-studio] [--no-open]";
209
+ const flags = parseStackFlags(args, { booleans: ["--no-studio", "--no-open"] }, usage);
195
210
  if (flags.rest.length)
196
- throw usageError("Usage: nylorun start [--no-studio]");
211
+ throw usageError(`Usage: ${usage}`);
197
212
  await dockerPreflight(ctx.deps.docker);
198
213
  const started = await bringUp(ctx, { studio: !flags.booleans.has("--no-studio") });
199
214
  ctx.deps.out(`Runtime ${started.runtimeUrl}`);
200
215
  if (started.studioStarted) {
201
- const login = await tryStudioLogin(ctx, started.studioPort, started.adminKey);
202
- if (login)
203
- ctx.deps.out(`Studio ${login}`);
216
+ ctx.deps.out(`Studio ${studioOrigin(started.studioPort)}`);
217
+ if (opensBrowser(ctx.deps, flags)) {
218
+ const login = await tryStudioLogin(ctx, started.studioPort, started.adminKey);
219
+ if (login)
220
+ await openLogin(ctx, login);
221
+ }
222
+ else
223
+ ctx.deps.err(STUDIO_SIGN_IN_HINT);
204
224
  }
205
225
  if ((await adminTenantCount(ctx.deps, started.runtimeUrl, started.adminKey)) === 0)
206
226
  ctx.deps.err(TENANT_HINT);
@@ -446,9 +466,13 @@ async function studio(ctx, args, options = {}) {
446
466
  const login = await studioLoginUrl(ctx.deps, stack, options.next);
447
467
  if (!login)
448
468
  return 1;
449
- ctx.deps.out(`Studio ${login}`);
450
- if (!flags.booleans.has("--no-open"))
451
- await ctx.deps.openBrowser(login);
469
+ if (flags.booleans.has("--no-open")) {
470
+ ctx.deps.out(`Studio ${login}`);
471
+ return 0;
472
+ }
473
+ const origin = studioOrigin(stack.studioPort);
474
+ ctx.deps.out(`Studio ${options.next ? new URL(options.next, origin).toString() : origin}`);
475
+ await openLogin(ctx, login);
452
476
  return 0;
453
477
  }
454
478
  /** `nylorun studio`, landing on `next` (the linked Project's Tenant) when given. */
@@ -40,17 +40,18 @@ export function defaultStackDeps(env) {
40
40
  },
41
41
  }
42
42
  : {}),
43
+ interactive,
43
44
  openBrowser: async (url) => {
44
45
  const command = browserCommand(env);
45
- await new Promise((resolve) => {
46
+ return await new Promise((resolve) => {
46
47
  const child = spawn(command, [url], { detached: true, stdio: "ignore" });
47
48
  child.once("error", () => {
48
- console.error(`Could not start ${command} to open a browser; open the Studio URL above.`);
49
- resolve();
49
+ console.error(`Could not start ${command} to open a browser.`);
50
+ resolve(false);
50
51
  });
51
52
  child.once("spawn", () => {
52
53
  child.unref();
53
- resolve();
54
+ resolve(true);
54
55
  });
55
56
  });
56
57
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nylorun",
3
- "version": "0.1.1-beta",
3
+ "version": "0.2.0-beta",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "description": "Set up and run the local Nylorun stack (Runtime and Studio) with Docker Compose",
@@ -30,7 +30,7 @@
30
30
  "prepack": "npm run build"
31
31
  },
32
32
  "dependencies": {
33
- "@nylorun/core": "0.7.0-beta"
33
+ "@nylorun/core": "0.8.0-beta"
34
34
  },
35
35
  "devDependencies": {
36
36
  "typescript": "npm:@typescript/typescript6@^6.0.2",
@@ -41,7 +41,7 @@
41
41
  "nylorun": "dist/cli.js"
42
42
  },
43
43
  "nylorun": {
44
- "runtime": "0.12.0-beta",
45
- "studio": "0.10.1-beta"
44
+ "runtime": "0.13.0-beta",
45
+ "studio": "0.12.0-beta"
46
46
  }
47
47
  }