@getmonoceros/workbench 1.7.2 → 1.7.4

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 CHANGED
@@ -365,7 +365,7 @@ var GitUserSchema = z.object({
365
365
  var RepoEntrySchema = z.object({
366
366
  url: z.string().regex(
367
367
  REPO_URL_RE,
368
- "Invalid repo URL. Only HTTPS URLs are supported (https://...). SSH-style URLs (git@host:..., ssh://...) are not in scope \u2014 see ADR 0006."
368
+ "Invalid repo URL. Only HTTPS URLs are supported (https://...). SSH-style URLs (git@host:..., ssh://...) are not supported."
369
369
  ),
370
370
  path: z.string().regex(
371
371
  REPO_PATH_RE,
@@ -824,22 +824,42 @@ function proxyUrlsFor(name, ports, hostPort = 80) {
824
824
  }
825
825
 
826
826
  // src/proxy/port-check.ts
827
- import { createServer } from "net";
827
+ import { Socket } from "net";
828
+ var CONNECT_TIMEOUT_MS = 750;
828
829
  var realPortProbe = (port) => {
829
830
  return new Promise((resolve) => {
830
- const server = createServer();
831
- server.unref();
832
- server.once("error", (err) => {
833
- resolve({
831
+ const socket = new Socket();
832
+ let settled = false;
833
+ const settle = (result) => {
834
+ if (settled) return;
835
+ settled = true;
836
+ socket.destroy();
837
+ resolve(result);
838
+ };
839
+ socket.setTimeout(CONNECT_TIMEOUT_MS);
840
+ socket.once("connect", () => {
841
+ settle({
834
842
  ok: false,
835
- code: err.code ?? "UNKNOWN",
836
- message: err.message
843
+ code: "EADDRINUSE",
844
+ message: `another process is listening on ${port}`
837
845
  });
838
846
  });
839
- server.once("listening", () => {
840
- server.close(() => resolve({ ok: true }));
847
+ socket.once("timeout", () => {
848
+ settle({ ok: true });
841
849
  });
842
- server.listen(port, "0.0.0.0");
850
+ socket.once("error", (err) => {
851
+ const code = err.code ?? "UNKNOWN";
852
+ if (code === "ECONNREFUSED") {
853
+ settle({ ok: true });
854
+ } else {
855
+ settle({
856
+ ok: false,
857
+ code,
858
+ message: err.message
859
+ });
860
+ }
861
+ });
862
+ socket.connect(port, "127.0.0.1");
843
863
  });
844
864
  };
845
865
  async function preflightHostPort(hostPort, opts = {}) {
@@ -887,16 +907,16 @@ function formatHostPortHeldError(hostPort, code, systemMessage) {
887
907
  lines.push("");
888
908
  lines.push(`Aborting \u2014 re-run after the conflict is resolved.`);
889
909
  } else {
890
- lines.push(`Cannot bind host port ${hostPort}: ${systemMessage}`);
910
+ lines.push(`Cannot reach host port ${hostPort}: ${systemMessage}`);
911
+ lines.push("");
912
+ lines.push(`This is not the typical "port already in use" case \u2014`);
913
+ lines.push(`Monoceros's pre-flight uses a TCP-connect probe (not a`);
914
+ lines.push(`bind), so EACCES / privileged-port errors normally don't`);
915
+ lines.push(`appear here. Most likely something on your host network`);
916
+ lines.push(`stack (firewall, network namespace, \u2026) is interfering with`);
917
+ lines.push(`loopback connects.`);
891
918
  lines.push("");
892
- if (code === "EACCES") {
893
- lines.push(`Port ${hostPort} is a privileged port (<1024) and your`);
894
- lines.push(`current Docker setup can't bind it. For rootful Docker`);
895
- lines.push(`(what Monoceros requires) this should normally work \u2014`);
896
- lines.push(`check that the docker daemon is running as root.`);
897
- lines.push("");
898
- }
899
- lines.push("You can also move Monoceros off this port by setting");
919
+ lines.push("Workaround: move Monoceros off this port by setting");
900
920
  lines.push("`routing.hostPort` in ~/.monoceros/monoceros-config.yml.");
901
921
  lines.push("");
902
922
  lines.push(`Aborting \u2014 re-run after the issue is resolved.`);
@@ -3303,8 +3323,7 @@ function formatRootlessNotSupportedError() {
3303
3323
  `shell. Otherwise new terminals keep pointing at the rootless`,
3304
3324
  `socket and Monoceros's auto-recovery has nothing to fall back to.`,
3305
3325
  ``,
3306
- `Then re-run. Background: see ${cyan2("docs/docker-on-linux.md")} in`,
3307
- `the workbench repo.`
3326
+ `Then re-run.`
3308
3327
  ].join("\n");
3309
3328
  }
3310
3329
 
@@ -3611,7 +3630,7 @@ function warnOnDeprecatedFeatureRefs(containerFeatures, globalConfig, logger) {
3611
3630
  }
3612
3631
 
3613
3632
  // src/version.ts
3614
- var CLI_VERSION = true ? "1.7.2" : "dev";
3633
+ var CLI_VERSION = true ? "1.7.4" : "dev";
3615
3634
 
3616
3635
  // src/commands/_dispatch.ts
3617
3636
  import { consola as consola12 } from "consola";
@@ -4041,10 +4060,9 @@ var SCHEMA_HEADER = [
4041
4060
  "# Monoceros solution-config. Edit freely, then run",
4042
4061
  "# `monoceros apply <name>` to materialize a dev-container.",
4043
4062
  "#",
4044
- "# Schema reference: see the workbench `templates/components/README.md`",
4045
- "# and `docs/konzept.md` for what each section does. Each feature",
4046
- "# under `features:` also accepts options not shown here \u2014 check",
4047
- "# the feature's `devcontainer-feature.json` for the full list."
4063
+ "# Each section below carries inline comments for the options it",
4064
+ "# accepts. Features expose additional knobs as commented hints",
4065
+ "# under their `options:` block \u2014 un-comment what you need."
4048
4066
  ];
4049
4067
  function generateComposedYml(name, components, lookupManifest, repoUrls = [], ports = []) {
4050
4068
  const merged = mergeComponents(components);
@@ -4259,7 +4277,7 @@ function emitHint(out, hint, description, linePrefix) {
4259
4277
  }
4260
4278
  function renderReposBlock(out, urls, commented) {
4261
4279
  out.push("# Repos \u2014 git repositories cloned into projects/ during");
4262
- out.push("# post-create. HTTPS-only (ADR 0006). Provider auto-detected");
4280
+ out.push("# post-create. HTTPS URLs only. Provider auto-detected");
4263
4281
  out.push("# for github.com, gitlab.com, bitbucket.org; for any other host");
4264
4282
  out.push("# (self-hosted GitLab, Bitbucket Data Center, Gitea/Forgejo,");
4265
4283
  out.push("# GitHub Enterprise, \u2026) declare provider explicitly.");
@@ -4330,7 +4348,7 @@ function renderRoutingHintBlock(out) {
4330
4348
  function renderActiveRoutingBlock(out, name, ports) {
4331
4349
  out.push("# Routing \u2014 expose these container ports to the host through");
4332
4350
  out.push("# the shared Traefik singleton. First entry doubles as");
4333
- out.push(`# http://${name}.localhost (the default route). See ADR 0007.`);
4351
+ out.push(`# http://${name}.localhost (the default route).`);
4334
4352
  out.push("routing:");
4335
4353
  out.push(" ports:");
4336
4354
  ports.forEach((port, idx) => {