@devrouter/cli 0.0.70 → 0.0.72

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.70" : "0.0.0-dev";
5162
+ const cliVersion = true ? "0.0.72" : "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(
@@ -8596,8 +8596,6 @@ function handleOperationRequest(state, event) {
8596
8596
  );
8597
8597
  if (state.operationHistory.some((entry) => entry.id === event.operationId))
8598
8598
  return unchanged(state, "conflict");
8599
- if (state.executionPolicy !== "manual" && state.operationHistory.length >= RELIABILITY_MAX_ITEMS)
8600
- return unchanged(state, "blocked");
8601
8599
  if (event.kind === "exec" && canExecAfterInterruptedEnsure(state) && event.recoverInterruptedEnsure !== true)
8602
8600
  return blocked(
8603
8601
  state,
@@ -8620,7 +8618,7 @@ function handleOperationRequest(state, event) {
8620
8618
  state,
8621
8619
  `exec requires a running workspace (runtimeRunning=${event.runtimeRunning}, desired='${state.desired}').`
8622
8620
  );
8623
- const rollover = state.executionPolicy === "manual" && state.operationHistory.length >= RELIABILITY_MAX_ITEMS;
8621
+ const rollover = state.operationHistory.length >= RELIABILITY_MAX_ITEMS;
8624
8622
  let retired = -1;
8625
8623
  if (rollover) {
8626
8624
  const latestEnsureId = [...state.operationHistory].reverse().find((entry) => entry.kind === "ensure")?.id;
@@ -9037,7 +9035,7 @@ var import_node_fs25 = __toESM(require("fs"));
9037
9035
  var import_node_path30 = __toESM(require("path"));
9038
9036
  var import_node_util5 = require("util");
9039
9037
  function installedCliVersion() {
9040
- return true ? "0.0.70" : "0.0.0-dev";
9038
+ return true ? "0.0.72" : "0.0.0-dev";
9041
9039
  }
9042
9040
  function compareCliVersions(left, right) {
9043
9041
  const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
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.70" : "0.0.0-dev";
4136
+ const cliVersion = true ? "0.0.72" : "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.70" : "0.0.0-dev";
5389
+ return true ? "0.0.72" : "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) {
@@ -11829,8 +11833,6 @@ function handleOperationRequest(state, event) {
11829
11833
  );
11830
11834
  if (state.operationHistory.some((entry) => entry.id === event.operationId))
11831
11835
  return unchanged(state, "conflict");
11832
- if (state.executionPolicy !== "manual" && state.operationHistory.length >= RELIABILITY_MAX_ITEMS)
11833
- return unchanged(state, "blocked");
11834
11836
  if (event.kind === "exec" && canExecAfterInterruptedEnsure(state) && event.recoverInterruptedEnsure !== true)
11835
11837
  return blocked(
11836
11838
  state,
@@ -11853,7 +11855,7 @@ function handleOperationRequest(state, event) {
11853
11855
  state,
11854
11856
  `exec requires a running workspace (runtimeRunning=${event.runtimeRunning}, desired='${state.desired}').`
11855
11857
  );
11856
- const rollover = state.executionPolicy === "manual" && state.operationHistory.length >= RELIABILITY_MAX_ITEMS;
11858
+ const rollover = state.operationHistory.length >= RELIABILITY_MAX_ITEMS;
11857
11859
  let retired = -1;
11858
11860
  if (rollover) {
11859
11861
  const latestEnsureId = [...state.operationHistory].reverse().find((entry) => entry.kind === "ensure")?.id;
@@ -15177,7 +15179,11 @@ async function superviseThroughController(input2) {
15177
15179
  const bind = () => observeControllerBinding(directory, {
15178
15180
  path: input2.repoPath,
15179
15181
  session: (0, import_node_crypto21.randomUUID)(),
15180
- profile: input2.profile ?? "full"
15182
+ profile: input2.profile ?? "full",
15183
+ // The protocol requires at least one readiness selector, and every
15184
+ // supervised operation depends on runtime readiness; "runtime" is the
15185
+ // one selector every managed binding may declare.
15186
+ require: ["runtime"]
15181
15187
  });
15182
15188
  let binding = await bind();
15183
15189
  let pending = await submitControllerOperation(
@@ -17000,7 +17006,10 @@ async function runController(options) {
17000
17006
  ]);
17001
17007
  if (!socket.destroyed)
17002
17008
  send({ version: 1, id: operationRequest2.id, ok: true, result });
17003
- }).catch(() => {
17009
+ }).catch((error) => {
17010
+ const cause = (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 300);
17011
+ if (cause) process.stderr.write(`controller operation failed: ${cause}
17012
+ `);
17004
17013
  if (!socket.destroyed)
17005
17014
  send({
17006
17015
  version: 1,
@@ -20389,7 +20398,7 @@ async function buildDoctorReport(options = {}) {
20389
20398
  const config = runtimeConfig.config;
20390
20399
  loadedConfig = config;
20391
20400
  loadedWorkspace = runtimeConfig.workspace;
20392
- const cliVersion = true ? "0.0.70" : "0.0.0-dev";
20401
+ const cliVersion = true ? "0.0.72" : "0.0.0-dev";
20393
20402
  const configVersion = config.devrouter?.version;
20394
20403
  if (configVersion && cliVersion !== "0.0.0-dev" && compareSemver(configVersion, cliVersion) > 0) {
20395
20404
  addCheck(checks, {
@@ -25819,7 +25828,7 @@ var init_version = __esm({
25819
25828
 
25820
25829
  // src/cli.ts
25821
25830
  var import_commander = require("commander");
25822
- var CLI_VERSION = true ? "0.0.70" : "0.0.0-dev";
25831
+ var CLI_VERSION = true ? "0.0.72" : "0.0.0-dev";
25823
25832
  var VERSION_FLAGS = /* @__PURE__ */ new Set(["-V", "--version"]);
25824
25833
  function withErrorHandling(action2) {
25825
25834
  return async (...args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrouter/cli",
3
- "version": "0.0.70",
3
+ "version": "0.0.72",
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,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.
@@ -0,0 +1,27 @@
1
+ # Upgrade to devrouter 0.0.72
2
+
3
+ This patch release lets capacity-enrolled checkouts keep working past the
4
+ 128-entry lifecycle journal cap. Previously the journal refused every later
5
+ `ensure` and `exec` once it filled, because history rollover ran only under
6
+ manual execution policy. Enrolled repositories now roll over under the same
7
+ conservative guards as manual ones. No schema, configuration, or CLI flag
8
+ changes.
9
+
10
+ ## Task
11
+
12
+ Install the published release and update `.devrouter.yml` devrouter.version to
13
+ 0.0.72. No configuration change is required.
14
+
15
+ ## Validation
16
+
17
+ On a repository with an enabled capacity policy enrollment whose journal is at
18
+ or near its cap, run `devrouter ensure <path> --json` and confirm the operation
19
+ is admitted and dispatched instead of failing with a blocked lifecycle
20
+ transition. `devrouter exec <path> -- echo ok` must complete, and
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 journal entry
26
+ count before and after the operation, and the final stopped status with the
27
+ route count.