nylorun 0.4.0-beta → 0.6.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 +39 -0
- package/README.md +207 -105
- package/dist/cli.js +24 -22
- package/dist/doctor.d.ts +10 -8
- package/dist/doctor.js +54 -37
- package/dist/home.d.ts +1 -1
- package/dist/home.js +1 -1
- package/dist/project/derived-key.d.ts +2 -2
- package/dist/project/derived-key.js +2 -2
- package/dist/project/link.d.ts +7 -7
- package/dist/project/link.js +3 -3
- package/dist/stack/commands.d.ts +23 -15
- package/dist/stack/commands.js +332 -214
- package/dist/stack/compose-file.d.ts +11 -8
- package/dist/stack/compose-file.js +54 -21
- package/dist/stack/docker.d.ts +10 -0
- package/dist/stack/docker.js +64 -1
- package/dist/stack/env-file.d.ts +12 -2
- package/dist/stack/env-file.js +13 -3
- package/dist/stack/host-files.d.ts +4 -4
- package/dist/stack/host-files.js +3 -3
- package/dist/stack/images.d.ts +4 -2
- package/dist/stack/images.js +3 -2
- package/dist/stack/index.d.ts +4 -3
- package/dist/stack/index.js +10 -4
- package/dist/stack/paths.d.ts +3 -3
- package/dist/stack/paths.js +1 -1
- package/dist/stack/ports.d.ts +4 -2
- package/dist/stack/ports.js +3 -1
- package/dist/stack/prepare.d.ts +7 -3
- package/dist/stack/prepare.js +5 -3
- package/dist/stack/proxy.d.ts +78 -0
- package/dist/stack/proxy.js +224 -0
- package/dist/stack/stacks.d.ts +37 -34
- package/dist/stack/stacks.js +91 -57
- package/dist/stack/studio-login.d.ts +4 -3
- package/dist/stack/studio-login.js +5 -4
- package/dist/stack/versions.d.ts +1 -1
- package/dist/stack/versions.js +1 -1
- package/dist/telemetry.d.ts +31 -0
- package/dist/telemetry.js +79 -0
- package/package.json +5 -5
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { STACK_CLIENT_HOST } from "./host-files.js";
|
|
2
|
-
/** Studio's origin
|
|
2
|
+
/** Studio's published origin: always `localhost` (the cookie's host). */
|
|
3
3
|
export function studioOrigin(port) {
|
|
4
4
|
return `http://${STACK_CLIENT_HOST}:${port}`;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Ask the Studio container for a single-use login token with the admin key
|
|
8
|
-
* (`POST /_studio/login-tokens`, Studio §6)
|
|
8
|
+
* (`POST /_studio/login-tokens`, Studio §6) on `origin` (its published port, or
|
|
9
|
+
* the proxy's `http://<name>.localhost:<port>`) and return the URL to open there.
|
|
9
10
|
* Accepts `{ loginUrl }`, `{ url }` or `{ token }` in the response.
|
|
10
11
|
*/
|
|
11
12
|
export async function mintStudioLogin(input) {
|
|
12
|
-
const origin =
|
|
13
|
+
const { origin } = input;
|
|
13
14
|
const response = await input.fetch(`${origin}/_studio/login-tokens`, {
|
|
14
15
|
method: "POST",
|
|
15
16
|
headers: {
|
|
@@ -27,7 +28,7 @@ export async function mintStudioLogin(input) {
|
|
|
27
28
|
for (const field of ["loginUrl", "url"]) {
|
|
28
29
|
const value = body[field];
|
|
29
30
|
if (typeof value === "string" && value !== "") {
|
|
30
|
-
// A relative URL is resolved against the
|
|
31
|
+
// A relative URL is resolved against the origin it was minted on.
|
|
31
32
|
return new URL(value, origin).toString();
|
|
32
33
|
}
|
|
33
34
|
}
|
package/dist/stack/versions.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type PinnedImage = "runtime" | "studio";
|
|
|
3
3
|
/**
|
|
4
4
|
* The version this CLI release pins for an image, from `cli/package.json`
|
|
5
5
|
* `nylorun.runtime` or `nylorun.studio`: the tag of `ghcr.io/nylorun/<name>`
|
|
6
|
-
*
|
|
6
|
+
* a local Tenant runs unless `NYLORUN_RUNTIME_IMAGE` / `NYLORUN_STUDIO_IMAGE`
|
|
7
7
|
* overrides it. The release tooling writes both pins.
|
|
8
8
|
*/
|
|
9
9
|
export declare function pinnedVersion(name: PinnedImage): string;
|
package/dist/stack/versions.js
CHANGED
|
@@ -9,7 +9,7 @@ function cliPackageJsonPath() {
|
|
|
9
9
|
/**
|
|
10
10
|
* The version this CLI release pins for an image, from `cli/package.json`
|
|
11
11
|
* `nylorun.runtime` or `nylorun.studio`: the tag of `ghcr.io/nylorun/<name>`
|
|
12
|
-
*
|
|
12
|
+
* a local Tenant runs unless `NYLORUN_RUNTIME_IMAGE` / `NYLORUN_STUDIO_IMAGE`
|
|
13
13
|
* overrides it. The release tooling writes both pins.
|
|
14
14
|
*/
|
|
15
15
|
export function pinnedVersion(name) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studio's anonymous usage analytics. Studio's dashboard reports page views,
|
|
3
|
+
* with every id replaced by `:id`, to this Google Analytics property unless the
|
|
4
|
+
* developer opted out. `nylorun start` decides and passes the id to the
|
|
5
|
+
* Studio container (`NYLORUN_STUDIO_ANALYTICS_ID`); Studio never decides itself.
|
|
6
|
+
*/
|
|
7
|
+
export declare const STUDIO_ANALYTICS_ID = "G-K6RPDFH6Q6";
|
|
8
|
+
/** `~/.nylorun/telemetry.json`: the developer's choice, for every Tenant on the machine. */
|
|
9
|
+
export interface TelemetryFile {
|
|
10
|
+
format: 1;
|
|
11
|
+
/** False after `nylorun telemetry disable`; absent until a choice is made. */
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
/** When `nylorun start` showed the notice (ISO time); it is shown once. */
|
|
14
|
+
noticeShown?: string;
|
|
15
|
+
}
|
|
16
|
+
export type TelemetryDecision = Readonly<{
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
reason: string;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const TELEMETRY_NOTICE: string;
|
|
21
|
+
export declare function telemetryPath(nylorunRoot: string): string;
|
|
22
|
+
export declare function readTelemetry(nylorunRoot: string): Promise<TelemetryFile>;
|
|
23
|
+
export declare function writeTelemetry(nylorunRoot: string, file: TelemetryFile): Promise<void>;
|
|
24
|
+
/** On unless the environment or the developer's choice turns it off. */
|
|
25
|
+
export declare function telemetryDecision(env: Readonly<Record<string, string | undefined>>, file: TelemetryFile): TelemetryDecision;
|
|
26
|
+
/** `nylorun telemetry [status|enable|disable]`. */
|
|
27
|
+
export declare function telemetryCommand(args: readonly string[], context: {
|
|
28
|
+
nylorunRoot: string;
|
|
29
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
30
|
+
out(line: string): void;
|
|
31
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { CliError } from "./errors.js";
|
|
5
|
+
/**
|
|
6
|
+
* Studio's anonymous usage analytics. Studio's dashboard reports page views,
|
|
7
|
+
* with every id replaced by `:id`, to this Google Analytics property unless the
|
|
8
|
+
* developer opted out. `nylorun start` decides and passes the id to the
|
|
9
|
+
* Studio container (`NYLORUN_STUDIO_ANALYTICS_ID`); Studio never decides itself.
|
|
10
|
+
*/
|
|
11
|
+
export const STUDIO_ANALYTICS_ID = "G-K6RPDFH6Q6";
|
|
12
|
+
export const TELEMETRY_NOTICE = [
|
|
13
|
+
"Studio collects anonymous usage data: which pages are opened, with every",
|
|
14
|
+
"Tenant, agent and session id removed. Nothing you send to agents is collected.",
|
|
15
|
+
'Turn it off with "nylorun telemetry disable" or NYLORUN_TELEMETRY_DISABLED=1.',
|
|
16
|
+
"Learn more: https://github.com/nylorun/agents/blob/main/nylorun/README.md#telemetry",
|
|
17
|
+
].join("\n");
|
|
18
|
+
export function telemetryPath(nylorunRoot) {
|
|
19
|
+
return join(nylorunRoot, "telemetry.json");
|
|
20
|
+
}
|
|
21
|
+
export async function readTelemetry(nylorunRoot) {
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(await readFile(telemetryPath(nylorunRoot), "utf8"));
|
|
24
|
+
if (parsed && typeof parsed === "object") {
|
|
25
|
+
const { enabled, noticeShown } = parsed;
|
|
26
|
+
return {
|
|
27
|
+
format: 1,
|
|
28
|
+
...(typeof enabled === "boolean" ? { enabled } : {}),
|
|
29
|
+
...(typeof noticeShown === "string" ? { noticeShown } : {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* missing or unreadable: no choice yet */
|
|
35
|
+
}
|
|
36
|
+
return { format: 1 };
|
|
37
|
+
}
|
|
38
|
+
export async function writeTelemetry(nylorunRoot, file) {
|
|
39
|
+
await mkdir(nylorunRoot, { recursive: true });
|
|
40
|
+
const path = telemetryPath(nylorunRoot);
|
|
41
|
+
const temporary = `${path}.${randomBytes(8).toString("hex")}.tmp`;
|
|
42
|
+
await writeFile(temporary, `${JSON.stringify(file, null, 2)}\n`);
|
|
43
|
+
await rename(temporary, path);
|
|
44
|
+
}
|
|
45
|
+
/** An environment flag is set unless it is empty, `0`, `false` or `no`. */
|
|
46
|
+
function flag(value) {
|
|
47
|
+
const trimmed = value?.trim() ?? "";
|
|
48
|
+
return trimmed !== "" && !/^(0|false|no)$/i.test(trimmed);
|
|
49
|
+
}
|
|
50
|
+
/** On unless the environment or the developer's choice turns it off. */
|
|
51
|
+
export function telemetryDecision(env, file) {
|
|
52
|
+
if (flag(env.NYLORUN_TELEMETRY_DISABLED))
|
|
53
|
+
return { enabled: false, reason: "NYLORUN_TELEMETRY_DISABLED is set" };
|
|
54
|
+
if (flag(env.DO_NOT_TRACK))
|
|
55
|
+
return { enabled: false, reason: "DO_NOT_TRACK is set" };
|
|
56
|
+
if (flag(env.CI))
|
|
57
|
+
return { enabled: false, reason: "CI is set" };
|
|
58
|
+
if (file.enabled === false)
|
|
59
|
+
return { enabled: false, reason: 'turned off with "nylorun telemetry disable"' };
|
|
60
|
+
return { enabled: true, reason: "on by default" };
|
|
61
|
+
}
|
|
62
|
+
const USAGE = "Usage: nylorun telemetry [status|enable|disable]";
|
|
63
|
+
/** `nylorun telemetry [status|enable|disable]`. */
|
|
64
|
+
export async function telemetryCommand(args, context) {
|
|
65
|
+
const [action = "status", ...rest] = args;
|
|
66
|
+
if (rest.length || !["status", "enable", "disable"].includes(action))
|
|
67
|
+
throw new CliError(USAGE, 2);
|
|
68
|
+
const file = await readTelemetry(context.nylorunRoot);
|
|
69
|
+
if (action !== "status") {
|
|
70
|
+
const enabled = action === "enable";
|
|
71
|
+
await writeTelemetry(context.nylorunRoot, { ...file, enabled });
|
|
72
|
+
context.out(`Studio telemetry ${enabled ? "enabled" : "disabled"}. Running Tenants pick this up on the next "nylorun start".`);
|
|
73
|
+
}
|
|
74
|
+
const decision = telemetryDecision(context.env, await readTelemetry(context.nylorunRoot));
|
|
75
|
+
context.out(`Studio telemetry is ${decision.enabled ? "on" : "off"} (${decision.reason}).`);
|
|
76
|
+
if (action === "status")
|
|
77
|
+
context.out(TELEMETRY_NOTICE);
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nylorun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-beta",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
|
-
"description": "Set up and run
|
|
6
|
+
"description": "Set up and run local Nylorun Tenants (Runtime and Studio) with Docker Compose",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/nylorun/agents.git",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"prepack": "npm run build"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@nylorun/core": "0.
|
|
33
|
+
"@nylorun/core": "0.11.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.15.
|
|
45
|
-
"studio": "0.
|
|
44
|
+
"runtime": "0.15.2-beta",
|
|
45
|
+
"studio": "0.17.0-beta"
|
|
46
46
|
}
|
|
47
47
|
}
|