@adhdev/daemon-core 0.9.82-rc.490 → 0.9.82-rc.492

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.mjs CHANGED
@@ -409,10 +409,10 @@ function readInjected(value) {
409
409
  }
410
410
  function getDaemonBuildInfo() {
411
411
  if (cached) return cached;
412
- const commit = readInjected(true ? "cfa673de50d6ede347cf424b9cab1e94081eadb2" : void 0) ?? "unknown";
413
- const commitShort = readInjected(true ? "cfa673de" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
- const version = readInjected(true ? "0.9.82-rc.490" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
- const builtAt = readInjected(true ? "2026-07-10T05:30:12.581Z" : void 0);
412
+ const commit = readInjected(true ? "d3ef86c2b3332b1ce289eb8d4193c7c945d39401" : void 0) ?? "unknown";
413
+ const commitShort = readInjected(true ? "d3ef86c2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
+ const version = readInjected(true ? "0.9.82-rc.492" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
+ const builtAt = readInjected(true ? "2026-07-10T07:51:20.549Z" : void 0);
416
416
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
417
417
  return cached;
418
418
  }
@@ -3037,6 +3037,7 @@ __export(mesh_config_exports, {
3037
3037
  listMagiKindPanels: () => listMagiKindPanels,
3038
3038
  listMeshes: () => listMeshes,
3039
3039
  markMeshHostPairingJoined: () => markMeshHostPairingJoined,
3040
+ normalizeCapabilityTags: () => normalizeCapabilityTags,
3040
3041
  normalizeMagiSlots: () => normalizeMagiSlots,
3041
3042
  normalizeRepoIdentity: () => normalizeRepoIdentity,
3042
3043
  removeMagiKindPanel: () => removeMagiKindPanel,
@@ -24501,7 +24502,7 @@ var init_provider_cli_parse = __esm({
24501
24502
  });
24502
24503
 
24503
24504
  // src/cli-adapters/cli-state-engine.ts
24504
- var SCRIPT_STATUS_DEBOUNCE_MS, MAX_FINISH_RETRIES, FINISH_RETRY_DELAY_MS, MAX_TRACE_ENTRIES, APPROVAL_EXIT_TIMEOUT_MS, IDLE_CONFIRMATION_GRACE_MS, CliStateEngine;
24505
+ var SCRIPT_STATUS_DEBOUNCE_MS, MAX_FINISH_RETRIES, FINISH_RETRY_DELAY_MS, MAX_TRACE_ENTRIES, APPROVAL_EXIT_TIMEOUT_MS, IDLE_CONFIRMATION_GRACE_MS, APPROVAL_RESUME_IDLE_DEFER_CAP_MS, CliStateEngine;
24505
24506
  var init_cli_state_engine = __esm({
24506
24507
  "src/cli-adapters/cli-state-engine.ts"() {
24507
24508
  "use strict";
@@ -24514,6 +24515,7 @@ var init_cli_state_engine = __esm({
24514
24515
  MAX_TRACE_ENTRIES = 250;
24515
24516
  APPROVAL_EXIT_TIMEOUT_MS = 6e4;
24516
24517
  IDLE_CONFIRMATION_GRACE_MS = 2e3;
24518
+ APPROVAL_RESUME_IDLE_DEFER_CAP_MS = 18e3;
24517
24519
  CliStateEngine = class {
24518
24520
  constructor(provider, runner, transport, callbacks, timeouts) {
24519
24521
  this.provider = provider;
@@ -24603,6 +24605,12 @@ var init_cli_state_engine = __esm({
24603
24605
  pendingScriptStatusTimer = null;
24604
24606
  // ── Idle candidate ───────────────────────────────
24605
24607
  idleFinishCandidate = null;
24608
+ // FALSE-IDLE (Fix 2): wall-clock when the current post-approval resume-grace idle
24609
+ // defer began, scoped to a responseEpoch. Zero when not deferring. Bounds the defer
24610
+ // to APPROVAL_RESUME_IDLE_DEFER_CAP_MS so a turn that genuinely ended right after an
24611
+ // approval eventually finishes. Reset whenever a new turn/response starts or completes.
24612
+ approvalResumeDeferSince = 0;
24613
+ approvalResumeDeferEpoch = -1;
24606
24614
  // ── Idle confirmation grace ──────────────────────
24607
24615
  /**
24608
24616
  * `finishResponse` produces the `generating → idle` transition that
@@ -24816,6 +24824,8 @@ var init_cli_state_engine = __esm({
24816
24824
  this.activeModal = null;
24817
24825
  this.pendingScriptStatus = null;
24818
24826
  this.pendingScriptStatusSince = 0;
24827
+ this.approvalResumeDeferSince = 0;
24828
+ this.approvalResumeDeferEpoch = -1;
24819
24829
  }
24820
24830
  clearIdleFinishCandidate(reason) {
24821
24831
  if (!this.idleFinishCandidate) return;
@@ -25237,6 +25247,14 @@ var init_cli_state_engine = __esm({
25237
25247
  const idleReady = !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleFinishConfirmMs;
25238
25248
  const candidate = this.idleFinishCandidate;
25239
25249
  const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === snap.lastOutputAt && candidate.lastScreenChangeAt === snap.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= idleFinishConfirmMs;
25250
+ if (this.shouldDeferIdleForApprovalResume(now)) {
25251
+ this.clearIdleFinishCandidate("approval_resume_grace_defer");
25252
+ if (this.idleTimeout) clearTimeout(this.idleTimeout);
25253
+ this.idleTimeout = setTimeout(() => {
25254
+ if (this.isWaitingForResponse) this.evaluateSettled(this.transport.getSnapshot());
25255
+ }, this.timeouts.idleFinish);
25256
+ return;
25257
+ }
25240
25258
  if (idleReady && candidateQuiet) {
25241
25259
  this.clearIdleFinishCandidate("finish_response");
25242
25260
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
@@ -25254,6 +25272,12 @@ var init_cli_state_engine = __esm({
25254
25272
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
25255
25273
  this.idleTimeout = setTimeout(() => {
25256
25274
  if (this.isWaitingForResponse && !this.hasActionableApproval()) {
25275
+ if (this.shouldDeferIdleForApprovalResume(Date.now())) {
25276
+ this.idleTimeout = setTimeout(() => {
25277
+ if (this.isWaitingForResponse) this.evaluateSettled(this.transport.getSnapshot());
25278
+ }, this.timeouts.idleFinish);
25279
+ return;
25280
+ }
25257
25281
  if (this.shouldDeferIdleTimeoutFinish()) return;
25258
25282
  const parsed = this.runParseSession(this.transport.getSnapshot());
25259
25283
  if (this.shouldDeferFinishForTranscript(parsed)) {
@@ -25265,6 +25289,47 @@ var init_cli_state_engine = __esm({
25265
25289
  }
25266
25290
  }, this.timeouts.idleFinish);
25267
25291
  }
25292
+ /**
25293
+ * FALSE-IDLE (Fix 2): should applyIdle suppress the idle/finish for the current
25294
+ * turn because we are inside the post-approval resume grace?
25295
+ *
25296
+ * True only when: (a) the owning instance reports it is an autonomous auto-approving
25297
+ * mesh session that resolved a modal within the resume-grace window
25298
+ * (isInApprovalResumeGrace callback — the SAME judgment Fix 1 uses), AND (b) the defer
25299
+ * for THIS response epoch has not yet exceeded APPROVAL_RESUME_IDLE_DEFER_CAP_MS.
25300
+ * The cap guarantees no infinite defer: a turn that genuinely ended right after an
25301
+ * approval and stays silent past the cap stops being suppressed and finishes normally.
25302
+ * The per-epoch anchor means a fresh turn/response restarts the clock.
25303
+ */
25304
+ shouldDeferIdleForApprovalResume(now) {
25305
+ if (typeof this.callbacks.isInApprovalResumeGrace !== "function") {
25306
+ this.clearApprovalResumeDefer();
25307
+ return false;
25308
+ }
25309
+ let inGrace = false;
25310
+ try {
25311
+ inGrace = this.callbacks.isInApprovalResumeGrace() === true;
25312
+ } catch {
25313
+ inGrace = false;
25314
+ }
25315
+ if (!inGrace) {
25316
+ this.clearApprovalResumeDefer();
25317
+ return false;
25318
+ }
25319
+ if (this.approvalResumeDeferEpoch !== this.responseEpoch || this.approvalResumeDeferSince === 0) {
25320
+ this.approvalResumeDeferEpoch = this.responseEpoch;
25321
+ this.approvalResumeDeferSince = now;
25322
+ return true;
25323
+ }
25324
+ if (now - this.approvalResumeDeferSince >= APPROVAL_RESUME_IDLE_DEFER_CAP_MS) {
25325
+ return false;
25326
+ }
25327
+ return true;
25328
+ }
25329
+ clearApprovalResumeDefer() {
25330
+ this.approvalResumeDeferSince = 0;
25331
+ this.approvalResumeDeferEpoch = -1;
25332
+ }
25268
25333
  finishResponse() {
25269
25334
  if (this.submitPendingUntil > Date.now()) return;
25270
25335
  if (this.responseSettleIgnoreUntil > Date.now()) return;
@@ -25706,7 +25771,8 @@ var init_provider_cli_adapter = __esm({
25706
25771
  },
25707
25772
  onTurnCompleted: () => {
25708
25773
  this.responseBuffer = "";
25709
- }
25774
+ },
25775
+ isInApprovalResumeGrace: () => this.inApprovalResumeGraceProbe?.() === true
25710
25776
  },
25711
25777
  resolvedConfig.timeouts
25712
25778
  );
@@ -25738,6 +25804,9 @@ var init_provider_cli_adapter = __esm({
25738
25804
  ptyProcess = null;
25739
25805
  transportFactory;
25740
25806
  onStatusChange = null;
25807
+ // FALSE-IDLE (Fix 2): probe the owning instance for the post-approval resume grace.
25808
+ // Null until the instance registers it; the engine treats absence as "not in grace".
25809
+ inApprovalResumeGraceProbe = null;
25741
25810
  // ─── State machine engine ─────────────────────────
25742
25811
  engine;
25743
25812
  responseBuffer = "";
@@ -25981,6 +26050,12 @@ ${lastSnapshot}`;
25981
26050
  setOnStatusChange(callback) {
25982
26051
  this.onStatusChange = callback;
25983
26052
  }
26053
+ // FALSE-IDLE (Fix 2): the instance registers its inApprovalResumeGrace judgment so the
26054
+ // engine's applyIdle hysteresis can scope itself to autonomous auto-approving sessions
26055
+ // without the engine needing any mesh/auto-approve awareness of its own.
26056
+ setInApprovalResumeGraceProbe(probe) {
26057
+ this.inApprovalResumeGraceProbe = probe;
26058
+ }
25984
26059
  setOnPtyData(callback) {
25985
26060
  this.onPtyDataCallback = callback;
25986
26061
  }
@@ -45197,6 +45272,28 @@ var CliProviderInstance = class _CliProviderInstance {
45197
45272
  * the nudge was NOT deferred) and leaked to the coordinator.
45198
45273
  */
45199
45274
  static AUTO_APPROVE_MASK_STALL_MS = 10500;
45275
+ /**
45276
+ * FALSE-IDLE (inter-approval quiet valley): grace window after an auto-approve
45277
+ * (or mesh_approve) RESOLVES a modal during which a subsequent generating→idle
45278
+ * quiet valley must NOT be treated as turn completion.
45279
+ *
45280
+ * The RCA: auto-approve resolves a modal → the agent resumes the same turn →
45281
+ * between resolving that approval and preparing the next tool/approval the agent
45282
+ * falls briefly silent. The FSM sees idle + a recorded mid-turn assistant bubble
45283
+ * and fires an early agent:generating_completed even though the turn is still in
45284
+ * flight. Live evidence showed the same session resuming waiting_approval ~13s
45285
+ * after a "clean" completion emit.
45286
+ *
45287
+ * The window must be comfortably larger than the observed resume gap (~13s) so
45288
+ * the valley is bridged, but not so large that a turn that genuinely ended right
45289
+ * after an approval is held for an annoying stretch. 18s clears 13s with margin
45290
+ * while capping the worst-case extra hold on a truly-finished turn at 18s (still
45291
+ * well under COMPLETED_FINALIZATION_MAX_WAIT_MS's 30s hard bound). The recency is
45292
+ * measured from the engine's lastApprovalResolvedAt, which is stamped ONLY by
45293
+ * resolveModal (auto-approve fire / dashboard / mesh_approve) — so a plain turn
45294
+ * with no approval never carries recency and is never held (no regression).
45295
+ */
45296
+ static APPROVAL_RESUME_GRACE_MS = 18e3;
45200
45297
  adapter;
45201
45298
  context = null;
45202
45299
  events = [];
@@ -45344,6 +45441,9 @@ var CliProviderInstance = class _CliProviderInstance {
45344
45441
  this.adapter.setOnStatusChange(() => {
45345
45442
  this.detectStatusTransition();
45346
45443
  });
45444
+ if (typeof this.adapter.setInApprovalResumeGraceProbe === "function") {
45445
+ this.adapter.setInApprovalResumeGraceProbe(() => this.inApprovalResumeGrace());
45446
+ }
45347
45447
  await this.adapter.spawn();
45348
45448
  await this.enforceFreshSessionLaunchIfNeeded();
45349
45449
  await this.applyInitialThinkingLevelViaControl();
@@ -46232,6 +46332,9 @@ var CliProviderInstance = class _CliProviderInstance {
46232
46332
  if (adapterAny?.isWaitingForResponse === true) return { reason: "adapter_waiting_for_response", terminal: !approvalResolvedIdle };
46233
46333
  if (adapterAny?.currentTurnScope) return { reason: "adapter_turn_scope_active", terminal: !approvalResolvedIdle };
46234
46334
  if (this.hasAdapterPendingResponse()) return { reason: "adapter_pending_response", terminal: !approvalResolvedIdle };
46335
+ if (!approvalResolvedIdle && this.inApprovalResumeGrace()) {
46336
+ return { reason: "approval_resume_grace", terminal: false };
46337
+ }
46235
46338
  const partial = typeof this.adapter.getPartialResponse === "function" ? this.adapter.getPartialResponse() : "";
46236
46339
  if (typeof partial === "string" && partial.trim()) return { reason: "partial_response_pending", terminal: true };
46237
46340
  let parsed;
@@ -46393,6 +46496,24 @@ var CliProviderInstance = class _CliProviderInstance {
46393
46496
  isAutonomousMeshSession() {
46394
46497
  return this.isMeshWorkerSession() || !!this.settings.meshCoordinatorFor;
46395
46498
  }
46499
+ /**
46500
+ * FALSE-IDLE: are we inside the post-approval resume grace window? True when this
46501
+ * is an autonomous auto-approving mesh session AND the engine resolved a modal
46502
+ * (auto-approve / mesh_approve) within APPROVAL_RESUME_GRACE_MS. This is the single
46503
+ * "auto-approve recency" judgment shared by Fix 1 (the SETTLE-VALLEY completion
46504
+ * hold below) and Fix 2 (the FSM-level applyIdle hysteresis in cli-state-engine).
46505
+ *
46506
+ * Scoped to autonomous auto-approving sessions so a foreground/attended session,
46507
+ * or a session with auto-approve off (whose approvals a human answers), is never
46508
+ * held. The recency clock (adapter.lastApprovalResolvedAt) is 0 until the first
46509
+ * resolveModal, so a plain turn that never saw an approval always returns false.
46510
+ */
46511
+ inApprovalResumeGrace(now = Date.now()) {
46512
+ if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return false;
46513
+ const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
46514
+ if (resolvedAt <= 0) return false;
46515
+ return now - resolvedAt < _CliProviderInstance.APPROVAL_RESUME_GRACE_MS;
46516
+ }
46396
46517
  /**
46397
46518
  * ARCH-REFACTOR R1: the taskId to attribute the CURRENTLY-completing turn to.
46398
46519
  * Prefers the per-turn binding (engine.currentTurnTaskId, set when the turn was
@@ -46704,7 +46825,14 @@ var CliProviderInstance = class _CliProviderInstance {
46704
46825
  this.autoApproveLastModalSeenAt = now;
46705
46826
  const modalKind = typeof modal?.kind === "string" ? modal.kind : "approval";
46706
46827
  if (modalKind !== "approval") {
46707
- return autoApproveActive;
46828
+ const modalText = `${String(modal?.title || "")}
46829
+ ${String(modal?.message || "")}
46830
+ ${buttons.join("\n")}`;
46831
+ const looksLikeSelectionPicker = /Select (?:a |an )?(?:model|mode|option)\b|Switch between/i.test(modalText);
46832
+ const looksLikeConsent = looksLikeActiveApprovalPromptText(modalText) || /Do you want to (?:proceed|create|make|edit|apply|run|delete|modify|allow)\b|allow all edits\b|don'?t ask again\b/i.test(modalText) || hasNegativeApprovalOption(buttons) || hasReliableApprovalAffirmative(buttons);
46833
+ if (looksLikeSelectionPicker && !looksLikeConsent) {
46834
+ return autoApproveActive;
46835
+ }
46708
46836
  }
46709
46837
  const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(buttons, this.provider);
46710
46838
  const hasReliableConsentAnchor = hasNegativeApprovalOption(buttons) || hasReliableApprovalAffirmative(buttons);
@@ -55189,7 +55317,7 @@ var meshCrudHandlers = {
55189
55317
  const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node update");
55190
55318
  if (ownerFailure) return ownerFailure;
55191
55319
  try {
55192
- const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
55320
+ const { updateNode: updateNode2, normalizeCapabilityTags: normalizeCapabilityTags2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
55193
55321
  const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
55194
55322
  if (Array.isArray(args?.providerPriority)) {
55195
55323
  const providerPriority = args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean);
@@ -55219,9 +55347,31 @@ var meshCrudHandlers = {
55219
55347
  patch.capabilities = args.capabilities.map((t) => typeof t === "string" ? t.trim() : "").filter(Boolean);
55220
55348
  }
55221
55349
  const node = updateNode2(meshId, nodeId, patch);
55222
- if (!node) return { success: false, error: "Mesh node not found" };
55223
- ctx.invalidateAggregateMeshStatus(meshId);
55224
- return { success: true, node };
55350
+ if (node) {
55351
+ ctx.invalidateAggregateMeshStatus(meshId);
55352
+ return { success: true, node };
55353
+ }
55354
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
55355
+ const mesh = meshRecord?.mesh;
55356
+ if (!mesh) return { success: false, error: "Mesh not found" };
55357
+ const inlineNode = Array.isArray(mesh.nodes) ? mesh.nodes.find((n) => meshNodeIdMatches(n, nodeId)) : void 0;
55358
+ if (!inlineNode) return { success: false, error: "Mesh node not found" };
55359
+ inlineNode.policy = {
55360
+ ...inlineNode.policy && typeof inlineNode.policy === "object" && !Array.isArray(inlineNode.policy) ? inlineNode.policy : {},
55361
+ ...patch.policy
55362
+ };
55363
+ if (Object.prototype.hasOwnProperty.call(patch, "systemPrompt")) {
55364
+ const sp = patch.systemPrompt;
55365
+ if (typeof sp === "string" && sp.trim()) inlineNode.systemPrompt = sp;
55366
+ else delete inlineNode.systemPrompt;
55367
+ }
55368
+ if (Object.prototype.hasOwnProperty.call(patch, "capabilities")) {
55369
+ const tags = normalizeCapabilityTags2(patch.capabilities);
55370
+ if (tags && tags.length) inlineNode.capabilities = tags;
55371
+ else delete inlineNode.capabilities;
55372
+ }
55373
+ ctx.updateInlineMeshNode(meshId, mesh, inlineNode);
55374
+ return { success: true, node: inlineNode };
55225
55375
  } catch (e) {
55226
55376
  return { success: false, error: e.message };
55227
55377
  }