adhdev 0.8.29 → 0.8.30

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
@@ -3440,6 +3440,59 @@ ${effect.notification.body || ""}`.trim();
3440
3440
  }
3441
3441
  });
3442
3442
 
3443
+ // ../../oss/packages/daemon-core/src/providers/approval-utils.ts
3444
+ function normalizeApprovalLabel(value) {
3445
+ return String(value || "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
3446
+ }
3447
+ function getApprovalPositiveHints(provider) {
3448
+ const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
3449
+ return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
3450
+ }
3451
+ function pickApprovalButton(buttons, provider) {
3452
+ const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
3453
+ if (labels.length === 0) {
3454
+ return { index: 0, label: "Approve" };
3455
+ }
3456
+ const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
3457
+ const hints = getApprovalPositiveHints(provider);
3458
+ for (const hint of hints) {
3459
+ const exactIndex = normalizedButtons.findIndex((label) => label === hint);
3460
+ if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
3461
+ const prefixIndex = normalizedButtons.findIndex((label) => label.startsWith(hint));
3462
+ if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
3463
+ const includeIndex = normalizedButtons.findIndex((label) => label.includes(hint));
3464
+ if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
3465
+ }
3466
+ return { index: 0, label: labels[0] };
3467
+ }
3468
+ function formatAutoApprovalMessage(modalMessage, buttonLabel) {
3469
+ const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
3470
+ const cleanMessage = String(modalMessage || "").trim();
3471
+ if (cleanMessage) lines.push(cleanMessage);
3472
+ return lines.join("\n");
3473
+ }
3474
+ var DEFAULT_APPROVAL_POSITIVE_HINTS;
3475
+ var init_approval_utils = __esm({
3476
+ "../../oss/packages/daemon-core/src/providers/approval-utils.ts"() {
3477
+ "use strict";
3478
+ DEFAULT_APPROVAL_POSITIVE_HINTS = [
3479
+ "run",
3480
+ "approve",
3481
+ "accept",
3482
+ "allow once",
3483
+ "always allow",
3484
+ "allow",
3485
+ "yes",
3486
+ "proceed",
3487
+ "continue",
3488
+ "confirm",
3489
+ "save",
3490
+ "ok",
3491
+ "trust"
3492
+ ];
3493
+ }
3494
+ });
3495
+
3443
3496
  // ../../oss/packages/daemon-core/src/providers/ide-provider-instance.ts
3444
3497
  var crypto2, IdeProviderInstance;
3445
3498
  var init_ide_provider_instance = __esm({
@@ -3451,6 +3504,7 @@ var init_ide_provider_instance = __esm({
3451
3504
  init_chat_history();
3452
3505
  init_logger();
3453
3506
  init_control_effects();
3507
+ init_approval_utils();
3454
3508
  IdeProviderInstance = class {
3455
3509
  type;
3456
3510
  category = "ide";
@@ -3517,6 +3571,8 @@ var init_ide_provider_instance = __esm({
3517
3571
  }
3518
3572
  getState() {
3519
3573
  const cdp = this.context?.cdp;
3574
+ const autoApproveActive = (this.currentStatus === "waiting_approval" || this.cachedChat?.status === "waiting_approval") && this.canAutoApprove();
3575
+ const visibleStatus = autoApproveActive ? "generating" : this.currentStatus;
3520
3576
  const extensionStates = [];
3521
3577
  for (const ext of this.extensions.values()) {
3522
3578
  extensionStates.push(ext.getState());
@@ -3525,13 +3581,13 @@ var init_ide_provider_instance = __esm({
3525
3581
  type: this.type,
3526
3582
  name: this.provider.name,
3527
3583
  category: "ide",
3528
- status: this.currentStatus,
3584
+ status: visibleStatus,
3529
3585
  activeChat: this.cachedChat ? {
3530
3586
  id: this.cachedChat.id || "active_session",
3531
3587
  title: this.cachedChat.title || this.type,
3532
- status: this.cachedChat.status || this.currentStatus,
3588
+ status: autoApproveActive && this.cachedChat.status === "waiting_approval" ? "generating" : this.cachedChat.status || visibleStatus,
3533
3589
  messages: this.mergeConversationMessages(this.cachedChat.messages || []),
3534
- activeModal: this.cachedChat.activeModal || null,
3590
+ activeModal: autoApproveActive ? null : this.cachedChat.activeModal || null,
3535
3591
  inputContent: this.cachedChat.inputContent || ""
3536
3592
  } : null,
3537
3593
  workspace: this.workspace || null,
@@ -3750,7 +3806,9 @@ var init_ide_provider_instance = __esm({
3750
3806
  const chatStatus = chatData?.status;
3751
3807
  if (!chatStatus) return;
3752
3808
  const agentKey = `${this.type}:native`;
3753
- const agentStatus = chatStatus === "streaming" || chatStatus === "generating" ? "generating" : chatStatus === "waiting_approval" ? "waiting_approval" : "idle";
3809
+ const rawAgentStatus = chatStatus === "streaming" || chatStatus === "generating" ? "generating" : chatStatus === "waiting_approval" ? "waiting_approval" : "idle";
3810
+ const autoApproveActive = rawAgentStatus === "waiting_approval" && this.canAutoApprove();
3811
+ const agentStatus = autoApproveActive ? "generating" : rawAgentStatus;
3754
3812
  const lastMsg = Array.isArray(chatData?.messages) && chatData.messages.length > 0 ? chatData.messages[chatData.messages.length - 1] : null;
3755
3813
  const progressFingerprint = agentStatus === "generating" ? `${lastMsg?.role || ""}:${typeof lastMsg?.content === "string" ? lastMsg.content : JSON.stringify(lastMsg?.content || "")}`.slice(-2e3) : void 0;
3756
3814
  this.currentStatus = agentStatus;
@@ -3782,7 +3840,7 @@ var init_ide_provider_instance = __esm({
3782
3840
  this.applyProviderResponse(chatData, {
3783
3841
  phase: agentStatus === "idle" && (lastStatus === "generating" || lastStatus === "waiting_approval") ? "turn_completed" : "immediate"
3784
3842
  });
3785
- if (agentStatus === "waiting_approval" && this.settings.autoApprove && !this.autoApproveBusy) {
3843
+ if (rawAgentStatus === "waiting_approval" && autoApproveActive && !this.autoApproveBusy) {
3786
3844
  this.autoApproveViaScript(chatData);
3787
3845
  }
3788
3846
  const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
@@ -3933,6 +3991,9 @@ ${effect.notification.body || ""}`.trim();
3933
3991
  updateCdp(cdp) {
3934
3992
  if (this.context) this.context.cdp = cdp;
3935
3993
  }
