@devrouter/cli 0.0.77 → 0.0.78

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.
@@ -350,9 +350,25 @@ function acquireFileLock(lockPath, options) {
350
350
  }
351
351
  if (options.onWait && now - lastProgressAt >= progressIntervalMs) {
352
352
  lastProgressAt = now;
353
+ let holder;
354
+ try {
355
+ const bytes2 = import_node_fs2.default.readFileSync(lockPath, "utf-8");
356
+ const record6 = parseLockRecord(bytes2);
357
+ if (record6.owner && isLockOwnerLive(record6.owner, livenessCache) && import_node_fs2.default.readFileSync(lockPath, "utf-8") === bytes2) {
358
+ holder = {
359
+ kind: "live",
360
+ pid: record6.owner.pid,
361
+ acquiredAtMs: record6.acquiredAtMs
362
+ };
363
+ }
364
+ } catch {
365
+ }
353
366
  options.onWait({
354
367
  waitingMs: now - waitStartedAt,
355
- holderPid: queueState.leaderPid,
368
+ remainingWaitMs: Math.max(0, deadline - now),
369
+ queueLeaderPid: queueState.leaderPid,
370
+ holderPid: holder?.pid,
371
+ holderHeldMs: holder?.acquiredAtMs !== void 0 ? Math.max(0, now - holder.acquiredAtMs) : void 0,
356
372
  queuePosition: queueState.position,
357
373
  waitingOn: "queue"
358
374
  });
@@ -390,6 +406,7 @@ function acquireFileLock(lockPath, options) {
390
406
  lastProgressAt = now;
391
407
  options.onWait({
392
408
  waitingMs: now - waitStartedAt,
409
+ remainingWaitMs: Math.max(0, deadline - now),
393
410
  holderPid: state.pid,
394
411
  holderHeldMs: state.acquiredAtMs !== void 0 ? Math.max(0, now - state.acquiredAtMs) : void 0,
395
412
  queuePosition: queueState?.position,
@@ -444,9 +461,11 @@ async function withFileLock(lockPath, options, operation) {
444
461
  function createStderrWaitReporter(activity, target) {
445
462
  return (progress) => {
446
463
  const heldSeconds = progress.holderHeldMs !== void 0 ? `, held for ${Math.round(progress.holderHeldMs / 1e3)}s` : "";
447
- const status = progress.waitingOn === "queue" ? `waiting in provider queue position ${progress.queuePosition} led by PID ${progress.holderPid}` : progress.queuePosition !== void 0 && progress.queuePosition > 1 ? `waiting in provider queue position ${progress.queuePosition}; provider lock held by PID ${progress.holderPid}${heldSeconds}` : `waiting for the provider lock held by PID ${progress.holderPid}${heldSeconds}`;
464
+ const holder = progress.holderPid !== void 0 ? `provider lock held by PID ${progress.holderPid}${heldSeconds}` : "provider lock holder unknown";
465
+ const remaining = progress.remainingWaitMs !== void 0 ? `; queue acquisition timeout in ${Math.ceil(progress.remainingWaitMs / 1e3)}s (does not stop the holder)` : "";
466
+ const status = progress.waitingOn === "queue" ? `waiting in provider queue position ${progress.queuePosition}; first waiter PID ${progress.queueLeaderPid}; ${holder}` : progress.queuePosition !== void 0 && progress.queuePosition > 1 ? `waiting in provider queue position ${progress.queuePosition}; provider lock held by PID ${progress.holderPid}${heldSeconds}` : `waiting for the provider lock held by PID ${progress.holderPid}${heldSeconds}`;
448
467
  process.stderr.write(
449
- `${activity} for ${target}: ${status}; waited ${Math.round(progress.waitingMs / 1e3)}s so far
468
+ `${activity} for ${target}: ${status}; waited ${Math.round(progress.waitingMs / 1e3)}s so far${remaining}
450
469
  `
451
470
  );
452
471
  };
@@ -4683,7 +4702,7 @@ var ControllerStore = class {
4683
4702
 
4684
4703
  // src/core/reliability-operation-store.ts
4685
4704
  function installedCliVersion() {
4686
- return true ? "0.0.77" : "0.0.0-dev";
4705
+ return true ? "0.0.78" : "0.0.0-dev";
4687
4706
  }
4688
4707
  function compareCliVersions(left, right) {
4689
4708
  const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -6383,7 +6402,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs18.default.rea
6383
6402
  const config = parseConfig(parsed ?? {}, configPath);
6384
6403
  const requiredVersion = config.devrouter?.version;
6385
6404
  if (requiredVersion && !hasWarnedVersionMismatch) {
6386
- const cliVersion = true ? "0.0.77" : "0.0.0-dev";
6405
+ const cliVersion = true ? "0.0.78" : "0.0.0-dev";
6387
6406
  if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
6388
6407
  hasWarnedVersionMismatch = true;
6389
6408
  process.stderr.write(
package/dist/devrouter.js CHANGED
@@ -474,9 +474,25 @@ function acquireFileLock(lockPath, options) {
474
474
  }
475
475
  if (options.onWait && now - lastProgressAt >= progressIntervalMs) {
476
476
  lastProgressAt = now;
477
+ let holder;
478
+ try {
479
+ const bytes2 = import_node_fs2.default.readFileSync(lockPath, "utf-8");
480
+ const record6 = parseLockRecord(bytes2);
481
+ if (record6.owner && isLockOwnerLive(record6.owner, livenessCache) && import_node_fs2.default.readFileSync(lockPath, "utf-8") === bytes2) {
482
+ holder = {
483
+ kind: "live",
484
+ pid: record6.owner.pid,
485
+ acquiredAtMs: record6.acquiredAtMs
486
+ };
487
+ }
488
+ } catch {
489
+ }
477
490
  options.onWait({
478
491
  waitingMs: now - waitStartedAt,
479
- holderPid: queueState.leaderPid,
492
+ remainingWaitMs: Math.max(0, deadline - now),
493
+ queueLeaderPid: queueState.leaderPid,
494
+ holderPid: holder?.pid,
495
+ holderHeldMs: holder?.acquiredAtMs !== void 0 ? Math.max(0, now - holder.acquiredAtMs) : void 0,
480
496
  queuePosition: queueState.position,
481
497
  waitingOn: "queue"
482
498
  });
@@ -514,6 +530,7 @@ function acquireFileLock(lockPath, options) {
514
530
  lastProgressAt = now;
515
531
  options.onWait({
516
532
  waitingMs: now - waitStartedAt,
533
+ remainingWaitMs: Math.max(0, deadline - now),
517
534
  holderPid: state.pid,
518
535
  holderHeldMs: state.acquiredAtMs !== void 0 ? Math.max(0, now - state.acquiredAtMs) : void 0,
519
536
  queuePosition: queueState?.position,
@@ -568,9 +585,11 @@ async function withFileLock(lockPath, options, operation) {
568
585
  function createStderrWaitReporter(activity, target) {
569
586
  return (progress) => {
570
587
  const heldSeconds = progress.holderHeldMs !== void 0 ? `, held for ${Math.round(progress.holderHeldMs / 1e3)}s` : "";
571
- const status = progress.waitingOn === "queue" ? `waiting in provider queue position ${progress.queuePosition} led by PID ${progress.holderPid}` : progress.queuePosition !== void 0 && progress.queuePosition > 1 ? `waiting in provider queue position ${progress.queuePosition}; provider lock held by PID ${progress.holderPid}${heldSeconds}` : `waiting for the provider lock held by PID ${progress.holderPid}${heldSeconds}`;
588
+ const holder = progress.holderPid !== void 0 ? `provider lock held by PID ${progress.holderPid}${heldSeconds}` : "provider lock holder unknown";
589
+ const remaining = progress.remainingWaitMs !== void 0 ? `; queue acquisition timeout in ${Math.ceil(progress.remainingWaitMs / 1e3)}s (does not stop the holder)` : "";
590
+ const status = progress.waitingOn === "queue" ? `waiting in provider queue position ${progress.queuePosition}; first waiter PID ${progress.queueLeaderPid}; ${holder}` : progress.queuePosition !== void 0 && progress.queuePosition > 1 ? `waiting in provider queue position ${progress.queuePosition}; provider lock held by PID ${progress.holderPid}${heldSeconds}` : `waiting for the provider lock held by PID ${progress.holderPid}${heldSeconds}`;
572
591
  process.stderr.write(
573
- `${activity} for ${target}: ${status}; waited ${Math.round(progress.waitingMs / 1e3)}s so far
592
+ `${activity} for ${target}: ${status}; waited ${Math.round(progress.waitingMs / 1e3)}s so far${remaining}
574
593
  `
575
594
  );
576
595
  };
@@ -4256,7 +4275,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs7.default.read
4256
4275
  const config = parseConfig(parsed ?? {}, configPath);
4257
4276
  const requiredVersion = config.devrouter?.version;
4258
4277
  if (requiredVersion && !hasWarnedVersionMismatch) {
4259
- const cliVersion = true ? "0.0.77" : "0.0.0-dev";
4278
+ const cliVersion = true ? "0.0.78" : "0.0.0-dev";
4260
4279
  if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
4261
4280
  hasWarnedVersionMismatch = true;
4262
4281
  process.stderr.write(
@@ -5509,7 +5528,7 @@ var init_reliability_contract = __esm({
5509
5528
 
5510
5529
  // src/core/reliability-operation-store.ts
5511
5530
  function installedCliVersion() {
5512
- return true ? "0.0.77" : "0.0.0-dev";
5531
+ return true ? "0.0.78" : "0.0.0-dev";
5513
5532
  }
5514
5533
  function compareCliVersions(left, right) {
5515
5534
  const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
@@ -21123,7 +21142,7 @@ async function buildDoctorReport(options = {}) {
21123
21142
  const config = runtimeConfig.config;
21124
21143
  loadedConfig = config;
21125
21144
  loadedWorkspace = runtimeConfig.workspace;
21126
- const cliVersion = true ? "0.0.77" : "0.0.0-dev";
21145
+ const cliVersion = true ? "0.0.78" : "0.0.0-dev";
21127
21146
  const configVersion = config.devrouter?.version;
21128
21147
  if (configVersion && cliVersion !== "0.0.0-dev" && compareSemver(configVersion, cliVersion) > 0) {
21129
21148
  addCheck(checks, {
@@ -26564,7 +26583,7 @@ var init_version = __esm({
26564
26583
 
26565
26584
  // src/cli.ts
26566
26585
  var import_commander = require("commander");
26567
- var CLI_VERSION = true ? "0.0.77" : "0.0.0-dev";
26586
+ var CLI_VERSION = true ? "0.0.78" : "0.0.0-dev";
26568
26587
  var VERSION_FLAGS = /* @__PURE__ */ new Set(["-V", "--version"]);
26569
26588
  function withErrorHandling(action2) {
26570
26589
  return async (...args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrouter/cli",
3
- "version": "0.0.77",
3
+ "version": "0.0.78",
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,35 @@
1
+ # Upgrade to devrouter 0.0.78
2
+
3
+ Provider queue diagnostics now distinguish the first waiter from the observed
4
+ lock holder. They report held duration and remaining acquisition time, including
5
+ that acquisition timeout does not stop the holder. Missing or changing evidence
6
+ reports an unknown holder. Acquisition, ownership, cancellation and startup
7
+ behavior remain unchanged. No schema, command, flag or environment migration is
8
+ needed.
9
+
10
+ ## Task
11
+
12
+ Use the published 0.0.78 CLI. Update the repository devrouter.version metadata
13
+ only when consumer source changes are authorized. Preserve staged work and the
14
+ existing runtime owner. Refresh generated agent guidance only with its owner's
15
+ authority. No generated runtime configuration or journal rewrite is needed.
16
+
17
+ For a queued operation, distinguish its queue leader from the observed provider
18
+ lock holder. An acquisition timeout describes the waiting operation; it does not
19
+ cancel the holder. Unknown holder evidence requires inspection, not lock removal.
20
+ Historical configuration-drift repair remains subject to its existing proof gates.
21
+
22
+ ## Validation
23
+
24
+ Verify the resolved executable and installed version. Use existing captured or
25
+ synthetic queue evidence to check holder attribution and timeout semantics; do
26
+ not start an unrelated workspace to exercise diagnostics. Require independent
27
+ terminal evidence for any already-authorized lifecycle operation. Preserve
28
+ live-worker, exact ownership, configuration and surviving-resource checks.
29
+
30
+ ## Report
31
+
32
+ Report release revision, executable, installed version, queue versus holder
33
+ evidence, and terminal operation result where available. Keep source and package
34
+ validation separate from consumer readiness or recovery. Record unknowns without
35
+ interpreting diagnostic messages as permission to cancel or remove resources.