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/cli/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 {
@@ -9993,6 +10046,7 @@ var init_cli_provider_instance = __esm({
9993
10046
  init_chat_history();
9994
10047
  init_logger();
9995
10048
  init_control_effects();
10049
+ init_approval_utils();
9996
10050
  CachedDatabaseSync = null;
9997
10051
  CliProviderInstance = class {
9998
10052
  constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
@@ -10150,6 +10204,8 @@ var init_cli_provider_instance = __esm({
10150
10204
  getState() {
10151
10205
  const adapterStatus = this.adapter.getStatus();
10152
10206
  const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
10207
+ const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
10208
+ const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
10153
10209
  const parsedProviderSessionId = typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId.trim() : "";
10154
10210
  if (parsedProviderSessionId) {
10155
10211
  this.promoteProviderSessionId(parsedProviderSessionId);
@@ -10189,14 +10245,14 @@ var init_cli_provider_instance = __esm({
10189
10245
  type: this.type,
10190
10246
  name: this.provider.name,
10191
10247
  category: "cli",
10192
- status: adapterStatus.status,
10248
+ status: visibleStatus,
10193
10249
  mode: this.presentationMode,
10194
10250
  activeChat: {
10195
10251
  id: `${this.type}_${this.workingDir}`,
10196
10252
  title: parsedStatus?.title || dirName,
10197
- status: parsedStatus?.status || adapterStatus.status,
10253
+ status: autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
10198
10254
  messages: mergedMessages,
10199
- activeModal: parsedStatus?.activeModal ?? adapterStatus.activeModal,
10255
+ activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
10200
10256
  inputContent: ""
10201
10257
  },
10202
10258
  workspace: this.workingDir,
@@ -10260,7 +10316,16 @@ var init_cli_provider_instance = __esm({
10260
10316
  const now = Date.now();
10261
10317
  const adapterStatus = this.adapter.getStatus();
10262
10318
  const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
10263
- const newStatus = adapterStatus.status;
10319
+ const rawStatus = adapterStatus.status;
10320
+ const autoApproveActive = rawStatus === "waiting_approval" && this.shouldAutoApprove();
10321
+ if (autoApproveActive) {
10322
+ const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(adapterStatus.activeModal?.buttons, this.provider);
10323
+ this.recordAutoApproval(adapterStatus.activeModal?.message, buttonLabel, now);
10324
+ setTimeout(() => {
10325
+ this.adapter.resolveModal(buttonIndex);
10326
+ }, 0);
10327
+ }
10328
+ const newStatus = autoApproveActive ? "generating" : rawStatus;
10264
10329
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
10265
10330
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
10266
10331
  const partial2 = this.adapter.getPartialResponse();
@@ -10470,6 +10535,16 @@ ${effect.notification.body || ""}`.trim();
10470
10535
  get cliName() {
10471
10536
  return this.provider.name;
10472
10537
  }
10538
+ shouldAutoApprove() {
10539
+ return this.settings.autoApprove !== false;
10540
+ }
10541
+ recordAutoApproval(modalMessage, buttonLabel, now = Date.now()) {
10542
+ this.appendRuntimeSystemMessage(
10543
+ formatAutoApprovalMessage(modalMessage, buttonLabel),
10544
+ `auto_approval:${now}:${buttonLabel || "approve"}`,
10545
+ now
10546
+ );
10547
+ }
10473
10548
  recordApprovalSelection(buttonText) {
10474
10549
  const cleanButton = String(buttonText || "").trim();
10475
10550
  if (!cleanButton) return;
@@ -27355,8 +27430,10 @@ var init_acp_provider_instance = __esm({
27355
27430
  input: tc.rawInput ? typeof tc.rawInput === "string" ? tc.rawInput : JSON.stringify(tc.rawInput) : void 0
27356
27431
  });
27357
27432
  }
27358
- if (this.settings.autoApprove) {
27359
- this.log.info(`[${this.type}] Auto-approving: ${tc.title || tc.toolCallId}`);
27433
+ if (this.settings.autoApprove !== false) {
27434
+ const toolTitle = tc.title || tc.toolCallId || "tool call";
27435
+ this.log.info(`[${this.type}] Auto-approving: ${toolTitle}`);
27436
+ this.appendSystemMessage(`Auto-approved: ${toolTitle}`);
27360
27437
  const allowOption = params.options.find((o) => o.kind === "allow_once") || params.options.find((o) => o.kind === "allow_always");
27361
27438
  if (allowOption) {
27362
27439
  return { outcome: { outcome: "selected", optionId: allowOption.optionId } };
@@ -27808,6 +27885,18 @@ var init_acp_provider_instance = __esm({
27808
27885
  this.events.push(event);
27809
27886
  if (this.events.length > 50) this.events = this.events.slice(-50);
27810
27887
  }
27888
+ appendSystemMessage(content, timestamp = Date.now()) {
27889
+ const normalizedContent = String(content || "").trim();
27890
+ if (!normalizedContent) return;
27891
+ this.messages.push({
27892
+ role: "system",
27893
+ content: normalizedContent,
27894
+ timestamp
27895
+ });
27896
+ if (this.messages.length > 200) {
27897
+ this.messages = this.messages.slice(-100);
27898
+ }
27899
+ }
27811
27900
  flushEvents() {
27812
27901
  const events = [...this.events];
27813
27902
  this.events = [];
@@ -31151,7 +31240,7 @@ var init_provider_loader = __esm({
31151
31240
  */
31152
31241
  getSettingValue(type, key) {
31153
31242
  const schemaDef = this.getSettingsSchema(type)[key];
31154
- const defaultVal = schemaDef ? schemaDef.default : void 0;
31243
+ const defaultVal = schemaDef ? key === "autoApprove" && schemaDef.type === "boolean" ? true : schemaDef.default : void 0;
31155
31244
  try {
31156
31245
  const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
31157
31246
  const config2 = loadConfig2();
@@ -31210,13 +31299,32 @@ var init_provider_loader = __esm({
31210
31299
  getSettingsSchema(type) {
31211
31300
  const provider = this.providers.get(type);
31212
31301
  if (!provider) return {};
31213
- return {
31302
+ const result = {
31214
31303
  ...this.getSyntheticSettings(type, provider),
31215
31304
  ...provider.settings || {}
31216
31305
  };
31306
+ if (result.autoApprove?.type === "boolean") {
31307
+ result.autoApprove = {
31308
+ ...result.autoApprove,
31309
+ default: true,
31310
+ public: true,
31311
+ label: result.autoApprove.label || "Auto Approve",
31312
+ description: result.autoApprove.description || "Automatically approve actionable prompts without sending approval alerts."
31313
+ };
31314
+ }
31315
+ return result;
31217
31316
  }
31218
31317
  getSyntheticSettings(type, provider) {
31219
31318
  const result = {};
31319
+ if (!provider.settings?.autoApprove) {
31320
+ result.autoApprove = {
31321
+ type: "boolean",
31322
+ default: true,
31323
+ public: true,
31324
+ label: "Auto Approve",
31325
+ description: "Automatically approve actionable prompts without sending approval alerts."
31326
+ };
31327
+ }
31220
31328
  if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executablePath) {
31221
31329
  result.executablePath = {
31222
31330
  type: "string",
@@ -33663,6 +33771,7 @@ var init_poller = __esm({
33663
33771
  init_setup();
33664
33772
  init_reconcile();
33665
33773
  init_logger();
33774
+ init_approval_utils();
33666
33775
  AgentStreamPoller = class {
33667
33776
  deps;
33668
33777
  timer = null;
@@ -33793,7 +33902,43 @@ var init_poller = __esm({
33793
33902
  }
33794
33903
  try {
33795
33904
  await agentStreamManager.syncActiveSession(cdp, parentSessionId);
33796
- const stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
33905
+ let stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
33906
+ if (stream?.status === "waiting_approval") {
33907
+ const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
33908
+ if (autoApprove && resolvedActiveSessionId) {
33909
+ const provider = providerLoader.getMeta(stream.agentType);
33910
+ const { label: buttonLabel } = pickApprovalButton(stream.activeModal?.buttons, provider);
33911
+ const approved = await agentStreamManager.resolveSessionAction(cdp, resolvedActiveSessionId, "approve", buttonLabel);
33912
+ if (approved) {
33913
+ const effectId = [
33914
+ "auto_approval",
33915
+ resolvedActiveSessionId,
33916
+ String(stream.messages?.length || 0),
33917
+ buttonLabel,
33918
+ String(stream.activeModal?.message || "").trim()
33919
+ ].join(":");
33920
+ stream = {
33921
+ ...stream,
33922
+ status: "streaming",
33923
+ activeModal: void 0,
33924
+ effects: [
33925
+ ...stream.effects || [],
33926
+ {
33927
+ type: "message",
33928
+ id: effectId,
33929
+ persist: true,
33930
+ message: {
33931
+ role: "system",
33932
+ senderName: "System",
33933
+ kind: "system",
33934
+ content: formatAutoApprovalMessage(stream.activeModal?.message, buttonLabel)
33935
+ }
33936
+ }
33937
+ ]
33938
+ };
33939
+ }
33940
+ }
33941
+ }
33797
33942
  this.deps.onStreamsUpdated?.(ideType, stream ? [stream] : []);
33798
33943
  } catch {
33799
33944
  }
@@ -48879,7 +49024,7 @@ var init_adhdev_daemon = __esm({
48879
49024
  import_ws3 = require("ws");
48880
49025
  import_chalk2 = __toESM(require("chalk"));
48881
49026
  init_version();
48882
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.29" });
49027
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.30" });
48883
49028
  DANGEROUS_PATTERNS = [
48884
49029
  /\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
48885
49030
  /\bsudo\b/i,