@adhdev/daemon-standalone 1.0.58-rc.11 → 1.0.58-rc.13

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.
package/dist/index.js CHANGED
@@ -36882,10 +36882,10 @@ var require_dist3 = __commonJS({
36882
36882
  }
36883
36883
  function getDaemonBuildInfo() {
36884
36884
  if (cached2) return cached2;
36885
- const commit = readInjected(true ? "3ca2b5ad15d65b9747431bc63b717940d2431daa" : void 0) ?? "unknown";
36886
- const commitShort = readInjected(true ? "3ca2b5ad" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
36887
- const version2 = readInjected(true ? "1.0.58-rc.11" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
36888
- const builtAt = readInjected(true ? "2026-08-25T02:16:50.726Z" : void 0);
36885
+ const commit = readInjected(true ? "900d8f99b49f7dc9b6f1455c21c6f5ea3b91d789" : void 0) ?? "unknown";
36886
+ const commitShort = readInjected(true ? "900d8f99" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
36887
+ const version2 = readInjected(true ? "1.0.58-rc.13" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
36888
+ const builtAt = readInjected(true ? "2026-08-25T08:35:02.974Z" : void 0);
36889
36889
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
36890
36890
  return cached2;
36891
36891
  }
@@ -40133,12 +40133,21 @@ child.on('exit', () => process.exit(0));
40133
40133
  async function fetchClaudeQuota2(overrides = {}) {
40134
40134
  const deps = resolveDeps(overrides);
40135
40135
  const paths = resolveInstallPaths(deps.env);
40136
+ const setupFailure = statuslineSetupFailure(deps.env);
40137
+ if (setupFailure !== null) {
40138
+ return setupFailure;
40139
+ }
40136
40140
  let raw;
40137
40141
  try {
40138
40142
  raw = fs5.readFileSync(paths.snapshotFile, "utf-8");
40139
40143
  } catch (err) {
40140
40144
  if (err?.code === "ENOENT") {
40141
- return missingSnapshotFailure(deps.env);
40145
+ return quotaFailure(
40146
+ "claude-cli",
40147
+ "unavailable",
40148
+ "No Claude quota captured yet \u2014 open a Claude Code session to record one",
40149
+ { source: SOURCE, failureKind: "no-data" }
40150
+ );
40142
40151
  }
40143
40152
  const message = err instanceof Error ? err.message : String(err);
40144
40153
  return quotaFailure("claude-cli", "error", `Unable to read Claude quota snapshot: ${message}`, {
@@ -40193,7 +40202,7 @@ child.on('exit', () => process.exit(0));
40193
40202
  metadata: { source: SOURCE }
40194
40203
  };
40195
40204
  }
40196
- function missingSnapshotFailure(env2) {
40205
+ function statuslineSetupFailure(env2) {
40197
40206
  let installed = false;
40198
40207
  let danglingPath = null;
40199
40208
  try {
@@ -40207,20 +40216,18 @@ child.on('exit', () => process.exit(0));
40207
40216
  "claude-cli",
40208
40217
  "unavailable",
40209
40218
  `Claude statusline wrapper is missing (${danglingPath}) \u2014 re-run \`adhdev quota claude:install\` to repair`,
40210
- { source: SOURCE, failureKind: "no-data" }
40219
+ { source: SOURCE, failureKind: "setup-required" }
40211
40220
  );
40212
40221
  }
40213
- return quotaFailure(
40214
- "claude-cli",
40215
- "unavailable",
40216
- installed ? "No Claude quota captured yet \u2014 open a Claude Code session to record one" : "Claude quota reporting is not set up \u2014 run `adhdev quota claude:install`",
40217
- // 'no-data', NOT 'missing-credentials': this fetcher reads no
40218
- // credential at all (see the header), and the old label made the
40219
- // dashboard render "(missing credentials)" for a machine that was
40220
- // merely waiting for its first statusline capture — a live
40221
- // coordinator misread that as a claude-cli auth failure.
40222
- { source: SOURCE, failureKind: "no-data" }
40223
- );
40222
+ if (!installed) {
40223
+ return quotaFailure(
40224
+ "claude-cli",
40225
+ "unavailable",
40226
+ "Claude quota reporting is not set up \u2014 run `adhdev quota claude:install`",
40227
+ { source: SOURCE, failureKind: "setup-required" }
40228
+ );
40229
+ }
40230
+ return null;
40224
40231
  }
40225
40232
  var fs5;
40226
40233
  var STALE_AFTER_MS;
@@ -44929,6 +44936,7 @@ ${error48.message || ""}`;
44929
44936
  normalizeCapabilityTags: () => normalizeCapabilityTags,
44930
44937
  normalizeMagiSlots: () => normalizeMagiSlots,
44931
44938
  normalizeRepoIdentity: () => normalizeRepoIdentity,
44939
+ readMeshConfigFromDisk: () => readMeshConfigFromDisk,
44932
44940
  removeMagiKindPanel: () => removeMagiKindPanel,
44933
44941
  removeNode: () => removeNode,
44934
44942
  resolveScopedMeshId: () => resolveScopedMeshId,
@@ -44936,6 +44944,7 @@ ${error48.message || ""}`;
44936
44944
  setMagiKindPanel: () => setMagiKindPanel,
44937
44945
  setMeshHostPin: () => setMeshHostPin,
44938
44946
  setMeshQuotaRouting: () => setMeshQuotaRouting,
44947
+ statMeshConfigFile: () => statMeshConfigFile,
44939
44948
  tokenIdForManualPairing: () => tokenIdForManualPairing,
44940
44949
  updateMesh: () => updateMesh,
44941
44950
  updateNode: () => updateNode
@@ -44987,17 +44996,28 @@ ${error48.message || ""}`;
44987
44996
  release2();
44988
44997
  }
44989
44998
  }
44990
- function readMeshConfigFile() {
44999
+ function readMeshConfigFromDisk() {
44991
45000
  const path63 = getMeshConfigPath();
44992
- if (!(0, import_fs5.existsSync)(path63)) return { meshes: [] };
45001
+ if (!(0, import_fs5.existsSync)(path63)) return null;
44993
45002
  try {
44994
45003
  const raw = JSON.parse((0, import_fs5.readFileSync)(path63, "utf-8"));
44995
- if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
45004
+ if (!raw || !Array.isArray(raw.meshes)) return null;
44996
45005
  return raw;
44997
45006
  } catch {
44998
- return { meshes: [] };
45007
+ return null;
45008
+ }
45009
+ }
45010
+ function statMeshConfigFile() {
45011
+ try {
45012
+ const stat2 = (0, import_fs5.statSync)(getMeshConfigPath());
45013
+ return { mtimeMs: stat2.mtimeMs, size: stat2.size };
45014
+ } catch {
45015
+ return null;
44999
45016
  }
45000
45017
  }
45018
+ function readMeshConfigFile() {
45019
+ return readMeshConfigFromDisk() ?? { meshes: [] };
45020
+ }
45001
45021
  function loadMeshConfig(options = {}) {
45002
45022
  const config2 = readMeshConfigFile();
45003
45023
  const migrated = migrateLoadedMeshConfig(config2);
@@ -127755,6 +127775,8 @@ ${ptyResult.output.slice(-2e3)}`);
127755
127775
  }
127756
127776
  init_debug_trace();
127757
127777
  init_mesh_host_ownership();
127778
+ init_repo_mesh_types();
127779
+ init_mesh_config();
127758
127780
  var fs58 = __toESM2(require("fs"));
127759
127781
  init_mesh_node_identity();
127760
127782
  init_router_refine();
@@ -128904,7 +128926,7 @@ ${ptyResult.output.slice(-2e3)}`);
128904
128926
  role: "member"
128905
128927
  };
128906
128928
  }
128907
- var DaemonCommandRouter = class {
128929
+ var DaemonCommandRouter = class _DaemonCommandRouter {
128908
128930
  /** Public (not private) so the extracted ./router-refine.ts orchestration can reach it via `self`. */
128909
128931
  deps;
128910
128932
  /** In-memory cache for cloud-originating meshes passed via inlineMesh.
@@ -128923,6 +128945,15 @@ ${ptyResult.output.slice(-2e3)}`);
128923
128945
  /** Coordinator-owned whole-mesh aggregate status snapshots. Browser callers read this by default.
128924
128946
  * Public (not private) so the extracted ./router-aggregate-status.ts orchestration can reach it via `self`. */
128925
128947
  aggregateMeshStatusCache = /* @__PURE__ */ new Map();
128948
+ /**
128949
+ * meshes.json policy resync state (see syncInlineMeshPoliciesFromDisk).
128950
+ * checkedAtMs throttles the stat; mtimeMs/size are the last-seen file
128951
+ * identity. -1 = no baseline recorded yet: the first check RECORDS the
128952
+ * baseline without applying, so a stale local file mirror can never
128953
+ * regress a fresher inline (cloud-coordinator) policy — only edits made
128954
+ * while this daemon is alive and watching are pulled into memory.
128955
+ */
128956
+ meshPolicyDiskSync = { checkedAtMs: 0, mtimeMs: -1, size: -1 };
128926
128957
  /** Shared per-peer git_status probe dedup + recently-probed reuse gate.
128927
128958
  * Spans separate mesh_status/get_mesh calls so the dashboard auto-retry
128928
128959
  * loop cannot storm a slow peer with back-to-back refreshUpstream probes. */
@@ -128966,7 +128997,67 @@ ${ptyResult.output.slice(-2e3)}`);
128966
128997
  rememberAggregateMeshStatus(meshId, snapshot, refreshReason) {
128967
128998
  return rememberAggregateMeshStatus(this, meshId, snapshot, refreshReason);
128968
128999
  }
129000
+ /**
129001
+ * meshes.json → inline-cache policy resync (mtime-triggered lazy reload).
129002
+ *
129003
+ * Out-of-band edits to meshes.json (an operator hand-editing a policy flag)
129004
+ * never reached the inline mesh cache: command-path updates (update_mesh)
129005
+ * rewrite BOTH disk and cache, but a direct file edit changed nothing in
129006
+ * memory, so mesh_status / refine gating kept serving the boot-time policy
129007
+ * until a daemon restart (live evidence 2026-08-25: requireApprovalForPush
129008
+ * flipped to false on disk 92 min after daemon boot; the daemon kept
129009
+ * reporting and enforcing true).
129010
+ *
129011
+ * Fix: on inline-cache reads, stat meshes.json (throttled — routing and
129012
+ * status polling are hot paths); when the file changed, re-apply ONLY each
129013
+ * cached mesh's `policy` block from disk. Policy-only, never nodes/meshHost:
129014
+ * the inline cache is the coordinator's live node truth, and the daemon's
129015
+ * own mutators read-modify-write through disk, so they already carry the
129016
+ * edit forward — overwriting the whole cached mesh here would clobber
129017
+ * in-flight node truth for zero benefit. A changed policy also busts the
129018
+ * aggregate status snapshot, whose scheduling projection is derived from it.
129019
+ *
129020
+ * Safety rules:
129021
+ * - unparseable file (torn mid-edit write) → keep the in-memory policy,
129022
+ * log only. Never fall back to defaults: that would silently LOOSEN
129023
+ * security flags (requireApprovalForPush / requireApprovalForDestructiveGit).
129024
+ * - mesh absent from disk (deleted, or inline-only cloud mesh) → keep the
129025
+ * cache entry untouched.
129026
+ */
129027
+ syncInlineMeshPoliciesFromDisk() {
129028
+ if (this.inlineMeshCache.size === 0) return;
129029
+ const now = Date.now();
129030
+ const sync = this.meshPolicyDiskSync;
129031
+ if (now - sync.checkedAtMs < _DaemonCommandRouter.MESH_POLICY_DISK_SYNC_THROTTLE_MS) return;
129032
+ sync.checkedAtMs = now;
129033
+ const stat2 = statMeshConfigFile();
129034
+ if (!stat2) return;
129035
+ if (stat2.mtimeMs === sync.mtimeMs && stat2.size === sync.size) return;
129036
+ const hadBaseline = sync.mtimeMs >= 0;
129037
+ sync.mtimeMs = stat2.mtimeMs;
129038
+ sync.size = stat2.size;
129039
+ if (!hadBaseline) return;
129040
+ const disk = readMeshConfigFromDisk();
129041
+ if (!disk) {
129042
+ console.warn("[mesh-config] meshes.json changed but is unparseable (mid-edit?) \u2014 keeping in-memory mesh policies");
129043
+ return;
129044
+ }
129045
+ const diskPolicyByMeshId = /* @__PURE__ */ new Map();
129046
+ for (const mesh of disk.meshes) {
129047
+ if (mesh?.id && mesh.policy && typeof mesh.policy === "object") diskPolicyByMeshId.set(mesh.id, mesh.policy);
129048
+ }
129049
+ for (const [meshId, cached5] of this.inlineMeshCache) {
129050
+ const diskPolicy = diskPolicyByMeshId.get(meshId);
129051
+ if (!diskPolicy) continue;
129052
+ const nextPolicy = mergeAndNormalizePolicy(void 0, diskPolicy);
129053
+ if (JSON.stringify(cached5?.policy ?? null) === JSON.stringify(nextPolicy)) continue;
129054
+ cached5.policy = nextPolicy;
129055
+ this.invalidateAggregateMeshStatus(meshId);
129056
+ }
129057
+ }
129058
+ static MESH_POLICY_DISK_SYNC_THROTTLE_MS = 250;
128969
129059
  getCachedInlineMeshNodes() {
129060
+ this.syncInlineMeshPoliciesFromDisk();
128970
129061
  const nodes = [];
128971
129062
  for (const mesh of this.inlineMeshCache.values()) {
128972
129063
  if (Array.isArray(mesh?.nodes)) {
@@ -128986,6 +129077,7 @@ ${ptyResult.output.slice(-2e3)}`);
128986
129077
  * the mesh policy is absent, matching the worker-launch stamp.
128987
129078
  */
128988
129079
  getCachedInlineMeshNodesWithVisibility() {
129080
+ this.syncInlineMeshPoliciesFromDisk();
128989
129081
  const out = [];
128990
129082
  for (const mesh of this.inlineMeshCache.values()) {
128991
129083
  const spawnedSessionVisibility = mesh?.policy?.spawnedSessionVisibility === "visible" ? "visible" : "hidden";
@@ -129006,6 +129098,7 @@ ${ptyResult.output.slice(-2e3)}`);
129006
129098
  return resolveRemoteMeshSessionOwnerDaemonId(this, sessionId, ownerNodeIdHint);
129007
129099
  }
129008
129100
  getCachedInlineMesh(meshId, inlineMesh) {
129101
+ this.syncInlineMeshPoliciesFromDisk();
129009
129102
  if (inlineMesh && typeof inlineMesh === "object") {
129010
129103
  return this.warmInlineMeshCache(meshId, inlineMesh);
129011
129104
  }