@devrouter/cli 0.0.69 → 0.0.71

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.
@@ -5159,7 +5159,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs14.default.rea
5159
5159
  const config = parseConfig(parsed ?? {}, configPath);
5160
5160
  const requiredVersion = config.devrouter?.version;
5161
5161
  if (requiredVersion && !hasWarnedVersionMismatch) {
5162
- const cliVersion = true ? "0.0.69" : "0.0.0-dev";
5162
+ const cliVersion = true ? "0.0.71" : "0.0.0-dev";
5163
5163
  if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
5164
5164
  hasWarnedVersionMismatch = true;
5165
5165
  process.stderr.write(
@@ -9037,7 +9037,7 @@ var import_node_fs25 = __toESM(require("fs"));
9037
9037
  var import_node_path30 = __toESM(require("path"));
9038
9038
  var import_node_util5 = require("util");
9039
9039
  function installedCliVersion() {
9040
- return true ? "0.0.69" : "0.0.0-dev";
9040
+ return true ? "0.0.71" : "0.0.0-dev";
9041
9041
  }
9042
9042
  function compareCliVersions(left, right) {
9043
9043
  const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -10147,7 +10147,11 @@ function parseHolderPortMap(value) {
10147
10147
  ports.push({ hostIp: normalizeHostIp(entry.HostIp), hostPort: bound, protocol });
10148
10148
  }
10149
10149
  }
10150
- return ports;
10150
+ const unique = /* @__PURE__ */ new Map();
10151
+ for (const port of ports) {
10152
+ unique.set(`${port.hostIp ?? ""}|${port.hostPort}|${port.protocol}`, port);
10153
+ }
10154
+ return [...unique.values()];
10151
10155
  }
10152
10156
  function parseHolderSnapshots(stdout) {
10153
10157
  return stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
package/dist/devrouter.js CHANGED
@@ -4133,7 +4133,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs7.default.read
4133
4133
  const config = parseConfig(parsed ?? {}, configPath);
4134
4134
  const requiredVersion = config.devrouter?.version;
4135
4135
  if (requiredVersion && !hasWarnedVersionMismatch) {
4136
- const cliVersion = true ? "0.0.69" : "0.0.0-dev";
4136
+ const cliVersion = true ? "0.0.71" : "0.0.0-dev";
4137
4137
  if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
4138
4138
  hasWarnedVersionMismatch = true;
4139
4139
  process.stderr.write(
@@ -5386,7 +5386,7 @@ var init_reliability_contract = __esm({
5386
5386
 
5387
5387
  // src/core/reliability-operation-store.ts
5388
5388
  function installedCliVersion() {
5389
- return true ? "0.0.69" : "0.0.0-dev";
5389
+ return true ? "0.0.71" : "0.0.0-dev";
5390
5390
  }
5391
5391
  function compareCliVersions(left, right) {
5392
5392
  const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -7361,16 +7361,20 @@ async function observeControllerBinding(directory, input2) {
7361
7361
  path: input2.path,
7362
7362
  session: input2.session,
7363
7363
  profile: input2.profile,
7364
- require: input2.require ?? []
7364
+ require: input2.require
7365
7365
  });
7366
- if (!isRecord4(response) || !hasExactKeys(response, ["store", "epoch", "generation", "session"]) || !isControllerId(response.session) || !isControllerId(response.store) || !isSafeCounter(response.epoch) || typeof response.generation !== "string" || response.generation.length > 4096) {
7366
+ if (!isRecord4(response) || response.version !== 1 || response.ok !== true || !isRecord4(response.result)) {
7367
+ throw new Error("Malformed controller observation binding.");
7368
+ }
7369
+ const result = response.result;
7370
+ if (!hasExactKeys(result, ["store", "epoch", "generation", "session"]) || !isControllerId(result.session) || !isControllerId(result.store) || !isSafeCounter(result.epoch) || typeof result.generation !== "string" || result.generation.length > 4096) {
7367
7371
  throw new Error("Malformed controller observation binding.");
7368
7372
  }
7369
7373
  return {
7370
- session: response.session,
7371
- store: response.store,
7372
- epoch: response.epoch,
7373
- generation: response.generation
7374
+ session: result.session,
7375
+ store: result.store,
7376
+ epoch: result.epoch,
7377
+ generation: result.generation
7374
7378
  };
7375
7379
  }
7376
7380
  async function controllerRequest(directory, input2, emit, timeoutMs) {
@@ -13062,7 +13066,11 @@ function parseHolderPortMap(value) {
13062
13066
  ports.push({ hostIp: normalizeHostIp(entry.HostIp), hostPort: bound, protocol });
13063
13067
  }
13064
13068
  }
13065
- return ports;
13069
+ const unique = /* @__PURE__ */ new Map();
13070
+ for (const port of ports) {
13071
+ unique.set(`${port.hostIp ?? ""}|${port.hostPort}|${port.protocol}`, port);
13072
+ }
13073
+ return [...unique.values()];
13066
13074
  }
13067
13075
  function parseHolderSnapshots(stdout) {
13068
13076
  return stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
@@ -15173,7 +15181,11 @@ async function superviseThroughController(input2) {
15173
15181
  const bind = () => observeControllerBinding(directory, {
15174
15182
  path: input2.repoPath,
15175
15183
  session: (0, import_node_crypto21.randomUUID)(),
15176
- profile: input2.profile ?? "full"
15184
+ profile: input2.profile ?? "full",
15185
+ // The protocol requires at least one readiness selector, and every
15186
+ // supervised operation depends on runtime readiness; "runtime" is the
15187
+ // one selector every managed binding may declare.
15188
+ require: ["runtime"]
15177
15189
  });
15178
15190
  let binding = await bind();
15179
15191
  let pending = await submitControllerOperation(
@@ -16996,7 +17008,10 @@ async function runController(options) {
16996
17008
  ]);
16997
17009
  if (!socket.destroyed)
16998
17010
  send({ version: 1, id: operationRequest2.id, ok: true, result });
16999
- }).catch(() => {
17011
+ }).catch((error) => {
17012
+ const cause = (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 300);
17013
+ if (cause) process.stderr.write(`controller operation failed: ${cause}
17014
+ `);
17000
17015
  if (!socket.destroyed)
17001
17016
  send({
17002
17017
  version: 1,
@@ -20385,7 +20400,7 @@ async function buildDoctorReport(options = {}) {
20385
20400
  const config = runtimeConfig.config;
20386
20401
  loadedConfig = config;
20387
20402
  loadedWorkspace = runtimeConfig.workspace;
20388
- const cliVersion = true ? "0.0.69" : "0.0.0-dev";
20403
+ const cliVersion = true ? "0.0.71" : "0.0.0-dev";
20389
20404
  const configVersion = config.devrouter?.version;
20390
20405
  if (configVersion && cliVersion !== "0.0.0-dev" && compareSemver(configVersion, cliVersion) > 0) {
20391
20406
  addCheck(checks, {
@@ -25815,7 +25830,7 @@ var init_version = __esm({
25815
25830
 
25816
25831
  // src/cli.ts
25817
25832
  var import_commander = require("commander");
25818
- var CLI_VERSION = true ? "0.0.69" : "0.0.0-dev";
25833
+ var CLI_VERSION = true ? "0.0.71" : "0.0.0-dev";
25819
25834
  var VERSION_FLAGS = /* @__PURE__ */ new Set(["-V", "--version"]);
25820
25835
  function withErrorHandling(action2) {
25821
25836
  return async (...args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrouter/cli",
3
- "version": "0.0.69",
3
+ "version": "0.0.71",
4
4
  "description": "Local dev routing CLI with shared Traefik reverse proxy",
5
5
  "author": "Roland Schlaefli",
6
6
  "homepage": "https://github.com/rschlaefli/devrouter#readme",
@@ -0,0 +1,23 @@
1
+ # Upgrade to devrouter 0.0.70
2
+
3
+ This patch release fixes host-port claim reporting so a holder that binds the
4
+ same port on both address families (0.0.0.0 and ::) is reported as one
5
+ conflict instead of duplicates. No schema, configuration, or CLI flag changes.
6
+
7
+ ## Task
8
+
9
+ Install the published release and update `.devrouter.yml` devrouter.version to
10
+ 0.0.70. No configuration change is required.
11
+
12
+ ## Validation
13
+
14
+ On a repository whose managed overlay declares a fixed published binding that
15
+ a running container holds, run `devrouter doctor --repo <path> --json` and
16
+ confirm `repo.host-port-claims` reports one conflict per distinct binding, not
17
+ one row per address family. `devrouter ensure <path> --json` must return the
18
+ same single `hostPortConflicts` entry.
19
+
20
+ ## Report
21
+
22
+ Report the tested CLI version, the repository and binding exercised, the
23
+ doctor check details, and whether duplicate conflict rows were observed.
@@ -0,0 +1,26 @@
1
+ # Upgrade to devrouter 0.0.71
2
+
3
+ This patch release repairs controller admission for capacity-enrolled
4
+ checkouts. Two client defects shipped in 0.0.69 and 0.0.70: supervised
5
+ operations bound with an empty requirement list that the controller protocol
6
+ rejects, and the observation binding validated the wire envelope instead of
7
+ the observation result. Enrolled `ensure` and `exec` therefore failed before
8
+ reaching the controller. The controller also now reports the bounded cause of
9
+ a failed operation on stderr. No schema, configuration, or CLI flag changes.
10
+
11
+ ## Task
12
+
13
+ Install the published release and update `.devrouter.yml` devrouter.version to
14
+ 0.0.71. No configuration change is required.
15
+
16
+ ## Validation
17
+
18
+ On a repository with an enabled capacity policy enrollment, run
19
+ `devrouter ensure <path> --json` and confirm startup is admitted, then run
20
+ `devrouter exec <path> -- echo ok` and confirm the admitted operation completes.
21
+ `devrouter stop <path>` must end with the runtime stopped and zero routes.
22
+
23
+ ## Report
24
+
25
+ Report the installed CLI version, the enrolled repository, the ensure and exec
26
+ outcomes, and the final stopped status with the route count.