@adhdev/daemon-standalone 0.9.82-rc.197 → 0.9.82-rc.198

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
@@ -49775,8 +49775,8 @@ ${lastSnapshot}`;
49775
49775
  if ((0, import_fs11.existsSync)(bundledCli)) resolvedCli = bundledCli;
49776
49776
  }
49777
49777
  if (!resolvedCli && appPath && os29 === "win32") {
49778
- const { dirname: dirname11 } = await import("path");
49779
- const appDir = dirname11(appPath);
49778
+ const { dirname: dirname12 } = await import("path");
49779
+ const appDir = dirname12(appPath);
49780
49780
  const candidates = [
49781
49781
  `${appDir}\\\\bin\\\\${def.cli}.cmd`,
49782
49782
  `${appDir}\\\\bin\\\\${def.cli}`,
@@ -62147,7 +62147,15 @@ ${formatManifestValidationIssues2(validation.issues)}`,
62147
62147
  * explicit wake-up there's nothing to trigger the busy → idle
62148
62148
  * downshift. */
62149
62149
  busyExpiryTimer = null;
62150
+ /** Pending idle-commit timer. Armed when the evaluator first returns idle;
62151
+ * fires after idle_hold_ms if no non-idle reading has cancelled it. */
62152
+ idleHoldTimer = null;
62153
+ /** State snapshot captured when the idle hold was armed — emitted on commit. */
62154
+ pendingIdleState = null;
62150
62155
  specWatcher = null;
62156
+ /** Ring buffer of committed state transitions (max 50). */
62157
+ stateHistory = [];
62158
+ prevStateAt = 0;
62151
62159
  /** Subscribe to outbound events. Returns an unsubscribe fn. */
