alasio 4.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.
Files changed (72) hide show
  1. package/dist/cli/src/cluster/docker.js +219 -0
  2. package/dist/cli/src/cluster/docker.js.map +1 -0
  3. package/dist/cli/src/cluster/local.js +392 -0
  4. package/dist/cli/src/cluster/local.js.map +1 -0
  5. package/dist/cli/src/commands/common.js +108 -0
  6. package/dist/cli/src/commands/common.js.map +1 -0
  7. package/dist/cli/src/commands/down.js +26 -0
  8. package/dist/cli/src/commands/down.js.map +1 -0
  9. package/dist/cli/src/commands/init.js +314 -0
  10. package/dist/cli/src/commands/init.js.map +1 -0
  11. package/dist/cli/src/commands/lake.js +33 -0
  12. package/dist/cli/src/commands/lake.js.map +1 -0
  13. package/dist/cli/src/commands/login.js +38 -0
  14. package/dist/cli/src/commands/login.js.map +1 -0
  15. package/dist/cli/src/commands/logs.js +27 -0
  16. package/dist/cli/src/commands/logs.js.map +1 -0
  17. package/dist/cli/src/commands/restart.js +23 -0
  18. package/dist/cli/src/commands/restart.js.map +1 -0
  19. package/dist/cli/src/commands/status.js +58 -0
  20. package/dist/cli/src/commands/status.js.map +1 -0
  21. package/dist/cli/src/commands/uninstall.js +47 -0
  22. package/dist/cli/src/commands/uninstall.js.map +1 -0
  23. package/dist/cli/src/commands/up.js +33 -0
  24. package/dist/cli/src/commands/up.js.map +1 -0
  25. package/dist/cli/src/commands/upgrade.js +50 -0
  26. package/dist/cli/src/commands/upgrade.js.map +1 -0
  27. package/dist/cli/src/commands.js +16 -0
  28. package/dist/cli/src/commands.js.map +1 -0
  29. package/dist/cli/src/config.js +169 -0
  30. package/dist/cli/src/config.js.map +1 -0
  31. package/dist/cli/src/images.js +7 -0
  32. package/dist/cli/src/images.js.map +1 -0
  33. package/dist/cli/src/install.js +39 -0
  34. package/dist/cli/src/install.js.map +1 -0
  35. package/dist/cli/src/kube/api.js +231 -0
  36. package/dist/cli/src/kube/api.js.map +1 -0
  37. package/dist/cli/src/kube/apply.js +98 -0
  38. package/dist/cli/src/kube/apply.js.map +1 -0
  39. package/dist/cli/src/kube/rollout.js +166 -0
  40. package/dist/cli/src/kube/rollout.js.map +1 -0
  41. package/dist/cli/src/main.js +30 -0
  42. package/dist/cli/src/main.js.map +1 -0
  43. package/dist/cli/src/manifests/agent-sandbox.js +89 -0
  44. package/dist/cli/src/manifests/agent-sandbox.js.map +1 -0
  45. package/dist/cli/src/manifests/alasio.js +367 -0
  46. package/dist/cli/src/manifests/alasio.js.map +1 -0
  47. package/dist/cli/src/manifests/common.js +157 -0
  48. package/dist/cli/src/manifests/common.js.map +1 -0
  49. package/dist/cli/src/manifests/config.js +283 -0
  50. package/dist/cli/src/manifests/config.js.map +1 -0
  51. package/dist/cli/src/manifests/index.js +20 -0
  52. package/dist/cli/src/manifests/index.js.map +1 -0
  53. package/dist/cli/src/manifests/lake.js +56 -0
  54. package/dist/cli/src/manifests/lake.js.map +1 -0
  55. package/dist/cli/src/manifests/neon.js +656 -0
  56. package/dist/cli/src/manifests/neon.js.map +1 -0
  57. package/dist/cli/src/manifests/network-policies.js +86 -0
  58. package/dist/cli/src/manifests/network-policies.js.map +1 -0
  59. package/dist/cli/src/manifests/object-store.js +204 -0
  60. package/dist/cli/src/manifests/object-store.js.map +1 -0
  61. package/dist/cli/src/manifests/sandboxes.agents.x-k8s.io.json +6295 -0
  62. package/dist/cli/src/release.js +15 -0
  63. package/dist/cli/src/release.js.map +1 -0
  64. package/dist/cli/src/secrets.js +49 -0
  65. package/dist/cli/src/secrets.js.map +1 -0
  66. package/dist/cli/src/target.js +55 -0
  67. package/dist/cli/src/target.js.map +1 -0
  68. package/dist/cli/src/telegram.js +27 -0
  69. package/dist/cli/src/telegram.js.map +1 -0
  70. package/dist/src/kube/config.js +99 -0
  71. package/dist/src/kube/config.js.map +1 -0
  72. package/package.json +32 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * What this version of the package installs. The release workflow writes the released