3994
+ canAutoApprove() {
3995
+ return this.settings.autoApprove !== false && typeof this.provider.scripts?.resolveAction === "function" && !!this.context?.cdp?.isConnected;
3996
+ }
3936
3997
  // ─── Auto-approve via CDP script ────────────────────
3937
3998
  async autoApproveViaScript(_chatData) {
3938
3999
  const cdp = this.context?.cdp;
@@ -3944,17 +4005,15 @@ ${effect.notification.body || ""}`.trim();
3944
4005
  }
3945
4006
  this.autoApproveBusy = true;
3946
4007
  try {
3947
- let targetButton = _chatData?.activeModal?.buttons?.[0] || "Run";
3948
- const buttons = _chatData?.activeModal?.buttons || [];
3949
- for (const b of buttons) {
3950
- const lower = String(b).toLowerCase().replace(/[^\w]/g, "");
3951
- if (/^(run|approve|accept|yes|allow|always|proceed|save)/.test(lower)) {
3952
- targetButton = b;
3953
- break;
3954
- }
3955
- }
4008
+ const { label: targetButton } = pickApprovalButton(_chatData?.activeModal?.buttons, this.provider);
3956
4009
  const script = scriptFn({ action: "approve", button: targetButton, buttonText: targetButton });
3957
4010
  if (!script) return;
4011
+ const now = Date.now();
4012
+ this.appendRuntimeSystemMessage(
4013
+ formatAutoApprovalMessage(_chatData?.activeModal?.message, targetButton),
4014
+ `auto_approval:${now}:${targetButton}`,
4015
+ now
4016
+ );
3958
4017
  LOG.info("IdeInstance", `[IdeInstance:${this.type}] autoApprove: executing resolveAction for "${targetButton}"`);
3959
4018
  let rawResult = await cdp.evaluate(script, 1e4);
3960
4019
  if (typeof rawResult === "string") {
@@ -3976,12 +4035,6 @@ ${effect.notification.body || ""}`.trim();
3976
4035
  LOG.warn("IdeInstance", `[IdeInstance:${this.type}] autoApprove: cdp.send() not available for coordinate click`);
3977
4036
  }
3978
4037
  }
