@devrouter/cli 0.0.56 → 0.0.57

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.
@@ -2007,6 +2007,9 @@ var RELIABILITY_MAX_ITEMS = 128;
2007
2007
  function isReliabilityId(value) {
2008
2008
  return typeof value === "string" && /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(value);
2009
2009
  }
2010
+ function isReliabilityProfile(value) {
2011
+ return typeof value === "string" && value.length <= 4096 && value.split(",").every((name) => isReliabilityId(name.trim()));
2012
+ }
2010
2013
  function isReliabilityCounter(value) {
2011
2014
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
2012
2015
  }
@@ -2037,7 +2040,7 @@ function validOperation(value) {
2037
2040
  function assertReliabilityState(value) {
2038
2041
  const intentRevision = record(value) ? value.intentRevision : void 0;
2039
2042
  const valid = record(value) && value.contractVersion === RELIABILITY_CONTRACT_VERSION && oneOf(value.executionPolicy, ["manual", "capacity-managed"]) && (value.executionPolicy === "manual" ? value.admission === "not-applicable" && value.chargeHeld === false : value.admission !== "not-applicable") && boundedArray(value.operationHistory) && uniqueIds(value.operationHistory, "key") && uniqueIds(value.operationHistory, "id") && value.operationHistory.every(
2040
- (entry) => record(entry) && isReliabilityId(entry.profile) && record(entry.consumer) && isReliabilityId(entry.consumer.id) && typeof entry.consumer.pinned === "boolean" && boundedArray(entry.consumer.requiredCapabilities) && entry.consumer.requiredCapabilities.every(isReliabilityId) && new Set(entry.consumer.requiredCapabilities).size === entry.consumer.requiredCapabilities.length && validOperation(entry)
2043
+ (entry) => record(entry) && isReliabilityProfile(entry.profile) && record(entry.consumer) && isReliabilityId(entry.consumer.id) && typeof entry.consumer.pinned === "boolean" && boundedArray(entry.consumer.requiredCapabilities) && entry.consumer.requiredCapabilities.every(isReliabilityId) && new Set(entry.consumer.requiredCapabilities).size === entry.consumer.requiredCapabilities.length && validOperation(entry)
2041
2044
  ) && isReliabilityCounter(value.observationsAfterMs) && isReliabilityId(value.environmentId) && isReliabilityCounter(value.intentRevision) && isReliabilityCounter(value.runtimeGeneration) && isReliabilityCounter(value.controllerEpoch) && oneOf(value.desired, ["running", "parked-for-capacity", "stopped-by-user"]) && oneOf(value.phase, [
2042
2045
  "idle",
2043
2046
  "queued",
@@ -2046,7 +2049,7 @@ function assertReliabilityState(value) {
2046
2049
  "stable",
2047
2050
  "recovering",
2048
2051
  "stopping"
2049
- ]) && (value.profile === null || isReliabilityId(value.profile)) && oneOf(value.admission, [
2052
+ ]) && (value.profile === null || isReliabilityProfile(value.profile)) && oneOf(value.admission, [
2050
2053
  "admitted",
2051
2054
  "waiting",
2052
2055
  "unknown",
@@ -2055,7 +2058,7 @@ function assertReliabilityState(value) {
2055
2058
  ]) && typeof value.chargeHeld === "boolean" && record(value.stopProof) && typeof value.stopProof.workloadsStopped === "boolean" && typeof value.stopProof.routesRemoved === "boolean" && boundedArray(value.consumers) && uniqueIds(value.consumers, "id") && value.consumers.every(
2056
2059
  (consumer) => record(consumer) && typeof consumer.pinned === "boolean" && boundedArray(consumer.requiredCapabilities) && consumer.requiredCapabilities.every(isReliabilityId) && new Set(consumer.requiredCapabilities).size === consumer.requiredCapabilities.length
2057
2060
  ) && boundedArray(value.requests) && uniqueIds(value.requests, "key") && value.requests.every(
2058
- (request) => record(request) && oneOf(request.mode, ["start", "attach"]) && isReliabilityId(request.consumerId) && isReliabilityId(request.operationId) && isReliabilityId(request.profile) && isReliabilityCounter(request.intentRevision) && isReliabilityCounter(intentRevision) && request.intentRevision <= intentRevision
2061
+ (request) => record(request) && oneOf(request.mode, ["start", "attach"]) && isReliabilityId(request.consumerId) && isReliabilityId(request.operationId) && isReliabilityProfile(request.profile) && isReliabilityCounter(request.intentRevision) && isReliabilityCounter(intentRevision) && request.intentRevision <= intentRevision
2059
2062
  ) && boundedArray(value.observations) && uniqueIds(value.observations, "capability") && value.observations.every(
2060
2063
  (observation) => record(observation) && oneOf(observation.infrastructure, ["healthy", "failed", "unknown"]) && oneOf(observation.application, ["verified", "unready", "unverified"]) && isReliabilityCounter(observation.observedAtMs) && isReliabilityCounter(observation.validForMs)
2061
2064
  ) && (value.operation === null || validOperation(value.operation)) && (value.executionPolicy !== "manual" || value.desired !== "parked-for-capacity" && value.incident === null) && (value.incident === null || record(value.incident) && isReliabilityId(value.incident.id) && isReliabilityCounter(value.incident.correctiveActionsTaken) && isReliabilityCounter(value.incident.actionLimit) && value.incident.actionLimit > 0 && value.incident.correctiveActionsTaken <= value.incident.actionLimit);
@@ -2124,10 +2127,10 @@ function assertReliabilityEvent(value) {
2124
2127
  let valid = false;
2125
2128
  switch (value.type) {
2126
2129
  case "request":
2127
- valid = oneOf2(value.mode, ["start", "attach"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityId(value.profile) && isConsumer(value.consumer);
2130
+ valid = oneOf2(value.mode, ["start", "attach"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityProfile(value.profile) && isConsumer(value.consumer);
2128
2131
  break;
2129
2132
  case "operation-request":
2130
- valid = oneOf2(value.kind, ["ensure", "exec"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityId(value.profile) && isConsumer(value.consumer) && typeof value.runtimeRunning === "boolean";
2133
+ valid = oneOf2(value.kind, ["ensure", "exec"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityProfile(value.profile) && isConsumer(value.consumer) && typeof value.runtimeRunning === "boolean";
2131
2134
  break;
2132
2135
  case "drained":
2133
2136
  valid = isReliabilityId(value.operationId);
@@ -4460,7 +4463,7 @@ function loadRepoConfig(repoPath) {
4460
4463
  const config = parseConfig(parsed ?? {}, configPath);
4461
4464
  const requiredVersion = config.devrouter?.version;
4462
4465
  if (requiredVersion && !hasWarnedVersionMismatch) {
4463
- const cliVersion = true ? "0.0.56" : "0.0.0-dev";
4466
+ const cliVersion = true ? "0.0.57" : "0.0.0-dev";
4464
4467
  if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
4465
4468
  hasWarnedVersionMismatch = true;
4466
4469
  process.stderr.write(
package/dist/devrouter.js CHANGED
@@ -2781,7 +2781,7 @@ function loadRepoConfig(repoPath) {
2781
2781
  const config = parseConfig(parsed ?? {}, configPath);
2782
2782
  const requiredVersion = config.devrouter?.version;
2783
2783
  if (requiredVersion && !hasWarnedVersionMismatch) {
2784
- const cliVersion = true ? "0.0.56" : "0.0.0-dev";
2784
+ const cliVersion = true ? "0.0.57" : "0.0.0-dev";
2785
2785
  if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
2786
2786
  hasWarnedVersionMismatch = true;
2787
2787
  process.stderr.write(
@@ -9166,7 +9166,7 @@ async function buildDoctorReport(options = {}) {
9166
9166
  const config = runtimeConfig.config;
9167
9167
  loadedConfig = config;
9168
9168
  loadedWorkspace = runtimeConfig.workspace;
9169
- const cliVersion = true ? "0.0.56" : "0.0.0-dev";
9169
+ const cliVersion = true ? "0.0.57" : "0.0.0-dev";
9170
9170
  const configVersion = config.devrouter?.version;
9171
9171
  if (configVersion && cliVersion !== "0.0.0-dev" && compareSemver(configVersion, cliVersion) > 0) {
9172
9172
  addCheck(checks, {
@@ -9803,6 +9803,9 @@ var init_up = __esm({
9803
9803
  function isReliabilityId(value) {
9804
9804
  return typeof value === "string" && /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(value);
9805
9805
  }
9806
+ function isReliabilityProfile(value) {
9807
+ return typeof value === "string" && value.length <= 4096 && value.split(",").every((name) => isReliabilityId(name.trim()));
9808
+ }
9806
9809
  function isReliabilityCounter(value) {
9807
9810
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
9808
9811
  }
@@ -9833,7 +9836,7 @@ function validOperation(value) {
9833
9836
  function assertReliabilityState(value) {
9834
9837
  const intentRevision = record(value) ? value.intentRevision : void 0;
9835
9838
  const valid = record(value) && value.contractVersion === RELIABILITY_CONTRACT_VERSION && oneOf(value.executionPolicy, ["manual", "capacity-managed"]) && (value.executionPolicy === "manual" ? value.admission === "not-applicable" && value.chargeHeld === false : value.admission !== "not-applicable") && boundedArray(value.operationHistory) && uniqueIds(value.operationHistory, "key") && uniqueIds(value.operationHistory, "id") && value.operationHistory.every(
9836
- (entry) => record(entry) && isReliabilityId(entry.profile) && record(entry.consumer) && isReliabilityId(entry.consumer.id) && typeof entry.consumer.pinned === "boolean" && boundedArray(entry.consumer.requiredCapabilities) && entry.consumer.requiredCapabilities.every(isReliabilityId) && new Set(entry.consumer.requiredCapabilities).size === entry.consumer.requiredCapabilities.length && validOperation(entry)
9839
+ (entry) => record(entry) && isReliabilityProfile(entry.profile) && record(entry.consumer) && isReliabilityId(entry.consumer.id) && typeof entry.consumer.pinned === "boolean" && boundedArray(entry.consumer.requiredCapabilities) && entry.consumer.requiredCapabilities.every(isReliabilityId) && new Set(entry.consumer.requiredCapabilities).size === entry.consumer.requiredCapabilities.length && validOperation(entry)
9837
9840
  ) && isReliabilityCounter(value.observationsAfterMs) && isReliabilityId(value.environmentId) && isReliabilityCounter(value.intentRevision) && isReliabilityCounter(value.runtimeGeneration) && isReliabilityCounter(value.controllerEpoch) && oneOf(value.desired, ["running", "parked-for-capacity", "stopped-by-user"]) && oneOf(value.phase, [
9838
9841
  "idle",
9839
9842
  "queued",
@@ -9842,7 +9845,7 @@ function assertReliabilityState(value) {
9842
9845
  "stable",
9843
9846
  "recovering",
9844
9847
  "stopping"
9845
- ]) && (value.profile === null || isReliabilityId(value.profile)) && oneOf(value.admission, [
9848
+ ]) && (value.profile === null || isReliabilityProfile(value.profile)) && oneOf(value.admission, [
9846
9849
  "admitted",
9847
9850
  "waiting",
9848
9851
  "unknown",
@@ -9851,7 +9854,7 @@ function assertReliabilityState(value) {
9851
9854
  ]) && typeof value.chargeHeld === "boolean" && record(value.stopProof) && typeof value.stopProof.workloadsStopped === "boolean" && typeof value.stopProof.routesRemoved === "boolean" && boundedArray(value.consumers) && uniqueIds(value.consumers, "id") && value.consumers.every(
9852
9855
  (consumer) => record(consumer) && typeof consumer.pinned === "boolean" && boundedArray(consumer.requiredCapabilities) && consumer.requiredCapabilities.every(isReliabilityId) && new Set(consumer.requiredCapabilities).size === consumer.requiredCapabilities.length
9853
9856
  ) && boundedArray(value.requests) && uniqueIds(value.requests, "key") && value.requests.every(
9854
- (request) => record(request) && oneOf(request.mode, ["start", "attach"]) && isReliabilityId(request.consumerId) && isReliabilityId(request.operationId) && isReliabilityId(request.profile) && isReliabilityCounter(request.intentRevision) && isReliabilityCounter(intentRevision) && request.intentRevision <= intentRevision
9857
+ (request) => record(request) && oneOf(request.mode, ["start", "attach"]) && isReliabilityId(request.consumerId) && isReliabilityId(request.operationId) && isReliabilityProfile(request.profile) && isReliabilityCounter(request.intentRevision) && isReliabilityCounter(intentRevision) && request.intentRevision <= intentRevision
9855
9858
  ) && boundedArray(value.observations) && uniqueIds(value.observations, "capability") && value.observations.every(
9856
9859
  (observation) => record(observation) && oneOf(observation.infrastructure, ["healthy", "failed", "unknown"]) && oneOf(observation.application, ["verified", "unready", "unverified"]) && isReliabilityCounter(observation.observedAtMs) && isReliabilityCounter(observation.validForMs)
9857
9860
  ) && (value.operation === null || validOperation(value.operation)) && (value.executionPolicy !== "manual" || value.desired !== "parked-for-capacity" && value.incident === null) && (value.incident === null || record(value.incident) && isReliabilityId(value.incident.id) && isReliabilityCounter(value.incident.correctiveActionsTaken) && isReliabilityCounter(value.incident.actionLimit) && value.incident.actionLimit > 0 && value.incident.correctiveActionsTaken <= value.incident.actionLimit);
@@ -9925,10 +9928,10 @@ function assertReliabilityEvent(value) {
9925
9928
  let valid = false;
9926
9929
  switch (value.type) {
9927
9930
  case "request":
9928
- valid = oneOf2(value.mode, ["start", "attach"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityId(value.profile) && isConsumer(value.consumer);
9931
+ valid = oneOf2(value.mode, ["start", "attach"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityProfile(value.profile) && isConsumer(value.consumer);
9929
9932
  break;
9930
9933
  case "operation-request":
9931
- valid = oneOf2(value.kind, ["ensure", "exec"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityId(value.profile) && isConsumer(value.consumer) && typeof value.runtimeRunning === "boolean";
9934
+ valid = oneOf2(value.kind, ["ensure", "exec"]) && isReliabilityId(value.key) && isReliabilityId(value.operationId) && isReliabilityProfile(value.profile) && isConsumer(value.consumer) && typeof value.runtimeRunning === "boolean";
9932
9935
  break;
9933
9936
  case "drained":
9934
9937
  valid = isReliabilityId(value.operationId);
@@ -16077,7 +16080,7 @@ var init_version = __esm({
16077
16080
 
16078
16081
  // src/cli.ts
16079
16082
  var import_commander = require("commander");
16080
- var CLI_VERSION = true ? "0.0.56" : "0.0.0-dev";
16083
+ var CLI_VERSION = true ? "0.0.57" : "0.0.0-dev";
16081
16084
  var VERSION_FLAGS = /* @__PURE__ */ new Set(["-V", "--version"]);
16082
16085
  function withErrorHandling(action2) {
16083
16086
  return async (...args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrouter/cli",
3
- "version": "0.0.56",
3
+ "version": "0.0.57",
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,33 @@
1
+ # Upgrade to devrouter 0.0.57
2
+
3
+ This patch restores managed ensure with comma-separated profiles. Lifecycle events,
4
+ current state and retained request history accept profile selections separately
5
+ from workspace and operation identifiers. Repository resolution still validates
6
+ configured profiles and combines their selected resources.
7
+
8
+ ## Task
9
+
10
+ Install the published 0.0.57 patch and update `.devrouter.yml` devrouter.version to
11
+ 0.0.57 through the consumer repository workflow. No schema or database migration
12
+ is required. Keep the intended profile selection; do not substitute full or delete
13
+ runtime state to avoid the earlier validator failure.
14
+
15
+ ## Validation
16
+
17
+ Use repository profile resolution to check the intended combined selection. Run
18
+ managed ensure only on an authorized exact checkout, retaining its data and
19
+ bindings. Report the resulting application and runtime outcomes separately from
20
+ successful selection validation. Stop only runtimes owned by the validation task,
21
+ then verify their provider status and zero exact routes.
22
+
23
+ ## Limits
24
+
25
+ This patch fixes pre-dispatch profile validation. It does not introduce a host-side
26
+ preparation hook, warm Compose drift reconciliation, capacity admission, a
27
+ controller, autonomous agent recovery or complete OOM protection.
28
+
29
+ ## Report
30
+
31
+ Report installed/configured versions, exact profile selection, validation result
32
+ and any separately authorized runtime evidence. Identify retained runtime leases
33
+ without ending another task's runtime.