@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.
@@ -48,6 +48,16 @@ export interface CliStateEngineCallbacks {
48
48
  onStatusChange(): void;
49
49
  onApplyParsedSession(session: ParsedSession): void;
50
50
  onTurnCompleted(): void;
51
+ /**
52
+ * FALSE-IDLE (Fix 2): true when the owning session is inside the post-approval
53
+ * resume grace — an autonomous auto-approving mesh session that resolved a modal
54
+ * within the resume-grace window. The engine cannot decide this on its own (it has
55
+ * no mesh/auto-approve awareness); the instance answers using the SAME
56
+ * `inApprovalResumeGrace` judgment Fix 1 uses, so the two fixes stay in lockstep.
57
+ * Optional: absent ⇒ treated as false (no hysteresis) so any non-instance embedder
58
+ * keeps the pre-fix behavior.
59
+ */
60
+ isInApprovalResumeGrace?(): boolean;
51
61
  }
52
62
  export declare class CliStateEngine {
53
63
  private readonly provider;
@@ -113,6 +123,8 @@ export declare class CliStateEngine {
113
123
  pendingScriptStatusSince: number;
114
124
  private pendingScriptStatusTimer;
115
125
  private idleFinishCandidate;
126
+ private approvalResumeDeferSince;
127
+ private approvalResumeDeferEpoch;
116
128
  /**
117
129
  * `finishResponse` produces the `generating → idle` transition that
118
130
  * coordinators interpret as "task complete". Some providers (antigravity-
@@ -201,6 +213,20 @@ export declare class CliStateEngine {
201
213
  private applyError;
202
214
  private maybeScheduleProviderErrorRetry;
203
215
  private applyIdle;
216
+ /**
217
+ * FALSE-IDLE (Fix 2): should applyIdle suppress the idle/finish for the current
218
+ * turn because we are inside the post-approval resume grace?
219
+ *
220
+ * True only when: (a) the owning instance reports it is an autonomous auto-approving
221
+ * mesh session that resolved a modal within the resume-grace window
222
+ * (isInApprovalResumeGrace callback — the SAME judgment Fix 1 uses), AND (b) the defer
223
+ * for THIS response epoch has not yet exceeded APPROVAL_RESUME_IDLE_DEFER_CAP_MS.
224
+ * The cap guarantees no infinite defer: a turn that genuinely ended right after an
225
+ * approval and stays silent past the cap stops being suppressed and finishes normally.
226
+ * The per-epoch anchor means a fresh turn/response restarts the clock.
227
+ */
228
+ private shouldDeferIdleForApprovalResume;
229
+ private clearApprovalResumeDefer;
204
230
  finishResponse(): void;
205
231
  private scheduleIdleFinish;
206
232
  private cancelPendingIdleFinish;
@@ -32,6 +32,7 @@ export declare class ProviderCliAdapter implements CliAdapter {
32
32
  private ptyProcess;
33
33
  private transportFactory;
34
34
  private onStatusChange;
35
+ private inApprovalResumeGraceProbe;
35
36
  readonly engine: CliStateEngine;
36
37
  private responseBuffer;
37
38
  private recentOutputBuffer;
@@ -137,6 +138,7 @@ export declare class ProviderCliAdapter implements CliAdapter {
137
138
  updateRuntimeSettings(settings: Record<string, any>): void;
138
139
  setServerConn(serverConn: any): void;
139
140
  setOnStatusChange(callback: () => void): void;
141
+ setInApprovalResumeGraceProbe(probe: () => boolean): void;
140
142
  setOnPtyData(callback: (data: string) => void): void;
141
143
  private flushPendingOutputParse;
142
144
  spawn(): Promise<void>;
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type { LocalMeshEntry, LocalMeshNodeEntry, RepoMeshPolicy, RepoMeshNodePolicy, RepoMeshNodeCapabilities, RepoMeshCoordinatorConfig, RepoMeshHostMetadata, RepoMeshDaemonRole } from '../repo-mesh-types.js';
9
9
  import type { MagiKindPanelMap, MagiSlot, DifficultyBrainMap } from '@adhdev/mesh-shared';
10
+ export declare function normalizeCapabilityTags(value: unknown): string[] | undefined;
10
11
  /**
11
12
  * Normalize a Git remote URL into a stable identity string.
12
13
  * e.g. "git@github.com:user/repo.git" → "github.com/user/repo"
package/dist/index.js CHANGED
@@ -414,10 +414,10 @@ function readInjected(value) {
414
414
  }
415
415
  function getDaemonBuildInfo() {
416
416
  if (cached) return cached;
417
- const commit = readInjected(true ? "cfa673de50d6ede347cf424b9cab1e94081eadb2" : void 0) ?? "unknown";
418
- const commitShort = readInjected(true ? "cfa673de" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
419
- const version = readInjected(true ? "0.9.82-rc.490" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
420
- const builtAt = readInjected(true ? "2026-07-10T05:30:12.581Z" : void 0);
417
+ const commit = readInjected(true ? "d3ef86c2b3332b1ce289eb8d4193c7c945d39401" : void 0) ?? "unknown";
418
+ const commitShort = readInjected(true ? "d3ef86c2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
419
+ const version = readInjected(true ? "0.9.82-rc.492" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
420
+ const builtAt = readInjected(true ? "2026-07-10T07:51:20.549Z" : void 0);
421
421
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
422
422
  return cached;
423
423
  }
@@ -3043,6 +3043,7 @@ __export(mesh_config_exports, {
3043
3043
  listMagiKindPanels: () => listMagiKindPanels,
3044
3044
  listMeshes: () => listMeshes,
3045
3045
  markMeshHostPairingJoined: () => markMeshHostPairingJoined,
3046
+ normalizeCapabilityTags: () => normalizeCapabilityTags,
3046
3047
  normalizeMagiSlots: () => normalizeMagiSlots,
3047
3048
  normalizeRepoIdentity: () => normalizeRepoIdentity,
3048
3049
  removeMagiKindPanel: () => removeMagiKindPanel,
@@ -24500,7 +24501,7 @@ var init_provider_cli_parse = __esm({
24500
24501
  });
24501
24502
 
24502
24503
  // src/cli-adapters/cli-state-engine.ts
24503
- var SCRIPT_STATUS_DEBOUNCE_MS, MAX_FINISH_RETRIES, FINISH_RETRY_DELAY_MS, MAX_TRACE_ENTRIES, APPROVAL_EXIT_TIMEOUT_MS, IDLE_CONFIRMATION_GRACE_MS, CliStateEngine;
24504
+ 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;
24504
24505
  var init_cli_state_engine = __esm({
24505
24506
  "src/cli-adapters/cli-state-engine.ts"() {
24506
24507
  "use strict";
@@ -24513,6 +24514,7 @@ var init_cli_state_engine = __esm({
24513
24514
  MAX_TRACE_ENTRIES = 250;
24514
24515
  APPROVAL_EXIT_TIMEOUT_MS = 6e4;
24515
24516
  IDLE_CONFIRMATION_GRACE_MS = 2e3;
24517
+ APPROVAL_RESUME_IDLE_DEFER_CAP_MS = 18e3;
24516
24518
  CliStateEngine = class {
24517
24519
  constructor(provider, runner, transport, callbacks, timeouts) {
24518
24520
  this.provider = provider;
@@ -24602,6 +24604,12 @@ var init_cli_state_engine = __esm({
24602
24604
  pendingScriptStatusTimer = null;
24603
24605
  // ── Idle candidate ───────────────────────────────
24604
24606
  idleFinishCandidate = null;
24607
+ // FALSE-IDLE (Fix 2): wall-clock when the current post-approval resume-grace idle
24608
+ // defer began, scoped to a responseEpoch. Zero when not deferring. Bounds the defer
24609
+ // to APPROVAL_RESUME_IDLE_DEFER_CAP_MS so a turn that genuinely ended right after an
24610
+ // approval eventually finishes. Reset whenever a new turn/response starts or completes.
24611
+ approvalResumeDeferSince = 0;
24612
+ approvalResumeDeferEpoch = -1;
24605
24613
  // ── Idle confirmation grace ──────────────────────
24606
24614
  /**
24607
24615
  * `finishResponse` produces the `generating → idle` transition that
@@ -24815,6 +24823,8 @@ var init_cli_state_engine = __esm({
24815
24823
  this.activeModal = null;
24816
24824
  this.pendingScriptStatus = null;
24817
24825
  this.pendingScriptStatusSince = 0;
24826
+ this.approvalResumeDeferSince = 0;
24827
+ this.approvalResumeDeferEpoch = -1;
24818
24828
  }
24819
24829
  clearIdleFinishCandidate(reason) {
24820
24830
  if (!this.idleFinishCandidate) return;
@@ -25236,6 +25246,14 @@ var init_cli_state_engine = __esm({
25236
25246
  const idleReady = !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleFinishConfirmMs;
25237
25247
  const candidate = this.idleFinishCandidate;
25238
25248
  const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === snap.lastOutputAt && candidate.lastScreenChangeAt === snap.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= idleFinishConfirmMs;
25249
+ if (this.shouldDeferIdleForApprovalResume(now)) {
25250
+ this.clearIdleFinishCandidate("approval_resume_grace_defer");
25251
+ if (this.idleTimeout) clearTimeout(this.idleTimeout);
25252
+ this.idleTimeout = setTimeout(() => {
25253
+ if (this.isWaitingForResponse) this.evaluateSettled(this.transport.getSnapshot());
25254
+ }, this.timeouts.idleFinish);
25255
+ return;
25256
+ }
25239
25257
  if (idleReady && candidateQuiet) {
25240
25258
  this.clearIdleFinishCandidate("finish_response");
25241
25259
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
@@ -25253,6 +25271,12 @@ var init_cli_state_engine = __esm({
25253
25271
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
25254
25272
  this.idleTimeout = setTimeout(() => {
25255
25273
  if (this.isWaitingForResponse && !this.hasActionableApproval()) {
25274
+ if (this.shouldDeferIdleForApprovalResume(Date.now())) {
25275
+ this.idleTimeout = setTimeout(() => {
25276
+ if (this.isWaitingForResponse) this.evaluateSettled(this.transport.getSnapshot());
25277
+ }, this.timeouts.idleFinish);
25278
+ return;
25279
+ }
25256
25280
  if (this.shouldDeferIdleTimeoutFinish()) return;
25257
25281
  const parsed = this.runParseSession(this.transport.getSnapshot());
25258
25282
  if (this.shouldDeferFinishForTranscript(parsed)) {
@@ -25264,6 +25288,47 @@ var init_cli_state_engine = __esm({
25264
25288
  }
25265
25289
  }, this.timeouts.idleFinish);
25266
25290
  }
25291
+ /**
25292
+ * FALSE-IDLE (Fix 2): should applyIdle suppress the idle/finish for the current
25293
+ * turn because we are inside the post-approval resume grace?
25294
+ *
25295
+ * True only when: (a) the owning instance reports it is an autonomous auto-approving
25296
+ * mesh session that resolved a modal within the resume-grace window
25297
+ * (isInApprovalResumeGrace callback — the SAME judgment Fix 1 uses), AND (b) the defer
25298
+ * for THIS response epoch has not yet exceeded APPROVAL_RESUME_IDLE_DEFER_CAP_MS.
25299
+ * The cap guarantees no infinite defer: a turn that genuinely ended right after an
25300
+ * approval and stays silent past the cap stops being suppressed and finishes normally.
25301
+ * The per-epoch anchor means a fresh turn/response restarts the clock.
25302
+ */
25303
+ shouldDeferIdleForApprovalResume(now) {
25304
+ if (typeof this.callbacks.isInApprovalResumeGrace !== "function") {
25305
+ this.clearApprovalResumeDefer();
25306
+ return false;
25307
+ }
25308
+ let inGrace = false;
25309
+ try {
25310
+ inGrace = this.callbacks.isInApprovalResumeGrace() === true;
25311
+ } catch {
25312
+ inGrace = false;
25313
+ }
25314
+ if (!inGrace) {
25315
+ this.clearApprovalResumeDefer();
25316
+ return false;
25317
+ }
25318
+ if (this.approvalResumeDeferEpoch !== this.responseEpoch || this.approvalResumeDeferSince === 0) {
25319
+ this.approvalResumeDeferEpoch = this.responseEpoch;
25320
+ this.approvalResumeDeferSince = now;
25321
+ return true;
25322
+ }
25323
+ if (now - this.approvalResumeDeferSince >= APPROVAL_RESUME_IDLE_DEFER_CAP_MS) {
25324
+ return false;
25325
+ }
25326
+ return true;
25327
+ }
25328
+ clearApprovalResumeDefer() {
25329
+ this.approvalResumeDeferSince = 0;
25330
+ this.approvalResumeDeferEpoch = -1;
25331
+ }
25267
25332
  finishResponse() {
25268
25333
  if (this.submitPendingUntil > Date.now()) return;
25269
25334
  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
  }
@@ -45617,6 +45692,28 @@ var CliProviderInstance = class _CliProviderInstance {
45617
45692
  * the nudge was NOT deferred) and leaked to the coordinator.
45618
45693
  */
45619
45694
  static AUTO_APPROVE_MASK_STALL_MS = 10500;
45695
+ /**
45696
+ * FALSE-IDLE (inter-approval quiet valley): grace window after an auto-approve
45697
+ * (or mesh_approve) RESOLVES a modal during which a subsequent generating→idle
45698
+ * quiet valley must NOT be treated as turn completion.
45699
+ *
45700
+ * The RCA: auto-approve resolves a modal → the agent resumes the same turn →
45701
+ * between resolving that approval and preparing the next tool/approval the agent
45702
+ * falls briefly silent. The FSM sees idle + a recorded mid-turn assistant bubble
45703
+ * and fires an early agent:generating_completed even though the turn is still in
45704
+ * flight. Live evidence showed the same session resuming waiting_approval ~13s
45705
+ * after a "clean" completion emit.
45706
+ *
45707
+ * The window must be comfortably larger than the observed resume gap (~13s) so
45708
+ * the valley is bridged, but not so large that a turn that genuinely ended right
45709
+ * after an approval is held for an annoying stretch. 18s clears 13s with margin
45710
+ * while capping the worst-case extra hold on a truly-finished turn at 18s (still
45711
+ * well under COMPLETED_FINALIZATION_MAX_WAIT_MS's 30s hard bound). The recency is
45712
+ * measured from the engine's lastApprovalResolvedAt, which is stamped ONLY by
45713
+ * resolveModal (auto-approve fire / dashboard / mesh_approve) — so a plain turn
45714
+ * with no approval never carries recency and is never held (no regression).
45715
+ */
45716
+ static APPROVAL_RESUME_GRACE_MS = 18e3;
45620
45717
  adapter;
45621
45718
  context = null;
45622
45719
  events = [];
@@ -45764,6 +45861,9 @@ var CliProviderInstance = class _CliProviderInstance {
45764
45861
  this.adapter.setOnStatusChange(() => {
45765
45862
  this.detectStatusTransition();
45766
45863
  });
45864
+ if (typeof this.adapter.setInApprovalResumeGraceProbe === "function") {
45865
+ this.adapter.setInApprovalResumeGraceProbe(() => this.inApprovalResumeGrace());
45866
+ }
45767
45867
  await this.adapter.spawn();
45768
45868
  await this.enforceFreshSessionLaunchIfNeeded();
45769
45869
  await this.applyInitialThinkingLevelViaControl();
@@ -46652,6 +46752,9 @@ var CliProviderInstance = class _CliProviderInstance {
46652
46752
  if (adapterAny?.isWaitingForResponse === true) return { reason: "adapter_waiting_for_response", terminal: !approvalResolvedIdle };
46653
46753
  if (adapterAny?.currentTurnScope) return { reason: "adapter_turn_scope_active", terminal: !approvalResolvedIdle };
46654
46754
  if (this.hasAdapterPendingResponse()) return { reason: "adapter_pending_response", terminal: !approvalResolvedIdle };
46755
+ if (!approvalResolvedIdle && this.inApprovalResumeGrace()) {
46756
+ return { reason: "approval_resume_grace", terminal: false };
46757
+ }
46655
46758
  const partial = typeof this.adapter.getPartialResponse === "function" ? this.adapter.getPartialResponse() : "";
46656
46759
  if (typeof partial === "string" && partial.trim()) return { reason: "partial_response_pending", terminal: true };
46657
46760
  let parsed;
@@ -46813,6 +46916,24 @@ var CliProviderInstance = class _CliProviderInstance {
46813
46916
  isAutonomousMeshSession() {
46814
46917
  return this.isMeshWorkerSession() || !!this.settings.meshCoordinatorFor;
46815
46918
  }
46919
+ /**
46920
+ * FALSE-IDLE: are we inside the post-approval resume grace window? True when this
46921
+ * is an autonomous auto-approving mesh session AND the engine resolved a modal
46922
+ * (auto-approve / mesh_approve) within APPROVAL_RESUME_GRACE_MS. This is the single
46923
+ * "auto-approve recency" judgment shared by Fix 1 (the SETTLE-VALLEY completion
46924
+ * hold below) and Fix 2 (the FSM-level applyIdle hysteresis in cli-state-engine).
46925
+ *
46926
+ * Scoped to autonomous auto-approving sessions so a foreground/attended session,
46927
+ * or a session with auto-approve off (whose approvals a human answers), is never
46928
+ * held. The recency clock (adapter.lastApprovalResolvedAt) is 0 until the first
46929
+ * resolveModal, so a plain turn that never saw an approval always returns false.
46930
+ */
46931
+ inApprovalResumeGrace(now = Date.now()) {
46932
+ if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return false;
46933
+ const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
46934
+ if (resolvedAt <= 0) return false;
46935
+ return now - resolvedAt < _CliProviderInstance.APPROVAL_RESUME_GRACE_MS;
46936
+ }
46816
46937
  /**
46817
46938
  * ARCH-REFACTOR R1: the taskId to attribute the CURRENTLY-completing turn to.
46818
46939
  * Prefers the per-turn binding (engine.currentTurnTaskId, set when the turn was
@@ -47124,7 +47245,14 @@ var CliProviderInstance = class _CliProviderInstance {
47124
47245
  this.autoApproveLastModalSeenAt = now;
47125
47246
  const modalKind = typeof modal?.kind === "string" ? modal.kind : "approval";
47126
47247
  if (modalKind !== "approval") {
47127
- return autoApproveActive;
47248
+ const modalText = `${String(modal?.title || "")}
47249
+ ${String(modal?.message || "")}
47250
+ ${buttons.join("\n")}`;
47251
+ const looksLikeSelectionPicker = /Select (?:a |an )?(?:model|mode|option)\b|Switch between/i.test(modalText);
47252
+ 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);
47253
+ if (looksLikeSelectionPicker && !looksLikeConsent) {
47254
+ return autoApproveActive;
47255
+ }
47128
47256
  }
47129
47257
  const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(buttons, this.provider);
47130
47258
  const hasReliableConsentAnchor = hasNegativeApprovalOption(buttons) || hasReliableApprovalAffirmative(buttons);
@@ -55604,7 +55732,7 @@ var meshCrudHandlers = {
55604
55732
  const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node update");
55605
55733
  if (ownerFailure) return ownerFailure;
55606
55734
  try {
55607
- const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
55735
+ const { updateNode: updateNode2, normalizeCapabilityTags: normalizeCapabilityTags2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
55608
55736
  const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
55609
55737
  if (Array.isArray(args?.providerPriority)) {
55610
55738
  const providerPriority = args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean);
@@ -55634,9 +55762,31 @@ var meshCrudHandlers = {
55634
55762
  patch.capabilities = args.capabilities.map((t) => typeof t === "string" ? t.trim() : "").filter(Boolean);
55635
55763
  }
55636
55764
  const node = updateNode2(meshId, nodeId, patch);
55637
- if (!node) return { success: false, error: "Mesh node not found" };
55638
- ctx.invalidateAggregateMeshStatus(meshId);
55639
- return { success: true, node };
55765
+ if (node) {
55766
+ ctx.invalidateAggregateMeshStatus(meshId);
55767
+ return { success: true, node };
55768
+ }
55769
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
55770
+ const mesh = meshRecord?.mesh;
55771
+ if (!mesh) return { success: false, error: "Mesh not found" };
55772
+ const inlineNode = Array.isArray(mesh.nodes) ? mesh.nodes.find((n) => meshNodeIdMatches(n, nodeId)) : void 0;
55773
+ if (!inlineNode) return { success: false, error: "Mesh node not found" };
55774
+ inlineNode.policy = {
55775
+ ...inlineNode.policy && typeof inlineNode.policy === "object" && !Array.isArray(inlineNode.policy) ? inlineNode.policy : {},
55776
+ ...patch.policy
55777
+ };
55778
+ if (Object.prototype.hasOwnProperty.call(patch, "systemPrompt")) {
55779
+ const sp = patch.systemPrompt;
55780
+ if (typeof sp === "string" && sp.trim()) inlineNode.systemPrompt = sp;
55781
+ else delete inlineNode.systemPrompt;
55782
+ }
55783
+ if (Object.prototype.hasOwnProperty.call(patch, "capabilities")) {
55784
+ const tags = normalizeCapabilityTags2(patch.capabilities);
55785
+ if (tags && tags.length) inlineNode.capabilities = tags;
55786
+ else delete inlineNode.capabilities;
55787
+ }
55788
+ ctx.updateInlineMeshNode(meshId, mesh, inlineNode);
55789
+ return { success: true, node: inlineNode };
55640
55790
  } catch (e) {
55641
55791
  return { success: false, error: e.message };
55642
55792
  }