@getmonoceros/workbench 1.17.1 → 1.19.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/dist/bin.js +587 -178
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1903,6 +1903,41 @@ function curatedServiceEnvDefaults(name) {
|
|
|
1903
1903
|
const def = SERVICE_CATALOG[name];
|
|
1904
1904
|
return def?.env ? { ...def.env } : {};
|
|
1905
1905
|
}
|
|
1906
|
+
function serviceConnectionEnv(services) {
|
|
1907
|
+
const env = {};
|
|
1908
|
+
for (const svc of services) {
|
|
1909
|
+
if (!isCuratedService(svc.name)) continue;
|
|
1910
|
+
const host = svc.name;
|
|
1911
|
+
if (svc.name === "postgres") {
|
|
1912
|
+
const user = svc.env.POSTGRES_USER ?? "postgres";
|
|
1913
|
+
const pass = svc.env.POSTGRES_PASSWORD ?? "";
|
|
1914
|
+
const db = svc.env.POSTGRES_DB ?? user;
|
|
1915
|
+
const port = svc.port ?? 5432;
|
|
1916
|
+
env.PGHOST = host;
|
|
1917
|
+
env.PGPORT = String(port);
|
|
1918
|
+
env.PGUSER = user;
|
|
1919
|
+
env.PGPASSWORD = pass;
|
|
1920
|
+
env.PGDATABASE = db;
|
|
1921
|
+
env.DATABASE_URL = `postgresql://${user}:${pass}@${host}:${port}/${db}`;
|
|
1922
|
+
} else if (svc.name === "mysql") {
|
|
1923
|
+
const pass = svc.env.MYSQL_ROOT_PASSWORD ?? "";
|
|
1924
|
+
const db = svc.env.MYSQL_DATABASE ?? "";
|
|
1925
|
+
const port = svc.port ?? 3306;
|
|
1926
|
+
env.MYSQL_HOST = host;
|
|
1927
|
+
env.MYSQL_PORT = String(port);
|
|
1928
|
+
env.MYSQL_USER = "root";
|
|
1929
|
+
env.MYSQL_PASSWORD = pass;
|
|
1930
|
+
env.MYSQL_DATABASE = db;
|
|
1931
|
+
if (env.DATABASE_URL === void 0) {
|
|
1932
|
+
env.DATABASE_URL = `mysql://root:${pass}@${host}:${port}/${db}`;
|
|
1933
|
+
}
|
|
1934
|
+
} else if (svc.name === "redis") {
|
|
1935
|
+
const port = svc.port ?? 6379;
|
|
1936
|
+
env.REDIS_URL = `redis://${host}:${port}`;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
return env;
|
|
1940
|
+
}
|
|
1906
1941
|
function deriveServiceName(image) {
|
|
1907
1942
|
const lastSegment = image.split("/").pop() ?? image;
|
|
1908
1943
|
const noTag = lastSegment.split("@")[0].split(":")[0];
|
|
@@ -2438,6 +2473,14 @@ function buildComposeYaml(opts, dockerMode = "rootful") {
|
|
|
2438
2473
|
for (const v of ideVolumes) {
|
|
2439
2474
|
lines.push(` - ${v.volume}:${v.target}`);
|
|
2440
2475
|
}
|
|
2476
|
+
const wsEnv = serviceConnectionEnv(opts.services);
|
|
2477
|
+
const wsEnvKeys = Object.keys(wsEnv);
|
|
2478
|
+
if (wsEnvKeys.length > 0) {
|
|
2479
|
+
lines.push(" environment:");
|
|
2480
|
+
for (const k of wsEnvKeys) {
|
|
2481
|
+
lines.push(` ${k}: ${composeScalar(wsEnv[k])}`);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2441
2484
|
for (const svc of opts.services) {
|
|
2442
2485
|
lines.push(` ${svc.name}:`);
|
|
2443
2486
|
lines.push(` image: ${svc.image}`);
|
|
@@ -3216,8 +3259,8 @@ function removeRepoFromDoc(doc, urlOrPath) {
|
|
|
3216
3259
|
if (!isMap2(item)) return false;
|
|
3217
3260
|
const url = item.get("url");
|
|
3218
3261
|
if (url === urlOrPath) return true;
|
|
3219
|
-
const
|
|
3220
|
-
const effectivePath = typeof
|
|
3262
|
+
const path24 = item.get("path");
|
|
3263
|
+
const effectivePath = typeof path24 === "string" ? path24 : typeof url === "string" ? deriveRepoName(url) : void 0;
|
|
3221
3264
|
return effectivePath === urlOrPath;
|
|
3222
3265
|
});
|
|
3223
3266
|
if (idx < 0) return false;
|
|
@@ -3329,7 +3372,7 @@ async function runAddRepo(input) {
|
|
|
3329
3372
|
"Missing repo URL. Usage: monoceros add-repo <containername> <url>."
|
|
3330
3373
|
);
|
|
3331
3374
|
}
|
|
3332
|
-
const
|
|
3375
|
+
const path24 = (input.path ?? deriveRepoName(url)).trim();
|
|
3333
3376
|
const hasName = typeof input.gitName === "string" && input.gitName.trim().length > 0;
|
|
3334
3377
|
const hasEmail = typeof input.gitEmail === "string" && input.gitEmail.trim().length > 0;
|
|
3335
3378
|
if (hasName !== hasEmail) {
|
|
@@ -3366,7 +3409,7 @@ async function runAddRepo(input) {
|
|
|
3366
3409
|
const providerToWrite = !canonical && explicitProvider ? explicitProvider : void 0;
|
|
3367
3410
|
const entry2 = {
|
|
3368
3411
|
url,
|
|
3369
|
-
path:
|
|
3412
|
+
path: path24,
|
|
3370
3413
|
...hasName && hasEmail ? {
|
|
3371
3414
|
gitUser: {
|
|
3372
3415
|
name: input.gitName.trim(),
|
|
@@ -4767,22 +4810,42 @@ function generateAgentsMd(input) {
|
|
|
4767
4810
|
lines.push(formatServiceLine(svc));
|
|
4768
4811
|
}
|
|
4769
4812
|
lines.push("");
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4813
|
+
const connEnv = serviceConnectionEnv(input.services);
|
|
4814
|
+
if (Object.keys(connEnv).length > 0) {
|
|
4815
|
+
lines.push(
|
|
4816
|
+
"Connection details for the curated services above are already set as",
|
|
4817
|
+
"environment variables in this container. Read them from the",
|
|
4818
|
+
"environment \u2014 do not ask the user for credentials, and do not",
|
|
4819
|
+
"hardcode them:"
|
|
4820
|
+
);
|
|
4821
|
+
lines.push("");
|
|
4822
|
+
if (connEnv.DATABASE_URL !== void 0) {
|
|
4823
|
+
lines.push(
|
|
4824
|
+
"- `DATABASE_URL` \u2014 the SQL database. Engine-specific variables are",
|
|
4825
|
+
" set too (`PGHOST`/`PGPORT`/`PGUSER`/`PGPASSWORD`/`PGDATABASE` for",
|
|
4826
|
+
" Postgres, `MYSQL_*` for MySQL)."
|
|
4827
|
+
);
|
|
4828
|
+
}
|
|
4829
|
+
if (connEnv.REDIS_URL !== void 0) {
|
|
4830
|
+
lines.push("- `REDIS_URL` \u2014 Redis.");
|
|
4831
|
+
}
|
|
4832
|
+
lines.push("");
|
|
4833
|
+
lines.push(
|
|
4834
|
+
"These are dev-only defaults for the local container, fine to use",
|
|
4835
|
+
"directly. Prefer reading the variable (e.g. `process.env.DATABASE_URL`)",
|
|
4836
|
+
"over copying its value into code."
|
|
4837
|
+
);
|
|
4838
|
+
}
|
|
4778
4839
|
const hasCustom = input.services.some((s) => !isCuratedService(s.name));
|
|
4779
4840
|
if (hasCustom) {
|
|
4780
4841
|
lines.push("");
|
|
4781
4842
|
lines.push(
|
|
4782
4843
|
"For custom-image services, Monoceros does not know the service's",
|
|
4783
|
-
"configuration (env vars, ports beyond the primary one,
|
|
4784
|
-
"volumes). Treat such a service as a black box reachable at
|
|
4785
|
-
"listed address; if you need
|
|
4844
|
+
"configuration or credentials (env vars, ports beyond the primary one,",
|
|
4845
|
+
"required volumes). Treat such a service as a black box reachable at",
|
|
4846
|
+
"the listed address; if you need to connect, ask the user in the",
|
|
4847
|
+
"current chat. Do not commit credentials into the repo \u2014 they belong",
|
|
4848
|
+
"in the user's `.env` on the host."
|
|
4786
4849
|
);
|
|
4787
4850
|
}
|
|
4788
4851
|
lines.push("");
|
|
@@ -4866,6 +4929,54 @@ function generateAgentsMd(input) {
|
|
|
4866
4929
|
" DataGrip) to one of the services."
|
|
4867
4930
|
);
|
|
4868
4931
|
lines.push("");
|
|
4932
|
+
if (input.ports.length > 0) {
|
|
4933
|
+
lines.push("## Running a long-running server");
|
|
4934
|
+
lines.push("");
|
|
4935
|
+
lines.push(
|
|
4936
|
+
"When you build something that serves on a port (a web app, an API),",
|
|
4937
|
+
"start it as a **detached** background process so it keeps running after",
|
|
4938
|
+
"this session ends. A plain `npm start` (or any foreground start) dies",
|
|
4939
|
+
"the moment the user exits you or closes the terminal \u2014 and then",
|
|
4940
|
+
`\`${input.containerName}.localhost\` returns 502 Bad Gateway.`
|
|
4941
|
+
);
|
|
4942
|
+
lines.push("");
|
|
4943
|
+
lines.push(
|
|
4944
|
+
"Launch it in a new session with `setsid`, using the project's own",
|
|
4945
|
+
"start command, and record the process-group PID + log under the",
|
|
4946
|
+
"container's logs directory:"
|
|
4947
|
+
);
|
|
4948
|
+
lines.push("");
|
|
4949
|
+
lines.push("```");
|
|
4950
|
+
lines.push(
|
|
4951
|
+
`setsid sh -c 'echo $$ >/workspaces/${input.containerName}/logs/<app>.pid; \\`
|
|
4952
|
+
);
|
|
4953
|
+
lines.push(
|
|
4954
|
+
` exec <the project's start command> >/workspaces/${input.containerName}/logs/<app>.log 2>&1' </dev/null &`
|
|
4955
|
+
);
|
|
4956
|
+
lines.push("```");
|
|
4957
|
+
lines.push("");
|
|
4958
|
+
lines.push(
|
|
4959
|
+
"Use whatever start command the project actually uses (`npm start`,",
|
|
4960
|
+
"`./mvnw spring-boot:run`, `python app.py`, `go run .`, \u2026) \u2014 do not force",
|
|
4961
|
+
"a language-specific one. `<app>` is a short name you choose."
|
|
4962
|
+
);
|
|
4963
|
+
lines.push("");
|
|
4964
|
+
lines.push("To stop it, kill the whole process group (also stops children");
|
|
4965
|
+
lines.push("like node under npm or java under maven):");
|
|
4966
|
+
lines.push("");
|
|
4967
|
+
lines.push("```");
|
|
4968
|
+
lines.push(
|
|
4969
|
+
`kill -TERM -$(cat /workspaces/${input.containerName}/logs/<app>.pid)`
|
|
4970
|
+
);
|
|
4971
|
+
lines.push("```");
|
|
4972
|
+
lines.push("");
|
|
4973
|
+
lines.push(
|
|
4974
|
+
`The user can follow the output with \`monoceros logs ${input.containerName} <app>\``,
|
|
4975
|
+
"on the host. The server must listen on `0.0.0.0` (not `127.0.0.1`) on",
|
|
4976
|
+
"the exposed port, or Traefik cannot reach it."
|
|
4977
|
+
);
|
|
4978
|
+
lines.push("");
|
|
4979
|
+
}
|
|
4869
4980
|
lines.push("## Command reference");
|
|
4870
4981
|
lines.push("");
|
|
4871
4982
|
lines.push(
|
|
@@ -5373,10 +5484,12 @@ var init_cli = __esm({
|
|
|
5373
5484
|
cachedBinaryPath = null;
|
|
5374
5485
|
spawnDevcontainer = (args, cwd, options = {}) => {
|
|
5375
5486
|
const binPath = devcontainerCliPath();
|
|
5487
|
+
const env = { ...process.env, DOCKER_CLI_HINTS: "false" };
|
|
5376
5488
|
return new Promise((resolve, reject) => {
|
|
5377
5489
|
if (options.interactive) {
|
|
5378
5490
|
const child2 = spawn4(process.execPath, [binPath, ...args], {
|
|
5379
5491
|
cwd,
|
|
5492
|
+
env,
|
|
5380
5493
|
stdio: "inherit"
|
|
5381
5494
|
});
|
|
5382
5495
|
child2.on("error", reject);
|
|
@@ -5385,6 +5498,7 @@ var init_cli = __esm({
|
|
|
5385
5498
|
}
|
|
5386
5499
|
const child = spawn4(process.execPath, [binPath, ...args], {
|
|
5387
5500
|
cwd,
|
|
5501
|
+
env,
|
|
5388
5502
|
stdio: ["ignore", "pipe", "pipe"]
|
|
5389
5503
|
});
|
|
5390
5504
|
if (options.quiet) {
|
|
@@ -6293,7 +6407,7 @@ var CLI_VERSION;
|
|
|
6293
6407
|
var init_version = __esm({
|
|
6294
6408
|
"src/version.ts"() {
|
|
6295
6409
|
"use strict";
|
|
6296
|
-
CLI_VERSION = true ? "1.
|
|
6410
|
+
CLI_VERSION = true ? "1.19.0" : "dev";
|
|
6297
6411
|
}
|
|
6298
6412
|
});
|
|
6299
6413
|
|
|
@@ -6482,6 +6596,43 @@ var init_completion = __esm({
|
|
|
6482
6596
|
}
|
|
6483
6597
|
});
|
|
6484
6598
|
|
|
6599
|
+
// src/login/services.ts
|
|
6600
|
+
function featureLeaf(ref) {
|
|
6601
|
+
const noTag = ref.replace(/:[^/:]*$/, "");
|
|
6602
|
+
return noTag.slice(noTag.lastIndexOf("/") + 1);
|
|
6603
|
+
}
|
|
6604
|
+
function loginCapableServices(refs) {
|
|
6605
|
+
const out = [];
|
|
6606
|
+
for (const ref of refs) {
|
|
6607
|
+
const service = LOGIN_SERVICE_BY_LEAF[featureLeaf(ref)];
|
|
6608
|
+
if (service && !out.includes(service)) out.push(service);
|
|
6609
|
+
}
|
|
6610
|
+
return out;
|
|
6611
|
+
}
|
|
6612
|
+
function parseCallbackTarget(authUrl) {
|
|
6613
|
+
try {
|
|
6614
|
+
const u = new URL(authUrl);
|
|
6615
|
+
const redirect = u.searchParams.get("redirect_uri");
|
|
6616
|
+
if (!redirect) return null;
|
|
6617
|
+
const r = new URL(redirect);
|
|
6618
|
+
if (r.hostname !== "localhost" && r.hostname !== "127.0.0.1") return null;
|
|
6619
|
+
const port = Number(r.port);
|
|
6620
|
+
if (!Number.isInteger(port) || port <= 0) return null;
|
|
6621
|
+
return { port, pathname: r.pathname };
|
|
6622
|
+
} catch {
|
|
6623
|
+
return null;
|
|
6624
|
+
}
|
|
6625
|
+
}
|
|
6626
|
+
var LOGIN_SERVICE_BY_LEAF;
|
|
6627
|
+
var init_services = __esm({
|
|
6628
|
+
"src/login/services.ts"() {
|
|
6629
|
+
"use strict";
|
|
6630
|
+
LOGIN_SERVICE_BY_LEAF = {
|
|
6631
|
+
"claude-code": "claude"
|
|
6632
|
+
};
|
|
6633
|
+
}
|
|
6634
|
+
});
|
|
6635
|
+
|
|
6485
6636
|
// src/completion/resolve.ts
|
|
6486
6637
|
import { existsSync as existsSync8, promises as fs13 } from "fs";
|
|
6487
6638
|
import path16 from "path";
|
|
@@ -6638,6 +6789,20 @@ async function listContainerNames(ctx) {
|
|
|
6638
6789
|
const entries = await fs13.readdir(dir);
|
|
6639
6790
|
return entries.filter((e) => e.endsWith(".yml")).map((e) => e.slice(0, -".yml".length)).sort();
|
|
6640
6791
|
}
|
|
6792
|
+
async function listLoginServices(ctx) {
|
|
6793
|
+
const after = ctx.prev.slice(2);
|
|
6794
|
+
const name = after.find((t) => !t.startsWith("-"));
|
|
6795
|
+
if (!name) return [];
|
|
6796
|
+
const home = ctx.opts.monocerosHome ?? monocerosHome();
|
|
6797
|
+
const cfgPath = path16.join(home, "container-configs", `${name}.yml`);
|
|
6798
|
+
if (!existsSync8(cfgPath)) return [];
|
|
6799
|
+
try {
|
|
6800
|
+
const { config } = await readConfig(cfgPath);
|
|
6801
|
+
return loginCapableServices(config.features.map((f) => f.ref));
|
|
6802
|
+
} catch {
|
|
6803
|
+
return [];
|
|
6804
|
+
}
|
|
6805
|
+
}
|
|
6641
6806
|
async function listFeatureComponents() {
|
|
6642
6807
|
const catalog = await loadComponentCatalog();
|
|
6643
6808
|
return [...catalog.values()].filter((c) => c.file.category === "feature").map((c) => c.name).sort();
|
|
@@ -6705,15 +6870,18 @@ var init_resolve = __esm({
|
|
|
6705
6870
|
"src/completion/resolve.ts"() {
|
|
6706
6871
|
"use strict";
|
|
6707
6872
|
init_paths();
|
|
6873
|
+
init_io();
|
|
6708
6874
|
init_components();
|
|
6709
6875
|
init_manifest();
|
|
6710
6876
|
init_catalog();
|
|
6877
|
+
init_services();
|
|
6711
6878
|
init_schema();
|
|
6712
6879
|
ALL_COMMANDS = [
|
|
6713
6880
|
"init",
|
|
6714
6881
|
"list-components",
|
|
6715
6882
|
"shell",
|
|
6716
6883
|
"run",
|
|
6884
|
+
"login",
|
|
6717
6885
|
"logs",
|
|
6718
6886
|
"start",
|
|
6719
6887
|
"stop",
|
|
@@ -6782,6 +6950,7 @@ var init_resolve = __esm({
|
|
|
6782
6950
|
positionals: [containerName],
|
|
6783
6951
|
flags: { "--in": { type: "value" } }
|
|
6784
6952
|
},
|
|
6953
|
+
login: { positionals: [containerName, (ctx) => listLoginServices(ctx)] },
|
|
6785
6954
|
logs: { positionals: [containerName] },
|
|
6786
6955
|
start: { positionals: [containerName] },
|
|
6787
6956
|
stop: { positionals: [containerName] },
|
|
@@ -7754,8 +7923,277 @@ var init_list_components = __esm({
|
|
|
7754
7923
|
}
|
|
7755
7924
|
});
|
|
7756
7925
|
|
|
7757
|
-
// src/
|
|
7926
|
+
// src/devcontainer/shell.ts
|
|
7927
|
+
import { existsSync as existsSync10 } from "fs";
|
|
7928
|
+
import path18 from "path";
|
|
7929
|
+
async function runShell(opts) {
|
|
7930
|
+
assertContainerExists(opts.root);
|
|
7931
|
+
const spawnFn = opts.spawn ?? spawnDevcontainer;
|
|
7932
|
+
const upCode = await spawnFn(
|
|
7933
|
+
["up", "--workspace-folder", opts.root, "--mount-workspace-git-root=false"],
|
|
7934
|
+
opts.root,
|
|
7935
|
+
{ quiet: true }
|
|
7936
|
+
);
|
|
7937
|
+
if (upCode !== 0) return upCode;
|
|
7938
|
+
return spawnFn(
|
|
7939
|
+
[
|
|
7940
|
+
"exec",
|
|
7941
|
+
"--workspace-folder",
|
|
7942
|
+
opts.root,
|
|
7943
|
+
"--mount-workspace-git-root=false",
|
|
7944
|
+
"bash"
|
|
7945
|
+
],
|
|
7946
|
+
opts.root,
|
|
7947
|
+
{ interactive: true }
|
|
7948
|
+
);
|
|
7949
|
+
}
|
|
7950
|
+
function assertContainerExists(root) {
|
|
7951
|
+
if (!existsSync10(path18.join(root, ".devcontainer"))) {
|
|
7952
|
+
throw new Error(
|
|
7953
|
+
`No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
|
|
7954
|
+
);
|
|
7955
|
+
}
|
|
7956
|
+
}
|
|
7957
|
+
var init_shell = __esm({
|
|
7958
|
+
"src/devcontainer/shell.ts"() {
|
|
7959
|
+
"use strict";
|
|
7960
|
+
init_cli();
|
|
7961
|
+
}
|
|
7962
|
+
});
|
|
7963
|
+
|
|
7964
|
+
// src/login/index.ts
|
|
7965
|
+
import { spawn as spawn8 } from "child_process";
|
|
7966
|
+
import { existsSync as existsSync11, promises as fsp2, readFileSync as readFileSync6 } from "fs";
|
|
7967
|
+
import http from "http";
|
|
7968
|
+
import path19 from "path";
|
|
7969
|
+
import { consola as consola16 } from "consola";
|
|
7970
|
+
function openInBrowser(url) {
|
|
7971
|
+
const platform = process.platform;
|
|
7972
|
+
const [cmd, args] = platform === "darwin" ? ["open", [url]] : platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
|
|
7973
|
+
try {
|
|
7974
|
+
const child = spawn8(cmd, args, {
|
|
7975
|
+
stdio: "ignore",
|
|
7976
|
+
detached: true
|
|
7977
|
+
});
|
|
7978
|
+
child.on("error", () => {
|
|
7979
|
+
});
|
|
7980
|
+
child.unref();
|
|
7981
|
+
} catch {
|
|
7982
|
+
}
|
|
7983
|
+
}
|
|
7984
|
+
async function runLogin(opts) {
|
|
7985
|
+
const root = containerDir(opts.name);
|
|
7986
|
+
assertContainerExists(root);
|
|
7987
|
+
const { config } = await readConfig(containerConfigPath(opts.name));
|
|
7988
|
+
const capable = loginCapableServices(config.features.map((f) => f.ref));
|
|
7989
|
+
if (capable.length === 0) {
|
|
7990
|
+
consola16.error(
|
|
7991
|
+
`Container "${opts.name}" has no tool with a Monoceros login. (Supported today: claude.)`
|
|
7992
|
+
);
|
|
7993
|
+
return 1;
|
|
7994
|
+
}
|
|
7995
|
+
if (!opts.feature) {
|
|
7996
|
+
consola16.info(
|
|
7997
|
+
`Login-capable tools in "${opts.name}": ${capable.join(", ")}.`
|
|
7998
|
+
);
|
|
7999
|
+
consola16.info(`Log one in with: monoceros login ${opts.name} <tool>`);
|
|
8000
|
+
return 0;
|
|
8001
|
+
}
|
|
8002
|
+
const service = opts.feature;
|
|
8003
|
+
if (!capable.includes(service)) {
|
|
8004
|
+
consola16.error(
|
|
8005
|
+
`"${service}" is not a login-capable tool in "${opts.name}". Available: ${capable.join(", ")}.`
|
|
8006
|
+
);
|
|
8007
|
+
return 1;
|
|
8008
|
+
}
|
|
8009
|
+
if (service !== "claude") {
|
|
8010
|
+
consola16.error(
|
|
8011
|
+
`Login for "${service}" is not implemented yet (only claude).`
|
|
8012
|
+
);
|
|
8013
|
+
return 1;
|
|
8014
|
+
}
|
|
8015
|
+
return runClaudeLogin(opts.name, root, opts.spawn ?? spawnDevcontainer);
|
|
8016
|
+
}
|
|
8017
|
+
async function runClaudeLogin(name, root, spawnFn) {
|
|
8018
|
+
const credFile = path19.join(root, "home", ".claude", ".credentials.json");
|
|
8019
|
+
if (existsSync11(credFile)) {
|
|
8020
|
+
consola16.success(
|
|
8021
|
+
`Claude is already logged in for "${name}". Re-apply or remove the credential to log in again.`
|
|
8022
|
+
);
|
|
8023
|
+
return 0;
|
|
8024
|
+
}
|
|
8025
|
+
const upCode = await spawnFn(
|
|
8026
|
+
["up", "--workspace-folder", root, "--mount-workspace-git-root=false"],
|
|
8027
|
+
root,
|
|
8028
|
+
{ quiet: true }
|
|
8029
|
+
);
|
|
8030
|
+
if (upCode !== 0) return upCode;
|
|
8031
|
+
const relayDir = path19.join(root, RELAY_DIRNAME);
|
|
8032
|
+
const relayScript = path19.join(relayDir, "xdg-open");
|
|
8033
|
+
const urlFile = path19.join(relayDir, "url");
|
|
8034
|
+
await fsp2.mkdir(relayDir, { recursive: true });
|
|
8035
|
+
await fsp2.rm(urlFile, { force: true });
|
|
8036
|
+
await fsp2.writeFile(
|
|
8037
|
+
relayScript,
|
|
8038
|
+
`#!/bin/sh
|
|
8039
|
+
printf '%s\\n' "$1" > "$(dirname "$0")/url"
|
|
8040
|
+
exit 0
|
|
8041
|
+
`,
|
|
8042
|
+
{ mode: 493 }
|
|
8043
|
+
);
|
|
8044
|
+
await fsp2.chmod(relayScript, 493);
|
|
8045
|
+
const servers = [];
|
|
8046
|
+
let handledUrl = false;
|
|
8047
|
+
const onAuthUrl = (authUrl) => {
|
|
8048
|
+
consola16.info("Opening the Claude sign-in page in your browser\u2026");
|
|
8049
|
+
openInBrowser(authUrl);
|
|
8050
|
+
const target = parseCallbackTarget(authUrl);
|
|
8051
|
+
if (!target) {
|
|
8052
|
+
return;
|
|
8053
|
+
}
|
|
8054
|
+
const server = http.createServer((req, res) => {
|
|
8055
|
+
const reqUrl = req.url ?? target.pathname;
|
|
8056
|
+
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
8057
|
+
res.end(
|
|
8058
|
+
'<html><body style="font-family:sans-serif;padding:3rem">You are signed in. You can close this tab and return to the terminal.</body></html>'
|
|
8059
|
+
);
|
|
8060
|
+
void spawnFn(
|
|
8061
|
+
[
|
|
8062
|
+
"exec",
|
|
8063
|
+
"--workspace-folder",
|
|
8064
|
+
root,
|
|
8065
|
+
"--mount-workspace-git-root=false",
|
|
8066
|
+
"curl",
|
|
8067
|
+
"-fsS",
|
|
8068
|
+
`http://localhost:${target.port}${reqUrl}`
|
|
8069
|
+
],
|
|
8070
|
+
root,
|
|
8071
|
+
{ quiet: true }
|
|
8072
|
+
);
|
|
8073
|
+
});
|
|
8074
|
+
server.on("error", (err) => {
|
|
8075
|
+
consola16.warn(
|
|
8076
|
+
`Could not start the local callback helper on port ${target.port} (${err.message}). If the browser shows a code, paste it into the terminal instead.`
|
|
8077
|
+
);
|
|
8078
|
+
});
|
|
8079
|
+
server.listen(target.port, "127.0.0.1");
|
|
8080
|
+
servers.push(server);
|
|
8081
|
+
};
|
|
8082
|
+
const poll = setInterval(() => {
|
|
8083
|
+
if (handledUrl || !existsSync11(urlFile)) return;
|
|
8084
|
+
let content = "";
|
|
8085
|
+
try {
|
|
8086
|
+
content = readFileSync6(urlFile, "utf8");
|
|
8087
|
+
} catch {
|
|
8088
|
+
return;
|
|
8089
|
+
}
|
|
8090
|
+
if (!content.trim()) return;
|
|
8091
|
+
handledUrl = true;
|
|
8092
|
+
onAuthUrl(content.trim());
|
|
8093
|
+
}, 250);
|
|
8094
|
+
consola16.info(
|
|
8095
|
+
"Starting Claude login. Pick your account in Claude's menu \u2014 the browser opens for you, no copying."
|
|
8096
|
+
);
|
|
8097
|
+
const child = spawn8(
|
|
8098
|
+
process.execPath,
|
|
8099
|
+
[
|
|
8100
|
+
devcontainerCliPath(),
|
|
8101
|
+
"exec",
|
|
8102
|
+
"--workspace-folder",
|
|
8103
|
+
root,
|
|
8104
|
+
"--mount-workspace-git-root=false",
|
|
8105
|
+
"bash",
|
|
8106
|
+
"-lc",
|
|
8107
|
+
`export PATH="/workspaces/${name}/${RELAY_DIRNAME}:$PATH"; exec claude`
|
|
8108
|
+
],
|
|
8109
|
+
{
|
|
8110
|
+
cwd: root,
|
|
8111
|
+
env: { ...process.env, DOCKER_CLI_HINTS: "false" },
|
|
8112
|
+
stdio: "inherit"
|
|
8113
|
+
}
|
|
8114
|
+
);
|
|
8115
|
+
const code = await new Promise((resolve) => {
|
|
8116
|
+
child.on("error", () => resolve(1));
|
|
8117
|
+
child.on("exit", (c) => resolve(c ?? 0));
|
|
8118
|
+
});
|
|
8119
|
+
clearInterval(poll);
|
|
8120
|
+
for (const s of servers) s.close();
|
|
8121
|
+
await fsp2.rm(relayDir, { recursive: true, force: true });
|
|
8122
|
+
if (existsSync11(credFile)) {
|
|
8123
|
+
consola16.success(
|
|
8124
|
+
`Claude is logged in for "${name}". The credential persists across rebuilds.`
|
|
8125
|
+
);
|
|
8126
|
+
}
|
|
8127
|
+
return code;
|
|
8128
|
+
}
|
|
8129
|
+
var RELAY_DIRNAME;
|
|
8130
|
+
var init_login = __esm({
|
|
8131
|
+
"src/login/index.ts"() {
|
|
8132
|
+
"use strict";
|
|
8133
|
+
init_io();
|
|
8134
|
+
init_paths();
|
|
8135
|
+
init_cli();
|
|
8136
|
+
init_shell();
|
|
8137
|
+
init_services();
|
|
8138
|
+
RELAY_DIRNAME = ".monoceros-login";
|
|
8139
|
+
}
|
|
8140
|
+
});
|
|
8141
|
+
|
|
8142
|
+
// src/commands/login.ts
|
|
7758
8143
|
import { defineCommand as defineCommand13 } from "citty";
|
|
8144
|
+
import { consola as consola17 } from "consola";
|
|
8145
|
+
var loginCommand;
|
|
8146
|
+
var init_login2 = __esm({
|
|
8147
|
+
"src/commands/login.ts"() {
|
|
8148
|
+
"use strict";
|
|
8149
|
+
init_login();
|
|
8150
|
+
loginCommand = defineCommand13({
|
|
8151
|
+
meta: {
|
|
8152
|
+
name: "login",
|
|
8153
|
+
group: "lifecycle",
|
|
8154
|
+
description: "Log a curated tool in inside the container. Opens the sign-in page in your browser for you \u2014 no copying URLs. Today: Claude."
|
|
8155
|
+
},
|
|
8156
|
+
args: {
|
|
8157
|
+
name: {
|
|
8158
|
+
type: "positional",
|
|
8159
|
+
description: "Container name.",
|
|
8160
|
+
required: true
|
|
8161
|
+
},
|
|
8162
|
+
feature: {
|
|
8163
|
+
type: "positional",
|
|
8164
|
+
description: "Which tool to log in (e.g. `claude`). Optional when the container has only one login-capable tool.",
|
|
8165
|
+
required: false
|
|
8166
|
+
}
|
|
8167
|
+
},
|
|
8168
|
+
async run({ args }) {
|
|
8169
|
+
try {
|
|
8170
|
+
const code = await runLogin({
|
|
8171
|
+
name: args.name,
|
|
8172
|
+
...args.feature ? { feature: args.feature } : {}
|
|
8173
|
+
});
|
|
8174
|
+
process.exit(code);
|
|
8175
|
+
} catch (err) {
|
|
8176
|
+
consola17.error(err instanceof Error ? err.message : String(err));
|
|
8177
|
+
process.exit(1);
|
|
8178
|
+
}
|
|
8179
|
+
}
|
|
8180
|
+
});
|
|
8181
|
+
}
|
|
8182
|
+
});
|
|
8183
|
+
|
|
8184
|
+
// src/commands/logs.ts
|
|
8185
|
+
import { spawn as spawn9 } from "child_process";
|
|
8186
|
+
import { existsSync as existsSync12 } from "fs";
|
|
8187
|
+
import path20 from "path";
|
|
8188
|
+
import { defineCommand as defineCommand14 } from "citty";
|
|
8189
|
+
function tailLogFile(file, follow) {
|
|
8190
|
+
const [cmd, args] = follow ? ["tail", ["-F", file]] : ["cat", [file]];
|
|
8191
|
+
return new Promise((resolve, reject) => {
|
|
8192
|
+
const child = spawn9(cmd, args, { stdio: "inherit" });
|
|
8193
|
+
child.on("error", reject);
|
|
8194
|
+
child.on("exit", (code) => resolve(code ?? 0));
|
|
8195
|
+
});
|
|
8196
|
+
}
|
|
7759
8197
|
var logsCommand;
|
|
7760
8198
|
var init_logs = __esm({
|
|
7761
8199
|
"src/commands/logs.ts"() {
|
|
@@ -7763,11 +8201,11 @@ var init_logs = __esm({
|
|
|
7763
8201
|
init_paths();
|
|
7764
8202
|
init_compose();
|
|
7765
8203
|
init_dispatch();
|
|
7766
|
-
logsCommand =
|
|
8204
|
+
logsCommand = defineCommand14({
|
|
7767
8205
|
meta: {
|
|
7768
8206
|
name: "logs",
|
|
7769
8207
|
group: "run",
|
|
7770
|
-
description: "Tail logs from
|
|
8208
|
+
description: "Tail logs from a compose service of the named dev-container, or from a long-running app started inside it (logs/<app>.log). Pass --no-follow for a one-shot dump."
|
|
7771
8209
|
},
|
|
7772
8210
|
args: {
|
|
7773
8211
|
name: {
|
|
@@ -7777,7 +8215,7 @@ var init_logs = __esm({
|
|
|
7777
8215
|
},
|
|
7778
8216
|
service: {
|
|
7779
8217
|
type: "string",
|
|
7780
|
-
description: "
|
|
8218
|
+
description: "A compose service (e.g. postgres) or an app whose log is at logs/<service>.log. Defaults to all compose services."
|
|
7781
8219
|
},
|
|
7782
8220
|
follow: {
|
|
7783
8221
|
type: "boolean",
|
|
@@ -7787,10 +8225,17 @@ var init_logs = __esm({
|
|
|
7787
8225
|
}
|
|
7788
8226
|
},
|
|
7789
8227
|
run({ args }) {
|
|
8228
|
+
const service = typeof args.service === "string" ? args.service : void 0;
|
|
8229
|
+
if (service) {
|
|
8230
|
+
const logFile = path20.join(containerLogsDir(args.name), `${service}.log`);
|
|
8231
|
+
if (existsSync12(logFile)) {
|
|
8232
|
+
return dispatch(() => tailLogFile(logFile, args.follow));
|
|
8233
|
+
}
|
|
8234
|
+
}
|
|
7790
8235
|
return dispatch(
|
|
7791
8236
|
() => runLogs({
|
|
7792
8237
|
root: containerDir(args.name),
|
|
7793
|
-
...
|
|
8238
|
+
...service ? { service } : {},
|
|
7794
8239
|
follow: args.follow
|
|
7795
8240
|
})
|
|
7796
8241
|
);
|
|
@@ -7800,11 +8245,11 @@ var init_logs = __esm({
|
|
|
7800
8245
|
});
|
|
7801
8246
|
|
|
7802
8247
|
// src/commands/port.ts
|
|
7803
|
-
import { defineCommand as
|
|
7804
|
-
import { consola as
|
|
8248
|
+
import { defineCommand as defineCommand15 } from "citty";
|
|
8249
|
+
import { consola as consola18 } from "consola";
|
|
7805
8250
|
async function runPortListing(opts) {
|
|
7806
8251
|
const out = opts.out ?? process.stdout;
|
|
7807
|
-
const info = opts.info ?? ((m) =>
|
|
8252
|
+
const info = opts.info ?? ((m) => consola18.info(m));
|
|
7808
8253
|
const parsed = await readConfig(
|
|
7809
8254
|
containerConfigPath(opts.name, opts.monocerosHome)
|
|
7810
8255
|
);
|
|
@@ -7862,7 +8307,7 @@ var init_port = __esm({
|
|
|
7862
8307
|
init_schema();
|
|
7863
8308
|
init_dynamic();
|
|
7864
8309
|
init_format();
|
|
7865
|
-
portCommand =
|
|
8310
|
+
portCommand = defineCommand15({
|
|
7866
8311
|
meta: {
|
|
7867
8312
|
name: "port",
|
|
7868
8313
|
group: "discovery",
|
|
@@ -7880,7 +8325,7 @@ var init_port = __esm({
|
|
|
7880
8325
|
const code = await runPortListing({ name: args.name });
|
|
7881
8326
|
process.exit(code);
|
|
7882
8327
|
} catch (err) {
|
|
7883
|
-
|
|
8328
|
+
consola18.error(err instanceof Error ? err.message : String(err));
|
|
7884
8329
|
process.exit(1);
|
|
7885
8330
|
}
|
|
7886
8331
|
}
|
|
@@ -7889,15 +8334,15 @@ var init_port = __esm({
|
|
|
7889
8334
|
});
|
|
7890
8335
|
|
|
7891
8336
|
// src/commands/remove-apt-packages.ts
|
|
7892
|
-
import { defineCommand as
|
|
7893
|
-
import { consola as
|
|
8337
|
+
import { defineCommand as defineCommand16 } from "citty";
|
|
8338
|
+
import { consola as consola19 } from "consola";
|
|
7894
8339
|
var removeAptPackagesCommand;
|
|
7895
8340
|
var init_remove_apt_packages = __esm({
|
|
7896
8341
|
"src/commands/remove-apt-packages.ts"() {
|
|
7897
8342
|
"use strict";
|
|
7898
8343
|
init_inner_args();
|
|
7899
8344
|
init_modify();
|
|
7900
|
-
removeAptPackagesCommand =
|
|
8345
|
+
removeAptPackagesCommand = defineCommand16({
|
|
7901
8346
|
meta: {
|
|
7902
8347
|
name: "remove-apt-packages",
|
|
7903
8348
|
group: "edit",
|
|
@@ -7919,7 +8364,7 @@ var init_remove_apt_packages = __esm({
|
|
|
7919
8364
|
async run({ args }) {
|
|
7920
8365
|
const packages = [...getInnerArgs()];
|
|
7921
8366
|
if (packages.length === 0) {
|
|
7922
|
-
|
|
8367
|
+
consola19.error(
|
|
7923
8368
|
"No package names given. Usage: `monoceros remove-apt-packages <containername> [--yes] -- <pkg> [<pkg> \u2026]`."
|
|
7924
8369
|
);
|
|
7925
8370
|
process.exit(1);
|
|
@@ -7932,7 +8377,7 @@ var init_remove_apt_packages = __esm({
|
|
|
7932
8377
|
});
|
|
7933
8378
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
7934
8379
|
} catch (err) {
|
|
7935
|
-
|
|
8380
|
+
consola19.error(err instanceof Error ? err.message : String(err));
|
|
7936
8381
|
process.exit(1);
|
|
7937
8382
|
}
|
|
7938
8383
|
}
|
|
@@ -7941,14 +8386,14 @@ var init_remove_apt_packages = __esm({
|
|
|
7941
8386
|
});
|
|
7942
8387
|
|
|
7943
8388
|
// src/commands/remove-feature.ts
|
|
7944
|
-
import { defineCommand as
|
|
7945
|
-
import { consola as
|
|
8389
|
+
import { defineCommand as defineCommand17 } from "citty";
|
|
8390
|
+
import { consola as consola20 } from "consola";
|
|
7946
8391
|
var removeFeatureCommand;
|
|
7947
8392
|
var init_remove_feature = __esm({
|
|
7948
8393
|
"src/commands/remove-feature.ts"() {
|
|
7949
8394
|
"use strict";
|
|
7950
8395
|
init_modify();
|
|
7951
|
-
removeFeatureCommand =
|
|
8396
|
+
removeFeatureCommand = defineCommand17({
|
|
7952
8397
|
meta: {
|
|
7953
8398
|
name: "remove-feature",
|
|
7954
8399
|
group: "edit",
|
|
@@ -7981,7 +8426,7 @@ var init_remove_feature = __esm({
|
|
|
7981
8426
|
});
|
|
7982
8427
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
7983
8428
|
} catch (err) {
|
|
7984
|
-
|
|
8429
|
+
consola20.error(err instanceof Error ? err.message : String(err));
|
|
7985
8430
|
process.exit(1);
|
|
7986
8431
|
}
|
|
7987
8432
|
}
|
|
@@ -7990,15 +8435,15 @@ var init_remove_feature = __esm({
|
|
|
7990
8435
|
});
|
|
7991
8436
|
|
|
7992
8437
|
// src/remove/index.ts
|
|
7993
|
-
import { existsSync as
|
|
7994
|
-
import
|
|
7995
|
-
import { consola as
|
|
8438
|
+
import { existsSync as existsSync13, promises as fs15 } from "fs";
|
|
8439
|
+
import path21 from "path";
|
|
8440
|
+
import { consola as consola21 } from "consola";
|
|
7996
8441
|
async function runRemove(opts) {
|
|
7997
8442
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
7998
8443
|
const logger = opts.logger ?? {
|
|
7999
|
-
info: (msg) =>
|
|
8000
|
-
success: (msg) =>
|
|
8001
|
-
warn: (msg) =>
|
|
8444
|
+
info: (msg) => consola21.info(msg),
|
|
8445
|
+
success: (msg) => consola21.success(msg),
|
|
8446
|
+
warn: (msg) => consola21.warn(msg)
|
|
8002
8447
|
};
|
|
8003
8448
|
if (!REGEX.solutionName.test(opts.name)) {
|
|
8004
8449
|
throw new Error(
|
|
@@ -8008,9 +8453,9 @@ async function runRemove(opts) {
|
|
|
8008
8453
|
const ymlPath = containerConfigPath(opts.name, home);
|
|
8009
8454
|
const envPath = containerEnvPath(opts.name, home);
|
|
8010
8455
|
const containerPath = containerDir(opts.name, home);
|
|
8011
|
-
const hasYml =
|
|
8012
|
-
const hasEnv =
|
|
8013
|
-
const hasContainer =
|
|
8456
|
+
const hasYml = existsSync13(ymlPath);
|
|
8457
|
+
const hasEnv = existsSync13(envPath);
|
|
8458
|
+
const hasContainer = existsSync13(containerPath);
|
|
8014
8459
|
if (!hasYml && !hasContainer) {
|
|
8015
8460
|
throw new Error(
|
|
8016
8461
|
`Nothing to remove for '${opts.name}': neither ${ymlPath} nor ${containerPath} exists.`
|
|
@@ -8036,16 +8481,16 @@ async function runRemove(opts) {
|
|
|
8036
8481
|
let backupPath = null;
|
|
8037
8482
|
if (!opts.noBackup && (hasYml || hasContainer)) {
|
|
8038
8483
|
const ts = (opts.now ?? /* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8039
|
-
backupPath =
|
|
8484
|
+
backupPath = path21.join(home, "container-backups", `${opts.name}-${ts}`);
|
|
8040
8485
|
await fs15.mkdir(backupPath, { recursive: true });
|
|
8041
8486
|
if (hasYml) {
|
|
8042
|
-
await fs15.copyFile(ymlPath,
|
|
8487
|
+
await fs15.copyFile(ymlPath, path21.join(backupPath, `${opts.name}.yml`));
|
|
8043
8488
|
}
|
|
8044
8489
|
if (hasEnv) {
|
|
8045
|
-
await fs15.copyFile(envPath,
|
|
8490
|
+
await fs15.copyFile(envPath, path21.join(backupPath, `${opts.name}.env`));
|
|
8046
8491
|
}
|
|
8047
8492
|
if (hasContainer) {
|
|
8048
|
-
await fs15.cp(containerPath,
|
|
8493
|
+
await fs15.cp(containerPath, path21.join(backupPath, "container"), {
|
|
8049
8494
|
recursive: true
|
|
8050
8495
|
});
|
|
8051
8496
|
}
|
|
@@ -8134,15 +8579,15 @@ var init_remove = __esm({
|
|
|
8134
8579
|
});
|
|
8135
8580
|
|
|
8136
8581
|
// src/commands/remove.ts
|
|
8137
|
-
import { defineCommand as
|
|
8138
|
-
import { consola as
|
|
8582
|
+
import { defineCommand as defineCommand18 } from "citty";
|
|
8583
|
+
import { consola as consola22 } from "consola";
|
|
8139
8584
|
import { createInterface } from "readline/promises";
|
|
8140
8585
|
var removeCommand;
|
|
8141
8586
|
var init_remove2 = __esm({
|
|
8142
8587
|
"src/commands/remove.ts"() {
|
|
8143
8588
|
"use strict";
|
|
8144
8589
|
init_remove();
|
|
8145
|
-
removeCommand =
|
|
8590
|
+
removeCommand = defineCommand18({
|
|
8146
8591
|
meta: {
|
|
8147
8592
|
name: "remove",
|
|
8148
8593
|
group: "lifecycle",
|
|
@@ -8179,7 +8624,7 @@ var init_remove2 = __esm({
|
|
|
8179
8624
|
const skipPrompt = args.yes === true;
|
|
8180
8625
|
if (!skipPrompt) {
|
|
8181
8626
|
const warning = noBackup ? `About to remove '${args.name}' WITHOUT a backup. Docker objects, container-configs entry, and container directory will all be deleted.` : `About to remove '${args.name}'. A backup will be written to container-backups/ first, then docker objects, container-configs entry, and container directory will all be deleted.`;
|
|
8182
|
-
|
|
8627
|
+
consola22.warn(warning);
|
|
8183
8628
|
const rl = createInterface({
|
|
8184
8629
|
input: process.stdin,
|
|
8185
8630
|
output: process.stdout
|
|
@@ -8187,7 +8632,7 @@ var init_remove2 = __esm({
|
|
|
8187
8632
|
const answer = await rl.question("Continue? [y/N] ");
|
|
8188
8633
|
rl.close();
|
|
8189
8634
|
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
8190
|
-
|
|
8635
|
+
consola22.info("Aborted. Nothing changed.");
|
|
8191
8636
|
process.exit(0);
|
|
8192
8637
|
}
|
|
8193
8638
|
}
|
|
@@ -8196,7 +8641,7 @@ var init_remove2 = __esm({
|
|
|
8196
8641
|
...noBackup ? { noBackup: true } : {}
|
|
8197
8642
|
});
|
|
8198
8643
|
} catch (err) {
|
|
8199
|
-
|
|
8644
|
+
consola22.error(err instanceof Error ? err.message : String(err));
|
|
8200
8645
|
process.exit(1);
|
|
8201
8646
|
}
|
|
8202
8647
|
}
|
|
@@ -8205,17 +8650,17 @@ var init_remove2 = __esm({
|
|
|
8205
8650
|
});
|
|
8206
8651
|
|
|
8207
8652
|
// src/restore/index.ts
|
|
8208
|
-
import { existsSync as
|
|
8209
|
-
import
|
|
8210
|
-
import { consola as
|
|
8653
|
+
import { existsSync as existsSync14, promises as fs16 } from "fs";
|
|
8654
|
+
import path22 from "path";
|
|
8655
|
+
import { consola as consola23 } from "consola";
|
|
8211
8656
|
async function runRestore(opts) {
|
|
8212
8657
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
8213
8658
|
const logger = opts.logger ?? {
|
|
8214
|
-
info: (msg) =>
|
|
8215
|
-
success: (msg) =>
|
|
8659
|
+
info: (msg) => consola23.info(msg),
|
|
8660
|
+
success: (msg) => consola23.success(msg)
|
|
8216
8661
|
};
|
|
8217
|
-
const backup =
|
|
8218
|
-
if (!
|
|
8662
|
+
const backup = path22.resolve(opts.backupPath);
|
|
8663
|
+
if (!existsSync14(backup)) {
|
|
8219
8664
|
throw new Error(`Backup not found: ${backup}.`);
|
|
8220
8665
|
}
|
|
8221
8666
|
const stat = await fs16.stat(backup);
|
|
@@ -8236,24 +8681,24 @@ async function runRestore(opts) {
|
|
|
8236
8681
|
}
|
|
8237
8682
|
const ymlFile = ymlFiles[0];
|
|
8238
8683
|
const name = ymlFile.replace(/\.yml$/, "");
|
|
8239
|
-
const containerInBackup =
|
|
8240
|
-
const hasContainer =
|
|
8241
|
-
const envInBackup =
|
|
8242
|
-
const hasEnv =
|
|
8684
|
+
const containerInBackup = path22.join(backup, "container");
|
|
8685
|
+
const hasContainer = existsSync14(containerInBackup);
|
|
8686
|
+
const envInBackup = path22.join(backup, `${name}.env`);
|
|
8687
|
+
const hasEnv = existsSync14(envInBackup);
|
|
8243
8688
|
const destYml = containerConfigPath(name, home);
|
|
8244
8689
|
const destContainer = containerDir(name, home);
|
|
8245
|
-
if (
|
|
8690
|
+
if (existsSync14(destYml)) {
|
|
8246
8691
|
throw new Error(
|
|
8247
8692
|
`Refusing to restore: ${destYml} already exists. Remove the current container first (\`monoceros remove ${name}\`) or rename the existing config.`
|
|
8248
8693
|
);
|
|
8249
8694
|
}
|
|
8250
|
-
if (hasContainer &&
|
|
8695
|
+
if (hasContainer && existsSync14(destContainer)) {
|
|
8251
8696
|
throw new Error(
|
|
8252
8697
|
`Refusing to restore: ${destContainer} already exists. Remove the current container first (\`monoceros remove ${name}\`).`
|
|
8253
8698
|
);
|
|
8254
8699
|
}
|
|
8255
8700
|
await fs16.mkdir(containerConfigsDir(home), { recursive: true });
|
|
8256
|
-
await fs16.copyFile(
|
|
8701
|
+
await fs16.copyFile(path22.join(backup, ymlFile), destYml);
|
|
8257
8702
|
if (hasEnv) {
|
|
8258
8703
|
await fs16.copyFile(envInBackup, containerEnvPath(name, home));
|
|
8259
8704
|
}
|
|
@@ -8278,14 +8723,14 @@ var init_restore = __esm({
|
|
|
8278
8723
|
});
|
|
8279
8724
|
|
|
8280
8725
|
// src/commands/restore.ts
|
|
8281
|
-
import { defineCommand as
|
|
8282
|
-
import { consola as
|
|
8726
|
+
import { defineCommand as defineCommand19 } from "citty";
|
|
8727
|
+
import { consola as consola24 } from "consola";
|
|
8283
8728
|
var restoreCommand;
|
|
8284
8729
|
var init_restore2 = __esm({
|
|
8285
8730
|
"src/commands/restore.ts"() {
|
|
8286
8731
|
"use strict";
|
|
8287
8732
|
init_restore();
|
|
8288
|
-
restoreCommand =
|
|
8733
|
+
restoreCommand = defineCommand19({
|
|
8289
8734
|
meta: {
|
|
8290
8735
|
name: "restore",
|
|
8291
8736
|
group: "lifecycle",
|
|
@@ -8302,7 +8747,7 @@ var init_restore2 = __esm({
|
|
|
8302
8747
|
try {
|
|
8303
8748
|
await runRestore({ backupPath: args["backup-path"] });
|
|
8304
8749
|
} catch (err) {
|
|
8305
|
-
|
|
8750
|
+
consola24.error(err instanceof Error ? err.message : String(err));
|
|
8306
8751
|
process.exit(1);
|
|
8307
8752
|
}
|
|
8308
8753
|
}
|
|
@@ -8311,14 +8756,14 @@ var init_restore2 = __esm({
|
|
|
8311
8756
|
});
|
|
8312
8757
|
|
|
8313
8758
|
// src/commands/remove-from-url.ts
|
|
8314
|
-
import { defineCommand as
|
|
8315
|
-
import { consola as
|
|
8759
|
+
import { defineCommand as defineCommand20 } from "citty";
|
|
8760
|
+
import { consola as consola25 } from "consola";
|
|
8316
8761
|
var removeFromUrlCommand;
|
|
8317
8762
|
var init_remove_from_url = __esm({
|
|
8318
8763
|
"src/commands/remove-from-url.ts"() {
|
|
8319
8764
|
"use strict";
|
|
8320
8765
|
init_modify();
|
|
8321
|
-
removeFromUrlCommand =
|
|
8766
|
+
removeFromUrlCommand = defineCommand20({
|
|
8322
8767
|
meta: {
|
|
8323
8768
|
name: "remove-from-url",
|
|
8324
8769
|
group: "edit",
|
|
@@ -8351,7 +8796,7 @@ var init_remove_from_url = __esm({
|
|
|
8351
8796
|
});
|
|
8352
8797
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
8353
8798
|
} catch (err) {
|
|
8354
|
-
|
|
8799
|
+
consola25.error(err instanceof Error ? err.message : String(err));
|
|
8355
8800
|
process.exit(1);
|
|
8356
8801
|
}
|
|
8357
8802
|
}
|
|
@@ -8360,14 +8805,14 @@ var init_remove_from_url = __esm({
|
|
|
8360
8805
|
});
|
|
8361
8806
|
|
|
8362
8807
|
// src/commands/remove-language.ts
|
|
8363
|
-
import { defineCommand as
|
|
8364
|
-
import { consola as
|
|
8808
|
+
import { defineCommand as defineCommand21 } from "citty";
|
|
8809
|
+
import { consola as consola26 } from "consola";
|
|
8365
8810
|
var removeLanguageCommand;
|
|
8366
8811
|
var init_remove_language = __esm({
|
|
8367
8812
|
"src/commands/remove-language.ts"() {
|
|
8368
8813
|
"use strict";
|
|
8369
8814
|
init_modify();
|
|
8370
|
-
removeLanguageCommand =
|
|
8815
|
+
removeLanguageCommand = defineCommand21({
|
|
8371
8816
|
meta: {
|
|
8372
8817
|
name: "remove-language",
|
|
8373
8818
|
group: "edit",
|
|
@@ -8400,7 +8845,7 @@ var init_remove_language = __esm({
|
|
|
8400
8845
|
});
|
|
8401
8846
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
8402
8847
|
} catch (err) {
|
|
8403
|
-
|
|
8848
|
+
consola26.error(err instanceof Error ? err.message : String(err));
|
|
8404
8849
|
process.exit(1);
|
|
8405
8850
|
}
|
|
8406
8851
|
}
|
|
@@ -8409,8 +8854,8 @@ var init_remove_language = __esm({
|
|
|
8409
8854
|
});
|
|
8410
8855
|
|
|
8411
8856
|
// src/commands/remove-port.ts
|
|
8412
|
-
import { defineCommand as
|
|
8413
|
-
import { consola as
|
|
8857
|
+
import { defineCommand as defineCommand22 } from "citty";
|
|
8858
|
+
import { consola as consola27 } from "consola";
|
|
8414
8859
|
function coerceToken2(raw) {
|
|
8415
8860
|
const n = Number(raw);
|
|
8416
8861
|
return Number.isFinite(n) ? n : raw;
|
|
@@ -8421,7 +8866,7 @@ var init_remove_port = __esm({
|
|
|
8421
8866
|
"use strict";
|
|
8422
8867
|
init_inner_args();
|
|
8423
8868
|
init_modify();
|
|
8424
|
-
removePortCommand =
|
|
8869
|
+
removePortCommand = defineCommand22({
|
|
8425
8870
|
meta: {
|
|
8426
8871
|
name: "remove-port",
|
|
8427
8872
|
group: "edit",
|
|
@@ -8443,7 +8888,7 @@ var init_remove_port = __esm({
|
|
|
8443
8888
|
async run({ args }) {
|
|
8444
8889
|
const tokens = [...getInnerArgs()];
|
|
8445
8890
|
if (tokens.length === 0) {
|
|
8446
|
-
|
|
8891
|
+
consola27.error(
|
|
8447
8892
|
"No ports given. Usage: `monoceros remove-port <containername> [--yes] -- <port> [<port> \u2026]`."
|
|
8448
8893
|
);
|
|
8449
8894
|
process.exit(1);
|
|
@@ -8456,7 +8901,7 @@ var init_remove_port = __esm({
|
|
|
8456
8901
|
});
|
|
8457
8902
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
8458
8903
|
} catch (err) {
|
|
8459
|
-
|
|
8904
|
+
consola27.error(err instanceof Error ? err.message : String(err));
|
|
8460
8905
|
process.exit(1);
|
|
8461
8906
|
}
|
|
8462
8907
|
}
|
|
@@ -8465,14 +8910,14 @@ var init_remove_port = __esm({
|
|
|
8465
8910
|
});
|
|
8466
8911
|
|
|
8467
8912
|
// src/commands/remove-repo.ts
|
|
8468
|
-
import { defineCommand as
|
|
8469
|
-
import { consola as
|
|
8913
|
+
import { defineCommand as defineCommand23 } from "citty";
|
|
8914
|
+
import { consola as consola28 } from "consola";
|
|
8470
8915
|
var removeRepoCommand;
|
|
8471
8916
|
var init_remove_repo = __esm({
|
|
8472
8917
|
"src/commands/remove-repo.ts"() {
|
|
8473
8918
|
"use strict";
|
|
8474
8919
|
init_modify();
|
|
8475
|
-
removeRepoCommand =
|
|
8920
|
+
removeRepoCommand = defineCommand23({
|
|
8476
8921
|
meta: {
|
|
8477
8922
|
name: "remove-repo",
|
|
8478
8923
|
group: "edit",
|
|
@@ -8505,7 +8950,7 @@ var init_remove_repo = __esm({
|
|
|
8505
8950
|
});
|
|
8506
8951
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
8507
8952
|
} catch (err) {
|
|
8508
|
-
|
|
8953
|
+
consola28.error(err instanceof Error ? err.message : String(err));
|
|
8509
8954
|
process.exit(1);
|
|
8510
8955
|
}
|
|
8511
8956
|
}
|
|
@@ -8514,14 +8959,14 @@ var init_remove_repo = __esm({
|
|
|
8514
8959
|
});
|
|
8515
8960
|
|
|
8516
8961
|
// src/commands/remove-service.ts
|
|
8517
|
-
import { defineCommand as
|
|
8518
|
-
import { consola as
|
|
8962
|
+
import { defineCommand as defineCommand24 } from "citty";
|
|
8963
|
+
import { consola as consola29 } from "consola";
|
|
8519
8964
|
var removeServiceCommand;
|
|
8520
8965
|
var init_remove_service = __esm({
|
|
8521
8966
|
"src/commands/remove-service.ts"() {
|
|
8522
8967
|
"use strict";
|
|
8523
8968
|
init_modify();
|
|
8524
|
-
removeServiceCommand =
|
|
8969
|
+
removeServiceCommand = defineCommand24({
|
|
8525
8970
|
meta: {
|
|
8526
8971
|
name: "remove-service",
|
|
8527
8972
|
group: "edit",
|
|
@@ -8554,7 +8999,7 @@ var init_remove_service = __esm({
|
|
|
8554
8999
|
});
|
|
8555
9000
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
8556
9001
|
} catch (err) {
|
|
8557
|
-
|
|
9002
|
+
consola29.error(err instanceof Error ? err.message : String(err));
|
|
8558
9003
|
process.exit(1);
|
|
8559
9004
|
}
|
|
8560
9005
|
}
|
|
@@ -8562,44 +9007,6 @@ var init_remove_service = __esm({
|
|
|
8562
9007
|
}
|
|
8563
9008
|
});
|
|
8564
9009
|
|
|
8565
|
-
// src/devcontainer/shell.ts
|
|
8566
|
-
import { existsSync as existsSync12 } from "fs";
|
|
8567
|
-
import path20 from "path";
|
|
8568
|
-
async function runShell(opts) {
|
|
8569
|
-
assertContainerExists(opts.root);
|
|
8570
|
-
const spawnFn = opts.spawn ?? spawnDevcontainer;
|
|
8571
|
-
const upCode = await spawnFn(
|
|
8572
|
-
["up", "--workspace-folder", opts.root, "--mount-workspace-git-root=false"],
|
|
8573
|
-
opts.root,
|
|
8574
|
-
{ quiet: true }
|
|
8575
|
-
);
|
|
8576
|
-
if (upCode !== 0) return upCode;
|
|
8577
|
-
return spawnFn(
|
|
8578
|
-
[
|
|
8579
|
-
"exec",
|
|
8580
|
-
"--workspace-folder",
|
|
8581
|
-
opts.root,
|
|
8582
|
-
"--mount-workspace-git-root=false",
|
|
8583
|
-
"bash"
|
|
8584
|
-
],
|
|
8585
|
-
opts.root,
|
|
8586
|
-
{ interactive: true }
|
|
8587
|
-
);
|
|
8588
|
-
}
|
|
8589
|
-
function assertContainerExists(root) {
|
|
8590
|
-
if (!existsSync12(path20.join(root, ".devcontainer"))) {
|
|
8591
|
-
throw new Error(
|
|
8592
|
-
`No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
|
|
8593
|
-
);
|
|
8594
|
-
}
|
|
8595
|
-
}
|
|
8596
|
-
var init_shell = __esm({
|
|
8597
|
-
"src/devcontainer/shell.ts"() {
|
|
8598
|
-
"use strict";
|
|
8599
|
-
init_cli();
|
|
8600
|
-
}
|
|
8601
|
-
});
|
|
8602
|
-
|
|
8603
9010
|
// src/devcontainer/run.ts
|
|
8604
9011
|
async function runInContainer(opts) {
|
|
8605
9012
|
if (opts.command.length === 0) {
|
|
@@ -8644,8 +9051,8 @@ var init_run = __esm({
|
|
|
8644
9051
|
});
|
|
8645
9052
|
|
|
8646
9053
|
// src/commands/run.ts
|
|
8647
|
-
import { defineCommand as
|
|
8648
|
-
import { consola as
|
|
9054
|
+
import { defineCommand as defineCommand25 } from "citty";
|
|
9055
|
+
import { consola as consola30 } from "consola";
|
|
8649
9056
|
var runCommand;
|
|
8650
9057
|
var init_run2 = __esm({
|
|
8651
9058
|
"src/commands/run.ts"() {
|
|
@@ -8653,7 +9060,7 @@ var init_run2 = __esm({
|
|
|
8653
9060
|
init_paths();
|
|
8654
9061
|
init_run();
|
|
8655
9062
|
init_inner_args();
|
|
8656
|
-
runCommand =
|
|
9063
|
+
runCommand = defineCommand25({
|
|
8657
9064
|
meta: {
|
|
8658
9065
|
name: "run",
|
|
8659
9066
|
group: "run",
|
|
@@ -8673,7 +9080,7 @@ var init_run2 = __esm({
|
|
|
8673
9080
|
async run({ args }) {
|
|
8674
9081
|
const command = [...getInnerArgs()];
|
|
8675
9082
|
if (command.length === 0) {
|
|
8676
|
-
|
|
9083
|
+
consola30.error(
|
|
8677
9084
|
"No command provided. Usage: `monoceros run <containername> -- <cmd> [args\u2026]`."
|
|
8678
9085
|
);
|
|
8679
9086
|
process.exit(1);
|
|
@@ -8686,7 +9093,7 @@ var init_run2 = __esm({
|
|
|
8686
9093
|
});
|
|
8687
9094
|
process.exit(exitCode);
|
|
8688
9095
|
} catch (err) {
|
|
8689
|
-
|
|
9096
|
+
consola30.error(err instanceof Error ? err.message : String(err));
|
|
8690
9097
|
process.exit(1);
|
|
8691
9098
|
}
|
|
8692
9099
|
}
|
|
@@ -8695,15 +9102,15 @@ var init_run2 = __esm({
|
|
|
8695
9102
|
});
|
|
8696
9103
|
|
|
8697
9104
|
// src/commands/shell.ts
|
|
8698
|
-
import { defineCommand as
|
|
8699
|
-
import { consola as
|
|
9105
|
+
import { defineCommand as defineCommand26 } from "citty";
|
|
9106
|
+
import { consola as consola31 } from "consola";
|
|
8700
9107
|
var shellCommand;
|
|
8701
9108
|
var init_shell2 = __esm({
|
|
8702
9109
|
"src/commands/shell.ts"() {
|
|
8703
9110
|
"use strict";
|
|
8704
9111
|
init_paths();
|
|
8705
9112
|
init_shell();
|
|
8706
|
-
shellCommand =
|
|
9113
|
+
shellCommand = defineCommand26({
|
|
8707
9114
|
meta: {
|
|
8708
9115
|
name: "shell",
|
|
8709
9116
|
group: "run",
|
|
@@ -8721,7 +9128,7 @@ var init_shell2 = __esm({
|
|
|
8721
9128
|
const exitCode = await runShell({ root: containerDir(args.name) });
|
|
8722
9129
|
process.exit(exitCode);
|
|
8723
9130
|
} catch (err) {
|
|
8724
|
-
|
|
9131
|
+
consola31.error(err instanceof Error ? err.message : String(err));
|
|
8725
9132
|
process.exit(1);
|
|
8726
9133
|
}
|
|
8727
9134
|
}
|
|
@@ -8730,8 +9137,8 @@ var init_shell2 = __esm({
|
|
|
8730
9137
|
});
|
|
8731
9138
|
|
|
8732
9139
|
// src/commands/start.ts
|
|
8733
|
-
import { defineCommand as
|
|
8734
|
-
import { consola as
|
|
9140
|
+
import { defineCommand as defineCommand27 } from "citty";
|
|
9141
|
+
import { consola as consola32 } from "consola";
|
|
8735
9142
|
var startCommand;
|
|
8736
9143
|
var init_start = __esm({
|
|
8737
9144
|
"src/commands/start.ts"() {
|
|
@@ -8743,7 +9150,7 @@ var init_start = __esm({
|
|
|
8743
9150
|
init_proxy();
|
|
8744
9151
|
init_port_check();
|
|
8745
9152
|
init_dispatch();
|
|
8746
|
-
startCommand =
|
|
9153
|
+
startCommand = defineCommand27({
|
|
8747
9154
|
meta: {
|
|
8748
9155
|
name: "start",
|
|
8749
9156
|
group: "run",
|
|
@@ -8768,7 +9175,7 @@ var init_start = __esm({
|
|
|
8768
9175
|
hostPort = proxyHostPort(global);
|
|
8769
9176
|
}
|
|
8770
9177
|
} catch (err) {
|
|
8771
|
-
|
|
9178
|
+
consola32.warn(
|
|
8772
9179
|
`Could not read container yml ahead of start: ${err instanceof Error ? err.message : String(err)}. Skipping Traefik pre-flight.`
|
|
8773
9180
|
);
|
|
8774
9181
|
}
|
|
@@ -8784,7 +9191,7 @@ var init_start = __esm({
|
|
|
8784
9191
|
});
|
|
8785
9192
|
|
|
8786
9193
|
// src/commands/status.ts
|
|
8787
|
-
import { defineCommand as
|
|
9194
|
+
import { defineCommand as defineCommand28 } from "citty";
|
|
8788
9195
|
var statusCommand;
|
|
8789
9196
|
var init_status = __esm({
|
|
8790
9197
|
"src/commands/status.ts"() {
|
|
@@ -8792,7 +9199,7 @@ var init_status = __esm({
|
|
|
8792
9199
|
init_paths();
|
|
8793
9200
|
init_compose();
|
|
8794
9201
|
init_dispatch();
|
|
8795
|
-
statusCommand =
|
|
9202
|
+
statusCommand = defineCommand28({
|
|
8796
9203
|
meta: {
|
|
8797
9204
|
name: "status",
|
|
8798
9205
|
group: "run",
|
|
@@ -8822,8 +9229,8 @@ var init_status = __esm({
|
|
|
8822
9229
|
});
|
|
8823
9230
|
|
|
8824
9231
|
// src/commands/stop.ts
|
|
8825
|
-
import { defineCommand as
|
|
8826
|
-
import { consola as
|
|
9232
|
+
import { defineCommand as defineCommand29 } from "citty";
|
|
9233
|
+
import { consola as consola33 } from "consola";
|
|
8827
9234
|
var stopCommand;
|
|
8828
9235
|
var init_stop = __esm({
|
|
8829
9236
|
"src/commands/stop.ts"() {
|
|
@@ -8832,7 +9239,7 @@ var init_stop = __esm({
|
|
|
8832
9239
|
init_compose();
|
|
8833
9240
|
init_proxy();
|
|
8834
9241
|
init_dispatch();
|
|
8835
|
-
stopCommand =
|
|
9242
|
+
stopCommand = defineCommand29({
|
|
8836
9243
|
meta: {
|
|
8837
9244
|
name: "stop",
|
|
8838
9245
|
group: "run",
|
|
@@ -8857,10 +9264,10 @@ var init_stop = __esm({
|
|
|
8857
9264
|
});
|
|
8858
9265
|
try {
|
|
8859
9266
|
await maybeStopProxy({
|
|
8860
|
-
logger: { info: (msg) =>
|
|
9267
|
+
logger: { info: (msg) => consola33.info(msg) }
|
|
8861
9268
|
});
|
|
8862
9269
|
} catch (err) {
|
|
8863
|
-
|
|
9270
|
+
consola33.warn(
|
|
8864
9271
|
`Could not tear down the Traefik proxy: ${err instanceof Error ? err.message : String(err)}. Ignored.`
|
|
8865
9272
|
);
|
|
8866
9273
|
}
|
|
@@ -8872,11 +9279,11 @@ var init_stop = __esm({
|
|
|
8872
9279
|
});
|
|
8873
9280
|
|
|
8874
9281
|
// src/tunnel/resolve.ts
|
|
8875
|
-
import { existsSync as
|
|
8876
|
-
import
|
|
9282
|
+
import { existsSync as existsSync15 } from "fs";
|
|
9283
|
+
import path23 from "path";
|
|
8877
9284
|
async function resolveTunnelTarget(opts) {
|
|
8878
9285
|
const ymlPath = containerConfigPath(opts.name, opts.monocerosHome);
|
|
8879
|
-
if (!
|
|
9286
|
+
if (!existsSync15(ymlPath)) {
|
|
8880
9287
|
throw new Error(
|
|
8881
9288
|
`No yml profile for '${opts.name}' at ${ymlPath}. Run \`monoceros init ${opts.name}\` first.`
|
|
8882
9289
|
);
|
|
@@ -8884,13 +9291,13 @@ async function resolveTunnelTarget(opts) {
|
|
|
8884
9291
|
const parsed = await readConfig(ymlPath);
|
|
8885
9292
|
const config = parsed.config;
|
|
8886
9293
|
const containerRoot = containerDir(opts.name, opts.monocerosHome);
|
|
8887
|
-
if (!
|
|
9294
|
+
if (!existsSync15(containerRoot)) {
|
|
8888
9295
|
throw new Error(
|
|
8889
9296
|
`Container '${opts.name}' is not materialised at ${containerRoot}. Run \`monoceros apply ${opts.name}\` first.`
|
|
8890
9297
|
);
|
|
8891
9298
|
}
|
|
8892
|
-
const composePath =
|
|
8893
|
-
const isCompose =
|
|
9299
|
+
const composePath = path23.join(containerRoot, ".devcontainer", "compose.yaml");
|
|
9300
|
+
const isCompose = existsSync15(composePath);
|
|
8894
9301
|
const parsedTarget = parseTargetArg(opts.target, config);
|
|
8895
9302
|
const docker = opts.docker ?? defaultDockerExec;
|
|
8896
9303
|
if (isCompose) {
|
|
@@ -9125,8 +9532,8 @@ var init_port_check2 = __esm({
|
|
|
9125
9532
|
});
|
|
9126
9533
|
|
|
9127
9534
|
// src/tunnel/run.ts
|
|
9128
|
-
import { spawn as
|
|
9129
|
-
import { consola as
|
|
9535
|
+
import { spawn as spawn10 } from "child_process";
|
|
9536
|
+
import { consola as consola34 } from "consola";
|
|
9130
9537
|
function signalNumber(signal) {
|
|
9131
9538
|
switch (signal) {
|
|
9132
9539
|
case "SIGINT":
|
|
@@ -9139,8 +9546,8 @@ function signalNumber(signal) {
|
|
|
9139
9546
|
}
|
|
9140
9547
|
async function runTunnel(opts) {
|
|
9141
9548
|
const log = opts.logger ?? {
|
|
9142
|
-
info: (m) =>
|
|
9143
|
-
warn: (m) =>
|
|
9549
|
+
info: (m) => consola34.info(m),
|
|
9550
|
+
warn: (m) => consola34.warn(m)
|
|
9144
9551
|
};
|
|
9145
9552
|
const resolve = opts.resolve ?? resolveTunnelTarget;
|
|
9146
9553
|
const resolveArgs3 = {
|
|
@@ -9215,7 +9622,7 @@ var init_run3 = __esm({
|
|
|
9215
9622
|
init_port_check2();
|
|
9216
9623
|
SOCAT_IMAGE = "alpine/socat:1.8.0.3";
|
|
9217
9624
|
defaultDockerSpawn = (args) => {
|
|
9218
|
-
const child =
|
|
9625
|
+
const child = spawn10("docker", args, {
|
|
9219
9626
|
stdio: "inherit"
|
|
9220
9627
|
});
|
|
9221
9628
|
const exited = new Promise((resolve, reject) => {
|
|
@@ -9246,8 +9653,8 @@ var init_run3 = __esm({
|
|
|
9246
9653
|
});
|
|
9247
9654
|
|
|
9248
9655
|
// src/commands/tunnel.ts
|
|
9249
|
-
import { defineCommand as
|
|
9250
|
-
import { consola as
|
|
9656
|
+
import { defineCommand as defineCommand30 } from "citty";
|
|
9657
|
+
import { consola as consola35 } from "consola";
|
|
9251
9658
|
function parseLocalPort(raw) {
|
|
9252
9659
|
if (raw === void 0) return void 0;
|
|
9253
9660
|
const n = Number(raw);
|
|
@@ -9263,7 +9670,7 @@ var init_tunnel = __esm({
|
|
|
9263
9670
|
"src/commands/tunnel.ts"() {
|
|
9264
9671
|
"use strict";
|
|
9265
9672
|
init_run3();
|
|
9266
|
-
tunnelCommand =
|
|
9673
|
+
tunnelCommand = defineCommand30({
|
|
9267
9674
|
meta: {
|
|
9268
9675
|
name: "tunnel",
|
|
9269
9676
|
group: "discovery",
|
|
@@ -9300,7 +9707,7 @@ var init_tunnel = __esm({
|
|
|
9300
9707
|
});
|
|
9301
9708
|
process.exit(exitCode);
|
|
9302
9709
|
} catch (err) {
|
|
9303
|
-
|
|
9710
|
+
consola35.error(err instanceof Error ? err.message : String(err));
|
|
9304
9711
|
process.exit(1);
|
|
9305
9712
|
}
|
|
9306
9713
|
}
|
|
@@ -9309,8 +9716,8 @@ var init_tunnel = __esm({
|
|
|
9309
9716
|
});
|
|
9310
9717
|
|
|
9311
9718
|
// src/upgrade/index.ts
|
|
9312
|
-
import { existsSync as
|
|
9313
|
-
import { consola as
|
|
9719
|
+
import { existsSync as existsSync16, promises as fs17 } from "fs";
|
|
9720
|
+
import { consola as consola36 } from "consola";
|
|
9314
9721
|
async function fetchRuntimeVersions() {
|
|
9315
9722
|
const tokenUrl = `https://ghcr.io/token?service=ghcr.io&scope=repository:${RUNTIME_REPO}:pull`;
|
|
9316
9723
|
const tokenRes = await fetch(tokenUrl);
|
|
@@ -9348,7 +9755,7 @@ ${yml}`;
|
|
|
9348
9755
|
}
|
|
9349
9756
|
async function runUpgrade(opts) {
|
|
9350
9757
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
9351
|
-
const logger = opts.logger ??
|
|
9758
|
+
const logger = opts.logger ?? consola36;
|
|
9352
9759
|
const fetchVersions = opts.fetchVersions ?? fetchRuntimeVersions;
|
|
9353
9760
|
if (opts.list) {
|
|
9354
9761
|
const versions = await fetchVersions();
|
|
@@ -9368,7 +9775,7 @@ async function runUpgrade(opts) {
|
|
|
9368
9775
|
);
|
|
9369
9776
|
}
|
|
9370
9777
|
const ymlPath = containerConfigPath(opts.name, home);
|
|
9371
|
-
if (!
|
|
9778
|
+
if (!existsSync16(ymlPath)) {
|
|
9372
9779
|
throw new Error(
|
|
9373
9780
|
`No such config: ${ymlPath}. Run \`monoceros init <template> ${opts.name}\` first.`
|
|
9374
9781
|
);
|
|
@@ -9416,7 +9823,7 @@ var init_upgrade = __esm({
|
|
|
9416
9823
|
});
|
|
9417
9824
|
|
|
9418
9825
|
// src/commands/upgrade.ts
|
|
9419
|
-
import { defineCommand as
|
|
9826
|
+
import { defineCommand as defineCommand31 } from "citty";
|
|
9420
9827
|
var upgradeCommand;
|
|
9421
9828
|
var init_upgrade2 = __esm({
|
|
9422
9829
|
"src/commands/upgrade.ts"() {
|
|
@@ -9424,7 +9831,7 @@ var init_upgrade2 = __esm({
|
|
|
9424
9831
|
init_upgrade();
|
|
9425
9832
|
init_version();
|
|
9426
9833
|
init_dispatch();
|
|
9427
|
-
upgradeCommand =
|
|
9834
|
+
upgradeCommand = defineCommand31({
|
|
9428
9835
|
meta: {
|
|
9429
9836
|
name: "upgrade",
|
|
9430
9837
|
group: "lifecycle",
|
|
@@ -9466,7 +9873,7 @@ var main_exports = {};
|
|
|
9466
9873
|
__export(main_exports, {
|
|
9467
9874
|
main: () => main
|
|
9468
9875
|
});
|
|
9469
|
-
import { defineCommand as
|
|
9876
|
+
import { defineCommand as defineCommand32 } from "citty";
|
|
9470
9877
|
var main;
|
|
9471
9878
|
var init_main = __esm({
|
|
9472
9879
|
"src/main.ts"() {
|
|
@@ -9483,6 +9890,7 @@ var init_main = __esm({
|
|
|
9483
9890
|
init_complete();
|
|
9484
9891
|
init_init2();
|
|
9485
9892
|
init_list_components();
|
|
9893
|
+
init_login2();
|
|
9486
9894
|
init_logs();
|
|
9487
9895
|
init_port();
|
|
9488
9896
|
init_remove_apt_packages();
|
|
@@ -9502,7 +9910,7 @@ var init_main = __esm({
|
|
|
9502
9910
|
init_tunnel();
|
|
9503
9911
|
init_upgrade2();
|
|
9504
9912
|
init_version();
|
|
9505
|
-
main =
|
|
9913
|
+
main = defineCommand32({
|
|
9506
9914
|
meta: {
|
|
9507
9915
|
name: "monoceros",
|
|
9508
9916
|
version: CLI_VERSION,
|
|
@@ -9513,6 +9921,7 @@ var init_main = __esm({
|
|
|
9513
9921
|
"list-components": listComponentsCommand,
|
|
9514
9922
|
shell: shellCommand,
|
|
9515
9923
|
run: runCommand,
|
|
9924
|
+
login: loginCommand,
|
|
9516
9925
|
logs: logsCommand,
|
|
9517
9926
|
start: startCommand,
|
|
9518
9927
|
stop: stopCommand,
|
|
@@ -9798,25 +10207,25 @@ function detectHelpRequest(argv, main2) {
|
|
|
9798
10207
|
const separatorIdx = argv.indexOf("--");
|
|
9799
10208
|
if (helpIdx === -1) return null;
|
|
9800
10209
|
if (separatorIdx !== -1 && separatorIdx < helpIdx) return null;
|
|
9801
|
-
const
|
|
10210
|
+
const path24 = [];
|
|
9802
10211
|
const tokens = argv.slice(
|
|
9803
10212
|
0,
|
|
9804
10213
|
separatorIdx === -1 ? argv.length : separatorIdx
|
|
9805
10214
|
);
|
|
9806
10215
|
let cursor = main2;
|
|
9807
10216
|
const mainName = (main2.meta ?? {}).name ?? "monoceros";
|
|
9808
|
-
|
|
10217
|
+
path24.push(mainName);
|
|
9809
10218
|
for (const tok of tokens) {
|
|
9810
10219
|
if (tok.startsWith("-")) continue;
|
|
9811
10220
|
const subs = cursor.subCommands ?? {};
|
|
9812
10221
|
if (tok in subs) {
|
|
9813
10222
|
cursor = subs[tok];
|
|
9814
|
-
|
|
10223
|
+
path24.push(tok);
|
|
9815
10224
|
continue;
|
|
9816
10225
|
}
|
|
9817
10226
|
break;
|
|
9818
10227
|
}
|
|
9819
|
-
return { path:
|
|
10228
|
+
return { path: path24, cmd: cursor };
|
|
9820
10229
|
}
|
|
9821
10230
|
async function maybeRenderHelp(argv, main2) {
|
|
9822
10231
|
const hit = detectHelpRequest(argv, main2);
|