62152
62160
  subscribe(listener) {
62153
62161
  this.listeners.add(listener);
@@ -62198,9 +62206,40 @@ ${formatManifestValidationIssues2(validation.issues)}`,
62198
62206
  shutdown() {
62199
62207
  for (const t of this.delegateTimers.values()) clearTimeout(t);
62200
62208
  this.delegateTimers.clear();
62209
+ this.cancelIdleHold();
62210
+ if (this.busyExpiryTimer) {
62211
+ clearTimeout(this.busyExpiryTimer);
62212
+ this.busyExpiryTimer = null;
62213
+ }
62201
62214
  this.specWatcher?.close();
62202
62215
  this.adapter.kill();
62203
62216
  }
62217
+ cancelIdleHold() {
62218
+ if (this.idleHoldTimer) {
62219
+ clearTimeout(this.idleHoldTimer);
62220
+ this.idleHoldTimer = null;
62221
+ }
62222
+ this.pendingIdleState = null;
62223
+ }
62224
+ pushHistory(stateId, label) {
62225
+ const now = Date.now();
62226
+ const durationMs = this.prevStateAt > 0 ? now - this.prevStateAt : 0;
62227
+ this.prevStateAt = now;
62228
+ this.stateHistory.push({ stateId, label, at: now, durationMs });
62229
+ if (this.stateHistory.length > 50) this.stateHistory.shift();
62230
+ }
62231
+ getStateHistory() {
62232
+ return this.stateHistory;
62233
+ }
62234
+ getLastBusyAt() {
62235
+ return this.lastBusyAt;
62236
+ }
62237
+ hasIdleHoldPending() {
62238
+ return this.idleHoldTimer !== null;
62239
+ }
62240
+ getSpecPath() {
62241
+ return this.opts.specPath;
62242
+ }
62204
62243
  // ────────────────────────────────────────────────────────────────────
62205
62244
  // Loading & adapter wiring
62206
62245
  // ────────────────────────────────────────────────────────────────────
@@ -62224,7 +62263,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
62224
62263
  }
62225
62264
  armSpecWatcher() {
62226
62265
  try {
62227
- this.specWatcher = fs10.watch(this.opts.specPath, { persistent: false }, () => {
62266
+ const dir = path19.dirname(this.opts.specPath);
62267
+ const base = path19.basename(this.opts.specPath);
62268
+ this.specWatcher = fs10.watch(dir, { persistent: false }, (_event, filename) => {
62269
+ if (filename && filename !== base) return;
62228
62270
  const res = loadSpec(this.opts.specPath);
62229
62271
  if (!res.ok) {
62230
62272
  this.emit({ kind: "spec_error", errors: res.errors });
@@ -62308,7 +62350,46 @@ ${formatManifestValidationIssues2(validation.issues)}`,
62308
62350
  if (evState.id === "busy") {
62309
62351
  this.lastBusyAt = Date.now();
62310
62352
  this.lastBusyState = evState;
62353
+ this.cancelIdleHold();
62311
62354
  this.scheduleBusyExpiry(busyWakeMs);
62355
+ } else if (evState.id !== this.currentStateId && evState.id !== "busy") {
62356
+ if (evState.id !== (this.spec.default_state ?? "idle")) {
62357
+ this.cancelIdleHold();
62358
+ }
62359
+ }
62360
+ const idleHoldMs = this.spec.debounce?.idle_hold_ms ?? 0;
62361
+ const isIdleState = evState.id === (this.spec.default_state ?? "idle");
62362
+ if (isIdleState && idleHoldMs > 0 && this.currentStateId !== evState.id) {
62363
+ if (!this.idleHoldTimer) {
62364
+ this.pendingIdleState = evState;
62365
+ this.idleHoldTimer = setTimeout(() => {
62366
+ this.idleHoldTimer = null;
62367
+ const committed = this.pendingIdleState;
62368
+ this.pendingIdleState = null;
62369
+ if (!committed) return;
62370
+ LOG2.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] idleHold committed after ${idleHoldMs}ms`);
62371
+ this.currentStateId = committed.id;
62372
+ this.currentEval = ev;
62373
+ this.pushHistory(committed.id, committed.label);
62374
+ this.emit({
62375
+ kind: "state_changed",
62376
+ state: committed,
62377
+ modal: null,
62378
+ controls: ev.controls.map((c) => ({ id: c.id, label: c.label, action_type: c.actionType }))
62379
+ });
62380
+ this.armOrCancelDelegateTimers(committed.id);
62381
+ if (this.opts.emitTrace) this.emit({ kind: "spec_trace", entries: ev.trace });
62382
+ }, idleHoldMs);
62383
+ }
62384
+ this.currentEval = ev;
62385
+ const graceMs2 = this.spec.debounce?.startup_grace_ms ?? STARTUP_GRACE_MS;
62386
+ if (!this.idleSeenOnce && Date.now() - this.startedAtMs >= graceMs2) {
62387
+ this.idleSeenOnce = true;
62388
+ const queued = this.pendingSends.splice(0);
62389
+ for (const text of queued) setTimeout(() => this.actuallySendMessage(text), 50);
62390
+ }
62391
+ if (this.pickerInProgress) this.tryAdvancePicker(screen);
62392
+ return;
62312
62393
  }
62313
62394
  const changed = forceEmit || evState.id !== this.currentStateId || !shallowSameModal(ev, this.currentEval) || !shallowSameControls(ev, this.currentEval);
62314
62395
  if (this.pickerInProgress) this.tryAdvancePicker(screen);
@@ -62324,6 +62405,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
62324
62405
  }
62325
62406
  if (changed) {
62326
62407
  this.currentStateId = evState.id;
62408
+ this.pushHistory(evState.id, evState.label);
62327
62409
  this.emit({
62328
62410
  kind: "state_changed",
62329
62411
  state: evState,
@@ -62755,7 +62837,11 @@ ${formatManifestValidationIssues2(validation.issues)}`,
62755
62837
  activeInteractivePrompt: this.activeInteractivePrompt,
62756
62838
  exited: this.exited,
62757
62839
  screen,
62758
- sections
62840
+ sections,
62841
+ stateHistory: this.driver.getStateHistory(),
62842
+ idleHoldPending: this.driver.hasIdleHoldPending(),
62843
+ lastBusyAt: this.driver.getLastBusyAt(),
62844
+ specPath: this.driver.getSpecPath()
62759
62845
  };
62760
62846
  }
62761
62847
  getRuntimeMetadata() {
@@ -68264,17 +68350,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
68264
68350
  }
68265
68351
  function readSession(sessionPath) {
68266
68352
  if (!sessionPath || !path25.isAbsolute(sessionPath)) return null;
68267
- const basename13 = path25.basename(sessionPath, ".jsonl");
68268
- if (!isSafeSessionId(basename13)) return null;
68353
+ const basename14 = path25.basename(sessionPath, ".jsonl");
68354
+ if (!isSafeSessionId(basename14)) return null;
68269
68355
  if (!fs14.existsSync(sessionPath)) return null;
68270
68356
  const sourceMtimeMs = statMtimeMs(sessionPath);
68271
- const messages = parseTranscriptFile(sessionPath, basename13);
68357
+ const messages = parseTranscriptFile(sessionPath, basename14);
68272
68358
  if (messages.length === 0) return null;
68273
68359
  const firstSystem = messages.find((m) => m.kind === "session_start");
68274
68360
  const workspace = firstSystem?.workspace || firstSystem?.content || void 0;
68275
68361
  return {
68276
68362
  messages,
68277
- providerSessionId: basename13,
68363
+ providerSessionId: basename14,
68278
68364
  source: "provider-native",
68279
68365
  sourcePath: sessionPath,
68280
68366
  sourceMtimeMs,
@@ -68474,8 +68560,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
68474
68560
  if (!fs15.existsSync(sessionPath)) return null;
68475
68561
  const meta3 = readSessionMeta(sessionPath);
68476
68562
  const metaId = String(meta3?.id ?? "").trim();
68477
- const basename13 = path26.basename(sessionPath, ".jsonl");
68478
- const uuidMatch = basename13.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
68563
+ const basename14 = path26.basename(sessionPath, ".jsonl");
68564
+ const uuidMatch = basename14.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
68479
68565
  const filenameUuid2 = uuidMatch ? uuidMatch[1] : "";
68480
68566
  if (metaId && filenameUuid2 && metaId !== filenameUuid2) return null;
68481
68567
  const sessionId = metaId || filenameUuid2;
@@ -75661,6 +75747,21 @@ ${e?.stderr || ""}`
75661
75747
  } : null
75662
75748
  };
75663
75749
  }
75750
+ case "get_spec_debug": {
75751
+ const sessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : typeof args?.sessionId === "string" ? args.sessionId.trim() : "";
75752
+ if (!sessionId) return { success: false, error: "targetSessionId required" };
75753
+ const target = this.deps.sessionRegistry.get(sessionId);
75754
+ if (!target) return { success: false, error: "Session not found", sessionId };
75755
+ const adapter = this.deps.cliManager.findAdapter(target.providerType, { instanceKey: sessionId })?.adapter;
75756
+ const snapshot = adapter && typeof adapter.getDebugSnapshot === "function" ? adapter.getDebugSnapshot() : null;
75757
+ return {
75758
+ success: true,
75759
+ sessionId,
75760
+ providerType: target.providerType,
75761
+ isSpecProvider: snapshot !== null,
75762
+ snapshot
75763
+ };
75764
+ }
75664
75765
  // ── User-level coordinator-prompt files (~/.adhdev/coordinator-prompts/).
75665
75766
  // These live on this daemon's filesystem and never sync to the
75666
75767
  // cloud / other daemons — they're per-machine config. The
@@ -76988,7 +77089,7 @@ ${ptyResult.output.slice(-2e3)}`);
76988
77089
  };
76989
77090
  }
76990
77091
  const { existsSync: existsSync39, readFileSync: readFileSync33, writeFileSync: writeFileSync21, copyFileSync: copyFileSync4, mkdirSync: mkdirSync19 } = await import("fs");
76991
- const { dirname: dirname11 } = await import("path");
77092
+ const { dirname: dirname12 } = await import("path");
76992
77093
  const mcpConfigPath = coordinatorSetup.configPath;
76993
77094
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
76994
77095
  let hermesBaseConfig = null;
@@ -77023,7 +77124,7 @@ ${ptyResult.output.slice(-2e3)}`);
77023
77124
  };
77024
77125
  }
77025
77126
  try {
77026
- mkdirSync19(dirname11(mcpConfigPath), { recursive: true });
77127
+ mkdirSync19(dirname12(mcpConfigPath), { recursive: true });
77027
77128
  } catch (error48) {
77028
77129
  const message = `Could not prepare MCP config path for automatic setup: ${error48?.message || error48}`;
77029
77130
  LOG2.error("MeshCoordinator", message);
@@ -77033,7 +77134,7 @@ ${ptyResult.output.slice(-2e3)}`);
77033
77134
  const hadExistingMcpConfig = existsSync39(mcpConfigPath);
77034
77135
  let existingMcpConfig = hermesBaseConfig?.config || {};
77035
77136
  if (hermesBaseConfig) {
77036
- copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname11(mcpConfigPath));
77137
+ copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname12(mcpConfigPath));
77037
77138
  }
77038
77139
  if (hadExistingMcpConfig) {
77039
77140
  try {
@@ -77071,7 +77172,7 @@ ${ptyResult.output.slice(-2e3)}`);
77071
77172
  const cliArgs = [];
77072
77173
  const launchEnv = {};
77073
77174
  if (configFormat === "hermes_config_yaml") {
77074
- launchEnv.HERMES_HOME = dirname11(mcpConfigPath);
77175
+ launchEnv.HERMES_HOME = dirname12(mcpConfigPath);
77075
77176
  launchEnv.HERMES_IGNORE_USER_CONFIG = "";
77076
77177
  }
77077
77178
  let autoImportContextFilePath;