3979
- this.pushEvent({
3980
- event: "agent:auto_approved",
3981
- chatTitle: _chatData?.title || this.provider.name,
3982
- timestamp: Date.now(),
3983
- ideType: this.type
3984
- });
3985
4038
  } catch (e) {
3986
4039
  LOG.warn("IdeInstance", `[IdeInstance:${this.type}] autoApprove error: ${e?.message}`);
3987
4040
  } finally {
@@ -9626,6 +9679,7 @@ var init_cli_provider_instance = __esm({
9626
9679
  init_chat_history();
9627
9680
  init_logger();
9628
9681
  init_control_effects();
9682
+ init_approval_utils();
9629
9683
  CachedDatabaseSync = null;
9630
9684
  CliProviderInstance = class {
9631
9685
  constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
@@ -9783,6 +9837,8 @@ var init_cli_provider_instance = __esm({
9783
9837
  getState() {
9784
9838
  const adapterStatus = this.adapter.getStatus();
9785
9839
  const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
9840
+ const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
9841
+ const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
9786
9842
  const parsedProviderSessionId = typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId.trim() : "";
9787
9843
  if (parsedProviderSessionId) {
9788
9844
  this.promoteProviderSessionId(parsedProviderSessionId);
@@ -9822,14 +9878,14 @@ var init_cli_provider_instance = __esm({
9822
9878
  type: this.type,
9823
9879
  name: this.provider.name,
9824
9880
  category: "cli",
9825
- status: adapterStatus.status,
9881
+ status: visibleStatus,
9826
9882
  mode: this.presentationMode,
9827
9883
  activeChat: {
9828
9884
  id: `${this.type}_${this.workingDir}`,
9829
9885
  title: parsedStatus?.title || dirName,
9830
- status: parsedStatus?.status || adapterStatus.status,
9886
+ status: autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
9831
9887
  messages: mergedMessages,
9832
- activeModal: parsedStatus?.activeModal ?? adapterStatus.activeModal,
9888
+ activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
9833
9889
  inputContent: ""
9834
9890
  },
9835
9891
  workspace: this.workingDir,
@@ -9893,7 +9949,16 @@ var init_cli_provider_instance = __esm({
9893
9949
  const now = Date.now();
9894
9950
  const adapterStatus = this.adapter.getStatus();
9895
9951
  const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
9896
- const newStatus = adapterStatus.status;
9952
+ const rawStatus = adapterStatus.status;
9953
+ const autoApproveActive = rawStatus === "waiting_approval" && this.shouldAutoApprove();
9954
+ if (autoApproveActive) {
9955
+ const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(adapterStatus.activeModal?.buttons, this.provider);
9956
+ this.recordAutoApproval(adapterStatus.activeModal?.message, buttonLabel, now);
9957
+ setTimeout(() => {
9958
+ this.adapter.resolveModal(buttonIndex);
9959
+ }, 0);
9960
+ }
9961
+ const newStatus = autoApproveActive ? "generating" : rawStatus;
9897
9962
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
9898
9963
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
9899
9964
  const partial2 = this.adapter.getPartialResponse();
@@ -10103,6 +10168,16 @@ ${effect.notification.body || ""}`.trim();
10103
10168
  get cliName() {
10104
10169
  return this.provider.name;
10105
10170
  }
10171
+ shouldAutoApprove() {
10172
+ return this.settings.autoApprove !== false;
10173
+ }
10174
+ recordAutoApproval(modalMessage, buttonLabel, now = Date.now()) {
10175
+ this.appendRuntimeSystemMessage(
10176
+ formatAutoApprovalMessage(modalMessage, buttonLabel),
10177
+ `auto_approval:${now}:${buttonLabel || "approve"}`,
10178
+ now
10179
+ );
10180
+ }
10106
10181
  recordApprovalSelection(buttonText) {
10107
10182
  const cleanButton = String(buttonText || "").trim();
10108
10183
  if (!cleanButton) return;
@@ -26988,8 +27063,10 @@ var init_acp_provider_instance = __esm({
26988
27063
  input: tc.rawInput ? typeof tc.rawInput === "string" ? tc.rawInput : JSON.stringify(tc.rawInput) : void 0
26989
27064
  });
26990
27065
  }
26991
- if (this.settings.autoApprove) {
26992
- this.log.info(`[${this.type}] Auto-approving: ${tc.title || tc.toolCallId}`);
27066
+ if (this.settings.autoApprove !== false) {
27067
+ const toolTitle = tc.title || tc.toolCallId || "tool call";
27068
+ this.log.info(`[${this.type}] Auto-approving: ${toolTitle}`);
27069
+ this.appendSystemMessage(`Auto-approved: ${toolTitle}`);
26993
27070
  const allowOption = params.options.find((o) => o.kind === "allow_once") || params.options.find((o) => o.kind === "allow_always");
26994
27071
  if (allowOption) {
26995
27072
  return { outcome: { outcome: "selected", optionId: allowOption.optionId } };
@@ -27441,6 +27518,18 @@ var init_acp_provider_instance = __esm({
27441
27518
  this.events.push(event);
27442
27519
  if (this.events.length > 50) this.events = this.events.slice(-50);
27443
27520
  }
27521
+ appendSystemMessage(content, timestamp = Date.now()) {
27522
+ const normalizedContent = String(content || "").trim();
27523
+ if (!normalizedContent) return;
27524
+ this.messages.push({
27525
+ role: "system",
27526
+ content: normalizedContent,
27527
+ timestamp
27528
+ });
27529
+ if (this.messages.length > 200) {
27530
+ this.messages = this.messages.slice(-100);
27531
+ }
27532
+ }
27444
27533
  flushEvents() {
27445
27534
  const events = [...this.events];
27446
27535
  this.events = [];
@@ -30784,7 +30873,7 @@ var init_provider_loader = __esm({
30784
30873
  */
30785
30874
  getSettingValue(type, key) {
30786
30875
  const schemaDef = this.getSettingsSchema(type)[key];
30787
- const defaultVal = schemaDef ? schemaDef.default : void 0;
30876
+ const defaultVal = schemaDef ? key === "autoApprove" && schemaDef.type === "boolean" ? true : schemaDef.default : void 0;
30788
30877
  try {
30789
30878
  const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
30790
30879
  const config2 = loadConfig2();
@@ -30843,13 +30932,32 @@ var init_provider_loader = __esm({
30843
30932
  getSettingsSchema(type) {
30844
30933
  const provider = this.providers.get(type);
30845
30934
  if (!provider) return {};
30846
- return {
30935
+ const result = {
30847
30936
  ...this.getSyntheticSettings(type, provider),
30848
30937
  ...provider.settings || {}
30849
30938
  };
30939
+ if (result.autoApprove?.type === "boolean") {
30940
+ result.autoApprove = {
30941
+ ...result.autoApprove,
30942
+ default: true,
30943
+ public: true,
30944
+ label: result.autoApprove.label || "Auto Approve",
30945
+ description: result.autoApprove.description || "Automatically approve actionable prompts without sending approval alerts."
30946
+ };
30947
+ }
30948
+ return result;
30850
30949
  }
30851
30950
  getSyntheticSettings(type, provider) {
30852
30951
  const result = {};
30952
+ if (!provider.settings?.autoApprove) {
30953
+ result.autoApprove = {
30954
+ type: "boolean",
30955
+ default: true,
30956
+ public: true,
30957
+ label: "Auto Approve",
30958
+ description: "Automatically approve actionable prompts without sending approval alerts."
30959
+ };
30960
+ }
30853
30961
  if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executablePath) {
30854
30962
  result.executablePath = {
30855
30963
  type: "string",
@@ -33296,6 +33404,7 @@ var init_poller = __esm({
33296
33404
  init_setup();
33297
33405
  init_reconcile();
33298
33406
  init_logger();
33407
+ init_approval_utils();
33299
33408
  AgentStreamPoller = class {
33300
33409
  deps;
33301
33410
  timer = null;
@@ -33426,7 +33535,43 @@ var init_poller = __esm({
33426
33535
  }
33427
33536
  try {
33428
33537
  await agentStreamManager.syncActiveSession(cdp, parentSessionId);
33429
- const stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
33538
+ let stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
33539
+ if (stream?.status === "waiting_approval") {
33540
+ const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
33541
+ if (autoApprove && resolvedActiveSessionId) {
33542
+ const provider = providerLoader.getMeta(stream.agentType);
33543
+ const { label: buttonLabel } = pickApprovalButton(stream.activeModal?.buttons, provider);
33544
+ const approved = await agentStreamManager.resolveSessionAction(cdp, resolvedActiveSessionId, "approve", buttonLabel);
33545
+ if (approved) {
33546
+ const effectId = [
33547
+ "auto_approval",
33548
+ resolvedActiveSessionId,
33549
+ String(stream.messages?.length || 0),
33550
+ buttonLabel,
33551
+ String(stream.activeModal?.message || "").trim()
33552
+ ].join(":");
33553
+ stream = {
33554
+ ...stream,
33555
+ status: "streaming",
33556
+ activeModal: void 0,
33557
+ effects: [
33558
+ ...stream.effects || [],
33559
+ {
33560
+ type: "message",
33561
+ id: effectId,
33562
+ persist: true,
33563
+ message: {
33564
+ role: "system",
33565
+ senderName: "System",
33566
+ kind: "system",
33567
+ content: formatAutoApprovalMessage(stream.activeModal?.message, buttonLabel)
33568
+ }
33569
+ }
33570
+ ]
33571
+ };
33572
+ }
33573
+ }
33574
+ }
33430
33575
  this.deps.onStreamsUpdated?.(ideType, stream ? [stream] : []);
33431
33576
  } catch {
33432
33577
  }
@@ -48330,7 +48475,7 @@ var init_adhdev_daemon = __esm({
48330
48475
  import_ws3 = require("ws");
48331
48476
  import_chalk2 = __toESM(require("chalk"));
48332
48477
  init_version();
48333
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.29" });
48478
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.30" });
48334
48479
  DANGEROUS_PATTERNS = [
48335
48480
  /\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
48336
48481
  /\bsudo\b/i,