3
+ * version and the digests of the images it published here, with tooling/pin-release.ts,
4
+ * before it builds the package; this module holds nothing else.
5
+ */
6
+ export const VERSION = "4.0.0";
7
+ /** alasio's own images, tagged with the version and pinned by digest once released. */
8
+ export const IMAGES = {
9
+ alasio: { repository: "ghcr.io/eaucoin/alasio", tag: VERSION, digest: "sha256:ae9b943a6122d4a2b026be9bf4c04d10b8a6c936152183d0f142e5884bb9220c" },
10
+ agent: { repository: "ghcr.io/eaucoin/alasio-agent", tag: VERSION, digest: "sha256:6fdf6b513385b74f3c40739f11fe3d38e7d62d1cf5ef696656bee0581c53d2f7" },
11
+ lake: { repository: "ghcr.io/eaucoin/alasio-lake", tag: VERSION, digest: "sha256:750ea9cca137c3b08735b6cc29b3fd31735365bd8ae2a5223245adc57c477a50" },
12
+ };
13
+ /** The local cluster's node image: k3s with gVisor (cluster/node), pinned like the others. */
14
+ export const NODE_IMAGE = { repository: "ghcr.io/eaucoin/alasio-node", tag: VERSION, digest: "sha256:3e98ad907f002d42eadc7cb126064e587e1d387f43154658fb34a06f4134d2ee" };
15
+ //# sourceMappingURL=release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.js","sourceRoot":"","sources":["../../../src/release.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,uFAAuF;AACvF,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE,EAAE,UAAU,EAAE,wBAAwB,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,yEAAyE,EAAE;IACjJ,KAAK,EAAE,EAAE,UAAU,EAAE,8BAA8B,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,yEAAyE,EAAE;IACtJ,IAAI,EAAE,EAAE,UAAU,EAAE,6BAA6B,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,yEAAyE,EAAE;CACrJ,CAAC;AAEF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,UAAU,EAAE,6BAA6B,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,yEAAyE,EAAE,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { Effect, Redacted } from "effect";
2
+ import { kind, KubeApi } from "./kube/api.js";
3
+ import { NAMESPACE } from "./manifests/common.js";
4
+ /** The bot's Secret: its token (`token`) and the users allowed to use it (`allowedUserIds`, comma-separated). */
5
+ export const TELEGRAM_SECRET = "alasio-telegram";
6
+ /** Claude Code's Secret: its token (`token`), from `claude setup-token`. */
7
+ export const CLAUDE_SECRET = "alasio-claude";
8
+ /** The annotation of the bot's Secret that names the bot, which is no secret. */
9
+ const BOT_ANNOTATION = "alasio.dev/bot-username";
10
+ const SECRET = kind("Secret");
11
+ /** A Secret of alasio's holding `data`. */
12
+ function secret(name, data, annotations = {}) {
13
+ return {
14
+ apiVersion: "v1",
15
+ kind: "Secret",
16
+ metadata: { name, namespace: NAMESPACE, labels: { "app.kubernetes.io/managed-by": "alasio", "app.kubernetes.io/part-of": "alasio" }, annotations },
17
+ type: "Opaque",
18
+ data: Object.fromEntries(Object.entries(data).map(([key, value]) => [key, Buffer.from(value, "utf8").toString("base64")])),
19
+ };
20
+ }
21
+ /** The value of `key` in `found`'s data, or null when it has none. */
22
+ const valueOf = (found, key) => {
23
+ const encoded = found?.data?.[key];
24
+ return encoded === undefined ? null : Buffer.from(encoded, "base64").toString("utf8");
25
+ };
26
+ /** Writes the bot's Secret. */
27
+ export const writeTelegramBot = (bot) => Effect.flatMap(KubeApi, (kube) => kube.apply(secret(TELEGRAM_SECRET, { token: Redacted.value(bot.token), allowedUserIds: bot.allowedUserIds.join(",") }, { [BOT_ANNOTATION]: bot.username }))).pipe(Effect.asVoid);
28
+ /** Writes Claude Code's Secret. */
29
+ export const writeClaudeToken = (token) => Effect.flatMap(KubeApi, (kube) => kube.apply(secret(CLAUDE_SECRET, { token: Redacted.value(token) }))).pipe(Effect.asVoid);
30
+ /** The bot of the bot's Secret, or null when there is none. */
31
+ export const readTelegramBot = Effect.gen(function* () {
32
+ const kube = yield* KubeApi;
33
+ const found = yield* kube.get({ ...SECRET, namespace: NAMESPACE, name: TELEGRAM_SECRET });
34
+ const token = valueOf(found, "token");
35
+ if (token === null)
36
+ return null;
37
+ return {
38
+ token: Redacted.make(token),
39
+ allowedUserIds: (valueOf(found, "allowedUserIds") ?? "").split(",").filter(Boolean),
40
+ username: found?.metadata?.annotations?.[BOT_ANNOTATION] ?? "",
41
+ };
42
+ });
43
+ /** Claude Code's token, or null when there is none. */
44
+ export const readClaudeToken = Effect.gen(function* () {
45
+ const kube = yield* KubeApi;
46
+ const token = valueOf(yield* kube.get({ ...SECRET, namespace: NAMESPACE, name: CLAUDE_SECRET }), "token");
47
+ return token === null ? null : Redacted.make(token);
48
+ });
49
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../src/secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The cluster the operator's config targets (./config.ts): the one alasio makes on this
3
+ * machine, whose kubeconfig it writes beside the config file, or one a kubeconfig
4
+ * reaches; and the services that reach it.
5
+ *
6
+ * The local cluster's nodes mount the host profile's paths at their own, as folder
7
+ * workspaces mount them from the node, but for those the target's own mounts already
8
+ * put there (as a node path of /host/tmp mounts the machine's /tmp).
9
+ */
10
+ import { Config, Effect, FileSystem, Layer, Option, Result } from "effect";
11
+ import { DockerEngine } from "./cluster/docker.js";
12
+ import { LocalCluster } from "./cluster/local.js";
13
+ import { defaultStoragePath, installConfigOf, localKubeconfigPath, OperatorConfigError } from "./config.js";
14
+ import { KubeApi } from "./kube/api.js";
15
+ /** The cluster `config` targets. */
16
+ export const resolveTarget = Effect.fnUntraced(function* (config) {
17
+ const { target } = config;
18
+ if ("kubeconfig" in target)
19
+ return { _tag: "Kubeconfig", kubeconfig: target.kubeconfig };
20
+ const { local } = target;
21
+ const install = installConfigOf(config.install, { claude: false });
22
+ if (Result.isFailure(install))
23
+ return yield* new OperatorConfigError({ path: config.path, reason: install.failure });
24
+ const { host } = install.success;
25
+ const hostPaths = host.enabled ? host.mounts.map(({ hostPath, readOnly }) => ({ source: hostPath, target: hostPath, readOnly })) : [];
26
+ return {
27
+ _tag: "Local",
28
+ cluster: {
29
+ name: local.name,
30
+ apiPort: local.apiPort,
31
+ storagePath: local.storagePath ?? (yield* defaultStoragePath),
32
+ ...(local.subnet ? { subnet: local.subnet } : {}),
33
+ ...(local.image ? { image: local.image } : {}),
34
+ hostAliases: local.hostAliases,
35
+ mounts: [...local.mounts, ...hostPaths.filter(({ target }) => !local.mounts.some((mount) => mount.target === target))],
36
+ agents: local.agents,
37
+ ...(local.registries ? { registries: local.registries } : {}),
38
+ },
39
+ kubeconfig: { path: localKubeconfigPath(config) },
40
+ };
41
+ });
42
+ /** Docker, as DOCKER_HOST names it. */
43
+ const docker = Layer.unwrap(Effect.map(Config.option(Config.String("DOCKER_HOST")), (host) => DockerEngine.layer(Option.match(host, { onNone: () => ({}), onSome: (DOCKER_HOST) => ({ DOCKER_HOST }) }))));
44
+ /** The local cluster made with `options`. */
45
+ export const localCluster = (options) => LocalCluster.layer(options).pipe(Layer.provide(docker));
46
+ /** The API of the cluster `target` is. */
47
+ export const kubeApi = (target) => KubeApi.layer(target.kubeconfig);
48
+ /** Where the cluster `target` is, as people read it. */
49
+ export function describeTarget(target) {
50
+ if (target._tag === "Local")
51
+ return `the cluster ${target.cluster.name} on this machine`;
52
+ const { path, context } = target.kubeconfig;
53
+ return `the cluster ${context ? `of context ${context}` : "of the current context"} of ${path ?? "the default kubeconfig"}`;
54
+ }
55
+ //# sourceMappingURL=target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target.js","sourceRoot":"","sources":["../../../src/target.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Telegram's Bot API, as far as alasio's command line asks it: which bot a token is
3
+ * (getMe), so a token is checked before it is kept. It only reads; it never sends a
4
+ * message. The API is at TELEGRAM_API_ROOT, as for alasio itself, or Telegram's own.
5
+ */
6
+ import { Config, Context, Effect, Layer, Redacted, Schema } from "effect";
7
+ const GetMeAnswer = Schema.Union([
8
+ Schema.Struct({ ok: Schema.Literal(true), result: Schema.Struct({ username: Schema.String }) }),
9
+ Schema.Struct({ ok: Schema.Literal(false), description: Schema.String }),
10
+ ]);
11
+ /** A bot token could not be checked, or Telegram refused it. */
12
+ export class BotTokenError extends Schema.TaggedError()("BotTokenError", {
13
+ message: Schema.String,
14
+ }) {
15
+ }
16
+ /** Why `cause`, a failed fetch, failed: its own cause's message, as a fetch's says only that it failed. */
17
+ const fetchFailure = (cause) => cause instanceof Error ? (cause.cause instanceof Error ? cause.cause.message : cause.message) : String(cause);
18
+ export class TelegramBotApi extends Context.Service()("alasio/TelegramBotApi") {
19
+ static layer = Layer.effect(TelegramBotApi, Effect.map(Config.String("TELEGRAM_API_ROOT").pipe(Config.withDefault("https://api.telegram.org")), (root) => TelegramBotApi.of({
20
+ getMe: (token) => Effect.tryPromise({
21
+ try: async (signal) => (await fetch(`${root.replace(/\/$/u, "")}/bot${Redacted.value(token)}/getMe`, { signal })).json(),
22
+ // Told by its cause alone, as the URL holds the token.
23
+ catch: (cause) => new BotTokenError({ message: `Telegram could not be asked about the bot token: ${fetchFailure(cause)}` }),
24
+ }).pipe(Effect.flatMap((answer) => Schema.decodeUnknownEffect(GetMeAnswer)(answer).pipe(Effect.mapError(() => new BotTokenError({ message: `${root} answered what Telegram's Bot API does not` })))), Effect.flatMap((answer) => answer.ok ? Effect.succeed(answer.result.username) : Effect.fail(new BotTokenError({ message: `Telegram refused the bot token: ${answer.description}` })))),
25
+ })));
26
+ }
27
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../src/telegram.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1E,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;IAC/B,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IAC/F,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;CACzE,CAAC,CAAC;AAEH,gEAAgE;AAChE,MAAM,OAAO,aAAc,SAAQ,MAAM,CAAC,WAAW,EAAiB,CAAC,eAAe,EAAE;IACtF,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC;CAAG;AAEL,2GAA2G;AAC3G,MAAM,YAAY,GAAG,CAAC,KAAc,EAAU,EAAE,CAC9C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEhH,MAAM,OAAO,cAAe,SAAQ,OAAO,CAAC,OAAO,EAG/C,CAAC,uBAAuB,CAAC;IAC3B,MAAM,CAAU,KAAK,GAAoD,KAAK,CAAC,MAAM,CACnF,cAAc,EACd,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3G,cAAc,CAAC,EAAE,CAAC;QAChB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,MAAM,CAAC,UAAU,CAAC;YAChB,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAsB;YAC5I,uDAAuD;YACvD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,OAAO,EAAE,oDAAoD,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;SAC5H,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACxB,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAClD,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,4CAA4C,EAAE,CAAC,CAAC,CAC3G,CACF,EACD,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACxB,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,EAAE,OAAO,EAAE,mCAAmC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAC1J,CACF;KACJ,CAAC,CAAC,CACN,CAAC;CACH"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * The templates alasio's installation gives it for its workspaces: `ALASIO_KUBE_TEMPLATES`
3
+ * is the path of a JSON file, which its Deployment mounts from a ConfigMap
4
+ * (cli/src/manifests/alasio.ts), of the form
5
+ *
6
+ * {
7
+ * "sessions": { "namespace", "port", "workspaceDir", "egressGate", "fullModeNameservers",
8
+ * "podTemplate", "volumeClaimTemplates" },
9
+ * "host": { "namespace", "port", "stateRoot", "podTemplate" }
10
+ * }
11
+ *
12
+ * either of which may be absent: no `sessions`, no session filesystems; no `host`, no
13
+ * folder workspaces. Each `podTemplate` has a container named `bayma` whose arguments
14
+ * serve MCP over HTTP on `port`; alasio adds the rest per Sandbox (./sandboxes.ts).
15
+ */
16
+ import { readFileSync } from "node:fs";
17
+ import { Config, Effect, Predicate, Result, Schema, SchemaGetter, SchemaIssue } from "effect";
18
+ /** The deployment's templates could not be read, or are not what alasio needs; the message says which. */
19
+ export class KubeTemplatesError extends Schema.TaggedError()("KubeTemplatesError", {
20
+ message: Schema.String,
21
+ }) {
22
+ }
23
+ const NAMESPACE = /^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$/u;
24
+ /**
25
+ * `schema`, whose every failure, a missing key's too, reads as `message`, which the
26
+ * error then says of the key's path.
27
+ */
28
+ const said = (schema, message) => schema.annotate({ message }).annotateKey({ messageMissingKey: message });
29
+ /** A namespace's name; a name YAML reads as a number (`123`) is that name. */
30
+ const Namespace = said(Schema.Union([Schema.String, Schema.Finite.pipe(Schema.decodeTo(Schema.String, { decode: SchemaGetter.String(), encode: SchemaGetter.Number() }))])
31
+ .check(Schema.isPattern(NAMESPACE, { message: "must be a namespace name" })), "must be a namespace name");
32
+ const Port = said(Schema.Number.check(Schema.isInt({ message: "must be a port number" }), Schema.isBetween({ minimum: 1, maximum: 65535 }, { message: "must be a port number" })), "must be a port number");
33
+ const Path = said(Schema.String, "must be a path");
34
+ /**
35
+ * What alasio relies on of a pod template is checked with its profile (a container named
36
+ * `bayma`); the rest of it, and the claim templates, are Kubernetes objects the
37
+ * installation gives, which the API server checks as each Sandbox is made.
38
+ */
39
+ const PodTemplate = said(Schema.declare((value) => Predicate.isObject(value)), "must be an object").pipe(Schema.withDecodingDefaultKey(Effect.succeed({})));
40
+ const VolumeClaimTemplates = said(Schema.Array(Schema.declare((value) => Predicate.isObject(value))), "must be a list of volume claim templates");
41
+ /** Whether `podTemplate`, as the installation gives it, runs a container named `bayma`. */
42
+ function runsBayma(podTemplate) {
43
+ const containers = Predicate.hasProperty(podTemplate, "spec") && Predicate.hasProperty(podTemplate.spec, "containers")
44
+ ? podTemplate.spec.containers
45
+ : undefined;
46
+ return Array.isArray(containers) && containers.some((container) => Predicate.hasProperty(container, "name") && container.name === "bayma");
47
+ }
48
+ /** What both profiles hold: where their Sandboxes are made, and from what. */
49
+ const sandboxProfile = { namespace: Namespace, port: Port, podTemplate: PodTemplate };
50
+ /** The issue of a profile whose pod template runs no bayma. */
51
+ const baymaIssue = { path: ["podTemplate", "spec", "containers"], issue: 'must include one named "bayma"' };
52
+ /** The template of session filesystems' Sandboxes (sessionsProfile in cli/src/manifests/alasio.ts). */
53
+ const SessionsProfile = said(Schema.Struct({
54
+ ...sandboxProfile,
55
+ /** Where the session's workspace is in bayma's container. */
56
+ workspaceDir: Path,
57
+ /** Whether a session waits for its egress to be confined before it starts; only false turns it off. */
58
+ egressGate: Schema.optional(said(Schema.NullOr(Schema.Boolean), "must be true or false")),
59
+ /** The resolvers sessions with internet access use, or none for alasio's defaults. */
60
+ fullModeNameservers: Schema.optional(said(Schema.NullOr(Schema.Array(Schema.String)), "must be a list of addresses")),
61
+ volumeClaimTemplates: Schema.optional(VolumeClaimTemplates),
62
+ }), "must be an object").check(Schema.makeFilter((profile) => (runsBayma(profile.podTemplate) ? undefined : baymaIssue)));
63
+ /** The template of folder workspaces' bayma (hostProfile in cli/src/manifests/alasio.ts). */
64
+ const HostProfile = said(Schema.Struct({
65
+ ...sandboxProfile,
66
+ /** The directory on the host under which each conversation's bayma keeps its state. */
67
+ stateRoot: Path,
68
+ }), "must be an object").check(Schema.makeFilter((profile) => (runsBayma(profile.podTemplate) ? undefined : baymaIssue)));
69
+ /** A profile the deployment may leave out, which is then null. */
70
+ const optionalProfile = (schema) => said(Schema.NullOr(schema), "must be an object").pipe(Schema.withDecodingDefaultKey(Effect.succeed(null)));
71
+ /** ALASIO_KUBE_TEMPLATES, checked: a profile the deployment does not render is null. */
72
+ const KubeTemplates = said(Schema.Struct({ sessions: optionalProfile(SessionsProfile), host: optionalProfile(HostProfile) }), "must be an object");
73
+ const formatIssue = SchemaIssue.makeFormatterStandardSchemaV1();
74
+ /** The first thing wrong with the templates, as alasio says it: the key's path, then what it must be. */
75
+ function describe(issue) {
76
+ const [first] = formatIssue(issue).issues;
77
+ const path = first?.path?.map((segment) => String(Predicate.hasProperty(segment, "key") ? segment.key : segment)).join(".") ?? "";
78
+ return ["ALASIO_KUBE_TEMPLATES", path, first?.message ?? "is not what alasio expects"].filter(Boolean).join(" ");
79
+ }
80
+ /** The templates in `text`, the content of the file at `path`, checked. */
81
+ export const decodeKubeTemplates = (path, text) => Result.try({
82
+ try: () => JSON.parse(text),
83
+ catch: (error) => new KubeTemplatesError({ message: `ALASIO_KUBE_TEMPLATES ${path} is not readable JSON: ${error instanceof Error ? error.message : String(error)}` }),
84
+ }).pipe(Result.flatMap((parsed) => Result.mapError(Schema.decodeUnknownResult(KubeTemplates)(parsed), (error) => new KubeTemplatesError({ message: describe(error.issue) }))));
85
+ /**
86
+ * The templates, read once at startup and checked, so a deployment that renders them
87
+ * wrongly fails as it starts rather than at a workspace's first turn.
88
+ */
89
+ export const loadKubeTemplates = Effect.gen(function* () {
90
+ const path = (yield* Config.String("ALASIO_KUBE_TEMPLATES").pipe(Config.withDefault(""))).trim();
91
+ if (!path)
92
+ return yield* new KubeTemplatesError({ message: "ALASIO_KUBE_TEMPLATES is not set: alasio runs where alasio up installs it" });
93
+ const text = yield* Effect.try({
94
+ try: () => readFileSync(path, "utf8"),
95
+ catch: (error) => new KubeTemplatesError({ message: `ALASIO_KUBE_TEMPLATES ${path} is not readable JSON: ${error instanceof Error ? error.message : String(error)}` }),
96
+ });
97
+ return yield* Effect.fromResult(decodeKubeTemplates(path, text));
98
+ });
99
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/kube/config.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "alasio",
3
+ "version": "4.0.0",
4
+ "description": "alasio: coding agents you talk to from Telegram, installed and run with npx alasio",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "bin": {
8
+ "alasio": "dist/cli/src/main.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "engines": {
14
+ "node": ">=24"
15
+ },
16
+ "scripts": {
17
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
18
+ "start": "node ./src/main.ts"
19
+ },
20
+ "dependencies": {
21
+ "@effect/platform-node": "4.0.0",
22
+ "@effect/platform-node-shared": "4.0.0",
23
+ "@kubernetes/client-node": "2.0.0",
24
+ "effect": "4.0.0"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/eaucoin/alasio.git",
29
+ "directory": "cli"
30
+ },
31
+ "homepage": "https://github.com/eaucoin/alasio"
32
+ }