@devrouter/cli 0.5.0 → 0.5.2

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.
@@ -871,8 +871,18 @@ function inspectManagedStopContainers(composeProject, endpoint) {
871
871
  requireSameContainerPopulation(listedIds, confirmedIds);
872
872
  return snapshots;
873
873
  }
874
+ function onlyVanished(stderr, ids2) {
875
+ const lines = (stderr ?? "").split(/\r?\n/).filter((line) => line.trim().length > 0);
876
+ return lines.length > 0 && lines.every((line) => {
877
+ const missing = /^(?:error(?: response from daemon)?:\s*)?no such (?:object|container):\s*(\S+)\s*$/i.exec(
878
+ line.trim()
879
+ )?.[1];
880
+ return missing !== void 0 && ids2.includes(missing);
881
+ });
882
+ }
874
883
  function inspectWorkspaceContainers(options) {
875
884
  let ids2 = options?.ids;
885
+ const listedAll = !ids2;
876
886
  if (!ids2) {
877
887
  const listed = (0, import_node_child_process3.spawnSync)(
878
888
  "docker",
@@ -899,7 +909,7 @@ function inspectWorkspaceContainers(options) {
899
909
  ["inspect", ...options?.withSize ? ["--size"] : [], "--format", template, ...ids2],
900
910
  { encoding: "utf-8", ...networkDockerOptions() }
901
911
  );
902
- if (inspected.status !== 0) {
912
+ if (inspected.status !== 0 && !(listedAll && onlyVanished(inspected.stderr, ids2))) {
903
913
  throw new Error(
904
914
  `docker inspect failed: ${(inspected.stderr || inspected.stdout || "unknown error").trim()}`
905
915
  );
@@ -5373,7 +5383,7 @@ function retain(session, previous) {
5373
5383
 
5374
5384
  // src/core/reliability-operation-store.ts
5375
5385
  function installedCliVersion() {
5376
- return true ? "0.5.0" : "0.0.0-dev";
5386
+ return true ? "0.5.2" : "0.0.0-dev";
5377
5387
  }
5378
5388
  function compareCliVersions(left, right) {
5379
5389
  const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -7383,7 +7393,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs19.default.rea
7383
7393
  const config = parseConfig(parsed ?? {}, configPath);
7384
7394
  const requiredVersion = config.devrouter?.version;
7385
7395
  if (requiredVersion && !hasWarnedVersionMismatch) {
7386
- const cliVersion = true ? "0.5.0" : "0.0.0-dev";
7396
+ const cliVersion = true ? "0.5.2" : "0.0.0-dev";
7387
7397
  if (cliVersion !== "0.0.0-dev" && compareSemver2(requiredVersion, cliVersion) > 0) {
7388
7398
  hasWarnedVersionMismatch = true;
7389
7399
  process.stderr.write(
package/dist/devrouter.js CHANGED
@@ -1002,8 +1002,18 @@ function inspectManagedStopContainers(composeProject, endpoint) {
1002
1002
  requireSameContainerPopulation(listedIds, confirmedIds);
1003
1003
  return snapshots;
1004
1004
  }
1005
+ function onlyVanished(stderr, ids2) {
1006
+ const lines = (stderr ?? "").split(/\r?\n/).filter((line) => line.trim().length > 0);
1007
+ return lines.length > 0 && lines.every((line) => {
1008
+ const missing = /^(?:error(?: response from daemon)?:\s*)?no such (?:object|container):\s*(\S+)\s*$/i.exec(
1009
+ line.trim()
1010
+ )?.[1];
1011
+ return missing !== void 0 && ids2.includes(missing);
1012
+ });
1013
+ }
1005
1014
  function inspectWorkspaceContainers(options) {
1006
1015
  let ids2 = options?.ids;
1016
+ const listedAll = !ids2;
1007
1017
  if (!ids2) {
1008
1018
  const listed = (0, import_node_child_process4.spawnSync)(
1009
1019
  "docker",
@@ -1030,7 +1040,7 @@ function inspectWorkspaceContainers(options) {
1030
1040
  ["inspect", ...options?.withSize ? ["--size"] : [], "--format", template, ...ids2],
1031
1041
  { encoding: "utf-8", ...networkDockerOptions() }
1032
1042
  );
1033
- if (inspected.status !== 0) {
1043
+ if (inspected.status !== 0 && !(listedAll && onlyVanished(inspected.stderr, ids2))) {
1034
1044
  throw new Error(
1035
1045
  `docker inspect failed: ${(inspected.stderr || inspected.stdout || "unknown error").trim()}`
1036
1046
  );
@@ -4764,7 +4774,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs8.default.read
4764
4774
  const config = parseConfig(parsed ?? {}, configPath);
4765
4775
  const requiredVersion = config.devrouter?.version;
4766
4776
  if (requiredVersion && !hasWarnedVersionMismatch) {
4767
- const cliVersion = true ? "0.5.0" : "0.0.0-dev";
4777
+ const cliVersion = true ? "0.5.2" : "0.0.0-dev";
4768
4778
  if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
4769
4779
  hasWarnedVersionMismatch = true;
4770
4780
  process.stderr.write(
@@ -6763,7 +6773,7 @@ var init_reliability_contract = __esm({
6763
6773
 
6764
6774
  // src/core/reliability-operation-store.ts
6765
6775
  function installedCliVersion() {
6766
- return true ? "0.5.0" : "0.0.0-dev";
6776
+ return true ? "0.5.2" : "0.0.0-dev";
6767
6777
  }
6768
6778
  function compareCliVersions(left, right) {
6769
6779
  const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -15520,6 +15530,12 @@ var init_reliability_model = __esm({
15520
15530
  function isLifecycleProgressPhase(value) {
15521
15531
  return typeof value === "string" && Object.hasOwn(ROLES, value);
15522
15532
  }
15533
+ function muteLifecycleProgressHeartbeat() {
15534
+ heartbeatMuted = true;
15535
+ }
15536
+ function lifecycleProgressHeartbeatMuted() {
15537
+ return heartbeatMuted;
15538
+ }
15523
15539
  function lifecycleProgressSnapshot(phase, receivedAt, now) {
15524
15540
  const elapsedMs = receivedAt === void 0 ? null : Math.max(0, Math.floor(now - receivedAt));
15525
15541
  return {
@@ -15531,7 +15547,7 @@ function lifecycleProgressSnapshot(phase, receivedAt, now) {
15531
15547
  liveness: "unknown"
15532
15548
  };
15533
15549
  }
15534
- var ROLES;
15550
+ var ROLES, heartbeatMuted;
15535
15551
  var init_lifecycle_progress = __esm({
15536
15552
  "src/core/lifecycle-progress.ts"() {
15537
15553
  "use strict";
@@ -15549,6 +15565,7 @@ var init_lifecycle_progress = __esm({
15549
15565
  rollback: "lifecycle-worker",
15550
15566
  stop: "lifecycle-stop"
15551
15567
  };
15568
+ heartbeatMuted = false;
15552
15569
  }
15553
15570
  });
15554
15571
 
@@ -15610,7 +15627,7 @@ async function runLifecycleWorker(request2, supervision, beforeAdmission) {
15610
15627
  let progressReceivedAt;
15611
15628
  let progressTimer;
15612
15629
  const emitProgress = () => {
15613
- if (closed || cancelled || request2.kind === "exec") return;
15630
+ if (closed || cancelled || request2.kind === "exec" || lifecycleProgressHeartbeatMuted()) return;
15614
15631
  const data = `${JSON.stringify(lifecycleProgressSnapshot(progressPhase, progressReceivedAt, performance.now()))}
15615
15632
  `;
15616
15633
  try {
@@ -24469,7 +24486,7 @@ function probeInstalledCliVersion(executable) {
24469
24486
  }
24470
24487
  function buildCliPathCheck(options = {}) {
24471
24488
  const id5 = "global.cli-path";
24472
- const runningVersion = options.runningVersion ?? (true ? "0.5.0" : "0.0.0-dev");
24489
+ const runningVersion = options.runningVersion ?? (true ? "0.5.2" : "0.0.0-dev");
24473
24490
  if (runningVersion === "0.0.0-dev") {
24474
24491
  return {
24475
24492
  id: id5,
@@ -25365,7 +25382,7 @@ async function buildDoctorReport(options = {}) {
25365
25382
  suggestion: `Remedy ${expansionNotice.remedy.code}: set a named default profile other than '${expansionNotice.profile}'${remedyCandidates}.`
25366
25383
  });
25367
25384
  }
25368
- const cliVersion = true ? "0.5.0" : "0.0.0-dev";
25385
+ const cliVersion = true ? "0.5.2" : "0.0.0-dev";
25369
25386
  const configVersion = config.devrouter?.version;
25370
25387
  const installedKnown = cliVersion !== "0.0.0-dev";
25371
25388
  const versionComparison = installedKnown && configVersion ? compareSemver(configVersion, cliVersion) : void 0;
@@ -33765,6 +33782,7 @@ async function runWorkspaceIdleCommand(options) {
33765
33782
  let stops = [];
33766
33783
  if (options.stop) {
33767
33784
  const paths = idleSweepPaths();
33785
+ if (!process.stderr.isTTY) muteLifecycleProgressHeartbeat();
33768
33786
  import_node_fs61.default.mkdirSync(paths.directory, { recursive: true, mode: 448 });
33769
33787
  const result = await withFileLock(paths.lock, { activity: "idle sweep" }, async () => {
33770
33788
  try {
@@ -33973,6 +33991,7 @@ var init_workspace2 = __esm({
33973
33991
  init_docker_leftovers();
33974
33992
  init_file_lock();
33975
33993
  init_idle_sweep();
33994
+ init_lifecycle_progress();
33976
33995
  init_output();
33977
33996
  init_reliability_lifecycle();
33978
33997
  init_repo_config();
@@ -34026,7 +34045,7 @@ var init_version = __esm({
34026
34045
 
34027
34046
  // src/cli.ts
34028
34047
  var import_commander = require("commander");
34029
- var CLI_VERSION = true ? "0.5.0" : "0.0.0-dev";
34048
+ var CLI_VERSION = true ? "0.5.2" : "0.0.0-dev";
34030
34049
  var VERSION_FLAGS = /* @__PURE__ */ new Set(["-V", "--version"]);
34031
34050
  function withErrorHandling(action2) {
34032
34051
  return async (...args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrouter/cli",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
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,27 @@
1
+ # Upgrade to devrouter 0.5.1
2
+
3
+ This patch release fixes lifecycle commands that failed with
4
+ `docker inspect failed: error: no such object: <id>` when any container on the
5
+ machine was removed while devrouter was listing containers, for example while
6
+ another checkout's stack was being recreated. `ensure`, `exec`, `stop`,
7
+ `status` and `workspace idle` now treat such a vanished container as absent.
8
+ Other inspect errors still fail. There is no configuration change and no
9
+ migration.
10
+
11
+ ## Task
12
+
13
+ Install the published 0.5.1 CLI. No repository change is needed. Bump a
14
+ repository's `devrouter.version` to 0.5.1 only when consumer source changes are
15
+ authorized. A machine that uses the idle-stop agent needs no setup rerun when
16
+ devrouter is installed through Volta, because the agent's entry path does not
17
+ change between versions.
18
+
19
+ ## Validation
20
+
21
+ 1. Run `devrouter -V` from the consumer checkout.
22
+ 2. Run `devrouter workspace idle --json` and confirm it completes.
23
+
24
+ ## Report
25
+
26
+ Report the release revision and the resolved executable with its installed
27
+ version.
@@ -0,0 +1,25 @@
1
+ # Upgrade to devrouter 0.5.2
2
+
3
+ This patch release keeps the idle-stop agent's `sweep.log` readable.
4
+ `workspace idle --stop` no longer writes a lifecycle progress line every ten
5
+ seconds of each stop when its stderr is not a terminal, as under launchd, so
6
+ the log records only stop outcomes and errors. An interactive sweep still shows
7
+ progress. There is no configuration change and no migration.
8
+
9
+ ## Task
10
+
11
+ Install the published 0.5.2 CLI. No repository change is needed. Bump a
12
+ repository's `devrouter.version` to 0.5.2 only when consumer source changes are
13
+ authorized. A machine that uses the idle-stop agent needs no setup rerun when
14
+ devrouter is installed through Volta, because the agent's entry path does not
15
+ change between versions.
16
+
17
+ ## Validation
18
+
19
+ 1. Run `devrouter -V` from the consumer checkout.
20
+ 2. Run `devrouter workspace idle --json` and confirm it completes.
21
+
22
+ ## Report
23
+
24
+ Report the release revision and the resolved executable with its installed
25
+ version.