@adhdev/daemon-core 0.9.82-rc.168 → 0.9.82-rc.169

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.
@@ -4,6 +4,10 @@ export declare function pickApprovalButton(buttons: string[] | null | undefined,
4
4
  index: number;
5
5
  label: string;
6
6
  };
7
+ export declare function pickAutoApprovalButton(buttons: string[] | null | undefined): {
8
+ index: number;
9
+ label: string;
10
+ };
7
11
  export declare function formatAutoApprovalMessage(modalMessage?: string, buttonLabel?: string): string;
8
12
  /**
9
13
  * Returns true when the given text (e.g. last assistant message content, or
@@ -245,6 +245,10 @@ export declare const SCHEMA: {
245
245
  readonly minimum: 1;
246
246
  readonly default: 2;
247
247
  };
248
+ readonly continuation_lines: {
249
+ readonly type: "boolean";
250
+ readonly default: false;
251
+ };
248
252
  };
249
253
  };
250
254
  };
@@ -23,6 +23,7 @@ export interface ModalButtonsRule {
23
23
  flags?: string;
24
24
  key_for_index: string;
25
25
  min_count?: number;
26
+ continuation_lines?: boolean;
26
27
  }
27
28
  export interface SpecState {
28
29
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.168",
3
+ "version": "0.9.82-rc.169",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,7 +19,7 @@ import type { SessionRegistry } from '../sessions/registry.js';
19
19
  import { reconcileIdeRuntimeSessions } from '../sessions/reconcile.js';
20
20
  import { LOG } from '../logging/logger.js';
21
21
  import type { AgentStreamState } from './types.js';
22
- import { formatAutoApprovalMessage, pickApprovalButton } from '../providers/approval-utils.js';
22
+ import { formatAutoApprovalMessage, pickAutoApprovalButton } from '../providers/approval-utils.js';
23
23
  import type { ProviderModule } from '../providers/contracts.js';
24
24
  import { buildRuntimeSystemChatMessage } from '../providers/chat-message-normalization.js';
25
25
 
@@ -210,8 +210,7 @@ export class AgentStreamPoller {
210
210
  if (stream?.status === 'waiting_approval') {
211
211
  const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
212
212
  if (autoApprove && resolvedActiveSessionId) {
213
- const provider = providerLoader.getMeta(stream.agentType);
214
- const { label: buttonLabel } = pickApprovalButton(stream.activeModal?.buttons, provider);
213
+ const { label: buttonLabel } = pickAutoApprovalButton(stream.activeModal?.buttons);
215
214
  const approved = await agentStreamManager.resolveSessionAction(cdp, resolvedActiveSessionId, 'approve', buttonLabel);
216
215
  if (approved) {
217
216
  const effectId = [
@@ -4,4 +4,8 @@ export declare function pickApprovalButton(buttons: string[] | null | undefined,
4
4
  index: number;
5
5
  label: string;
6
6
  };
7
+ export declare function pickAutoApprovalButton(buttons: string[] | null | undefined): {
8
+ index: number;
9
+ label: string;
10
+ };
7
11
  export declare function formatAutoApprovalMessage(modalMessage?: string, buttonLabel?: string): string;
@@ -66,6 +66,14 @@ export function pickApprovalButton(
66
66
  return { index: -1, label: '' };
67
67
  }
68
68
 
69
+ export function pickAutoApprovalButton(
70
+ buttons: string[] | null | undefined,
71
+ ): { index: number; label: string } {
72
+ const labels = (buttons || []).map((button) => String(button || '').trim());
73
+ const index = labels.findIndex(Boolean);
74
+ return index >= 0 ? { index, label: labels[index] } : { index: -1, label: '' };
75
+ }
76
+
69
77
  export function formatAutoApprovalMessage(modalMessage?: string, buttonLabel?: string): string {
70
78
  const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ''}`];
71
79
  const cleanMessage = String(modalMessage || '').trim();
@@ -22,7 +22,7 @@ import { ChatHistoryWriter, isNativeSourceCanonicalHistory, materializeProviderN
22
22
  import { LOG } from '../logging/logger.js';
23
23
  import type { ChatMessage } from '../types.js';
24
24
  import { buildPersistedProviderEffectMessage, normalizeProviderEffects } from './control-effects.js';
25
- import { formatAutoApprovalMessage, pickApprovalButton, looksLikeActiveApprovalPromptText } from './approval-utils.js';
25
+ import { formatAutoApprovalMessage, pickApprovalButton, pickAutoApprovalButton, looksLikeActiveApprovalPromptText } from './approval-utils.js';
26
26
  import { getCliScriptCommand, parseCliScriptResult } from './cli-script-results.js';
27
27
  import { mergeProviderPatchState, resolveProviderStateSurface } from './provider-patch-state.js';
28
28
  import { normalizeProviderSessionId } from './provider-session-id.js';
@@ -1092,9 +1092,9 @@ export class CliProviderInstance implements ProviderInstance {
1092
1092
  if (!modal || buttons.length === 0) {
1093
1093
  return autoApproveActive;
1094
1094
  }
1095
- const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(buttons, this.provider);
1095
+ const { index: buttonIndex, label: buttonLabel } = pickAutoApprovalButton(buttons);
1096
1096
  if (buttonIndex < 0) {
1097
- // No positive button matched — don't pick a random index, just
1097
+ // No concrete button matched — don't pick a random index, just
1098
1098
  // surface the modal so the user can decide.
1099
1099
  return autoApproveActive;
1100
1100
  }
@@ -20,7 +20,7 @@ import { LOG } from '../logging/logger.js';
20
20
  import { buildPersistedProviderEffectMessage, normalizeProviderEffects } from './control-effects.js';
21
21
  import { validateReadChatResultPayload } from './read-chat-contract.js';
22
22
  import type { ChatMessage } from '../types.js';
23
- import { formatAutoApprovalMessage, pickApprovalButton } from './approval-utils.js';
23
+ import { formatAutoApprovalMessage, pickAutoApprovalButton } from './approval-utils.js';
24
24
  import { mergeProviderPatchState, resolveProviderStateSurface } from './provider-patch-state.js';
25
25
  import { buildChatMessage, buildRuntimeSystemChatMessage, normalizeChatMessages, extractFinalSummaryFromMessages } from './chat-message-normalization.js';
26
26
  import { getProviderSessionCapabilities, IDE_PROVIDER_SESSION_CAPABILITIES_BASE } from './open-panel-support.js';
@@ -708,7 +708,7 @@ export class IdeProviderInstance implements ProviderInstance {
708
708
 
709
709
  this.autoApproveBusy = true;
710
710
  try {
711
- const { label: targetButton } = pickApprovalButton(_chatData?.activeModal?.buttons, this.provider);
711
+ const { label: targetButton } = pickAutoApprovalButton(_chatData?.activeModal?.buttons);
712
712
 
713
713
  const script = scriptFn({ action: 'approve', button: targetButton, buttonText: targetButton });
714
714
  if (!script) return;
@@ -125,6 +125,11 @@ function compilePattern(ref: { pattern: string; flags?: string }): RegExp {
125
125
  return new RegExp(ref.pattern, flags.includes('g') ? flags : flags + 'g');
126
126
  }
127
127
 
128
+ function compileLinePattern(ref: { pattern: string; flags?: string }): RegExp {
129
+ const flags = (ref.flags ?? 'm').replace(/g/g, '');
130
+ return new RegExp(ref.pattern, flags);
131
+ }
132
+
128
133
  // ────────────────────────────────────────────────────────────────────────────
129
134
  // State matching
130
135
  // ────────────────────────────────────────────────────────────────────────────
@@ -162,16 +167,41 @@ function extractModal(
162
167
  ): ModalSnapshot | null {
163
168
  if (!state.modal_buttons) return null;
164
169
  const hay = sectionText(sections, state.modal_buttons.section, fullScreen);
165
- const re = compilePattern(state.modal_buttons);
166
170
  const buttons: { index: number; label: string; key: string }[] = [];
167
- let m: RegExpExecArray | null;
168
- while ((m = re.exec(hay)) !== null) {
169
- const idx = Number(m[1]);
170
- const label = String(m[2] ?? '').trim();
171
- if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
172
- if (buttons.some(b => b.index === idx)) continue;
173
- const key = state.modal_buttons.key_for_index.replace(/\{index\}/g, String(idx));
174
- buttons.push({ index: idx, label, key });
171
+ if (state.modal_buttons.continuation_lines) {
172
+ const re = compileLinePattern(state.modal_buttons);
173
+ const lines = hay.split('\n');
174
+ for (let i = 0; i < lines.length; i += 1) {
175
+ const m = re.exec(lines[i]);
176
+ if (!m) continue;
177
+ const idx = Number(m[1]);
178
+ let label = String(m[2] ?? '').trim();
179
+ if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
180
+ let j = i + 1;
181
+ while (j < lines.length) {
182
+ const next = lines[j];
183
+ if (!next.trim()) break;
184
+ if (re.test(next)) break;
185
+ if (!/^\s+/.test(next)) break;
186
+ label += ' ' + next.trim();
187
+ j += 1;
188
+ }
189
+ if (buttons.some(b => b.index === idx)) continue;
190
+ const key = state.modal_buttons.key_for_index.replace(/\{index\}/g, String(idx));
191
+ buttons.push({ index: idx, label, key });
192
+ i = j - 1;
193
+ }
194
+ } else {
195
+ const re = compilePattern(state.modal_buttons);
196
+ let m: RegExpExecArray | null;
197
+ while ((m = re.exec(hay)) !== null) {
198
+ const idx = Number(m[1]);
199
+ const label = String(m[2] ?? '').trim();
200
+ if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
201
+ if (buttons.some(b => b.index === idx)) continue;
202
+ const key = state.modal_buttons.key_for_index.replace(/\{index\}/g, String(idx));
203
+ buttons.push({ index: idx, label, key });
204
+ }
175
205
  }
176
206
  buttons.sort((a, b) => a.index - b.index);
177
207
  const minCount = state.modal_buttons.min_count ?? 2;
@@ -269,6 +269,10 @@ export const SCHEMA = {
269
269
  "type": "integer",
270
270
  "minimum": 1,
271
271
  "default": 2
272
+ },
273
+ "continuation_lines": {
274
+ "type": "boolean",
275
+ "default": false
272
276
  }
273
277
  }
274
278
  }
@@ -122,7 +122,8 @@
122
122
  "pattern": { "type": "string", "minLength": 1 },
123
123
  "flags": { "type": "string" },
124
124
  "key_for_index": { "type": "string", "minLength": 1 },
125
- "min_count": { "type": "integer", "minimum": 1, "default": 2 }
125
+ "min_count": { "type": "integer", "minimum": 1, "default": 2 },
126
+ "continuation_lines": { "type": "boolean", "default": false }
126
127
  }
127
128
  }
128
129
  }
@@ -33,6 +33,7 @@ export interface ModalButtonsRule {
33
33
  flags?: string;
34
34
  key_for_index: string;
35
35
  min_count?: number;
36
+ continuation_lines?: boolean;
36
37
  }
37
38
 
38
39
  export interface SpecState {