@adhdev/daemon-core 1.0.18-rc.16 → 1.0.18-rc.17

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.
@@ -131,6 +131,15 @@ export declare function expandModelLaunchArgs(template: string[] | undefined, mo
131
131
  * thinking request without a template is a no-op). BRAIN-ROUTING thinking axis.
132
132
  */
133
133
  export declare function expandThinkingLaunchArgs(template: string[] | undefined, level: string | undefined, levelMap: Partial<Record<string, string>> | undefined): string[] | undefined;
134
+ /**
135
+ * Apply a selected launch-args auto-approve mode without mutating provider metadata.
136
+ * removeArgs only targets provider-owned base spawn.args; launchArgs are prepended to
137
+ * per-launch args beside model/thinking args, making conflict removal order-independent.
138
+ */
139
+ export declare function applyAutoApproveModeLaunchArgs(provider: ProviderModule | undefined, cliArgs: string[] | undefined, settings: Record<string, unknown> | undefined): {
140
+ provider: ProviderModule | undefined;
141
+ cliArgs: string[] | undefined;
142
+ };
134
143
  export declare function supportsExplicitSessionResume(resume?: ProviderResumeCapability): boolean;
135
144
  export declare function resolveCliSessionBinding(provider: ProviderModule | undefined, normalizedType: string, cliArgs?: string[], requestedResumeSessionId?: string): CliSessionBinding;
136
145
  export declare class DaemonCliManager {
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export type { SessionEntry, CompactSessionEntry, CompactDaemonEntry, CloudDaemon
8
8
  export type { InteractivePrompt, InteractiveQuestion, InteractiveOption, InteractivePromptResponse, InteractiveAnswer, } from './providers/types/interactive-prompt.js';
9
9
  export { normalizeInteractivePrompt, normalizeInteractivePromptResponse, buildClaudeInteractiveToolResult, interactivePromptFromClaudeAskUserQuestion, detectClaudeAskUserQuestionPromptFromJson, } from './providers/types/interactive-prompt.js';
10
10
  export type { RepoMesh, RepoMeshDaemonRole, RepoMeshHostMetadata, RepoMeshHostPairingMetadata, RepoMeshHostStatus, RepoMeshNode, RepoMeshNodeHealth, RepoMeshPolicy, RepoMeshMagiSessionCleanupMode, RepoMeshNodePolicy, RepoMeshRelatedRepo, RepoMeshNodeCapabilities, DetectedCommand, ProjectContextSnapshot, ProjectContextSource, RepoMeshCoordinatorConfig, LocalMeshConfig, LocalMeshEntry, LocalMeshNodeEntry, RepoMeshStatus, RepoMeshNodeStatus, RepoMeshPeerConnectionStatus, RepoMeshPeerConnectionState, RepoMeshPeerConnectionTransport, RepoMeshSessionStatus, RepoMeshQueueTask, RepoMeshQueueTaskStatus, RepoMeshQueueSummary, RepoMeshQueueStatus, RepoMeshLedgerEntryStatus, RepoMeshLedgerSummaryStatus, RepoMeshLedgerStatus, MeshAsyncJobLifecycle, RepoMeshSchedulingStrategy, RepoMeshSchedulingStatus, RepoMeshNodeSchedulingStatus, RepoMeshNodeProviderSchedulingStatus, } from './repo-mesh-types.js';
11
- export { DEFAULT_MESH_POLICY, resolveDelegatedWorkerAutoApprove, resolveAllowSendKeysDestructive, resolveMagiSessionCleanupMode, magiAutoLaunchedSessionCleanupDecision, MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, normalizeMeshSchedulingStrategy, resolveNodeSchedulingPriority, resolveProviderMaxParallel, mergeAndNormalizePolicy, normalizeAutoFastForwardPolicy, resolveMaxParallelTasks, MESH_MAX_PARALLEL_TASKS_MIN, MESH_MAX_PARALLEL_TASKS_MAX, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, resolveAutoConvergeCodeChange, } from './repo-mesh-types.js';
11
+ export { DEFAULT_MESH_POLICY, resolveDelegatedWorkerAutoApprove, delegatedWorkerAutoApproveSettings, resolveDelegatedWorkerDangerousModeAllow, resolveAllowSendKeysDestructive, resolveMagiSessionCleanupMode, magiAutoLaunchedSessionCleanupDecision, MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, normalizeMeshSchedulingStrategy, resolveNodeSchedulingPriority, resolveProviderMaxParallel, mergeAndNormalizePolicy, normalizeAutoFastForwardPolicy, resolveMaxParallelTasks, MESH_MAX_PARALLEL_TASKS_MIN, MESH_MAX_PARALLEL_TASKS_MAX, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, resolveAutoConvergeCodeChange, } from './repo-mesh-types.js';
12
12
  export * from './git/index.js';
13
13
  import type { RuntimeWriteOwner as _RuntimeWriteOwner } from './shared-types-extra.js';
14
14
  import type { RuntimeAttachedClient as _RuntimeAttachedClient } from './shared-types-extra.js';
@@ -137,7 +137,7 @@ export { ProviderInstanceManager } from './providers/provider-instance-manager.j
137
137
  export { IdeProviderInstance } from './providers/ide-provider-instance.js';
138
138
  export { CliProviderInstance } from './providers/cli-provider-instance.js';
139
139
  export { AcpProviderInstance } from './providers/acp-provider-instance.js';
140
- export type { ProviderModule, CdpTargetFilter, ProviderResumeCapability, InputEnvelope, InputPart, MessagePart, ReadChatTurnStatus, ControlListResult, ControlSetResult, ControlInvokeResult } from './providers/contracts.js';
140
+ export type { ProviderModule, AutoApproveMode, AutoApproveModesConfig, AutoApproveModeRisk, AutoApproveModeStrategy, CdpTargetFilter, ProviderResumeCapability, InputEnvelope, InputPart, MessagePart, ReadChatTurnStatus, ControlListResult, ControlSetResult, ControlInvokeResult } from './providers/contracts.js';
141
141
  export type { ProviderSourceConfigSnapshot, ProviderSourceConfigUpdate } from './config/provider-source-config.js';
142
142
  export { parseProviderSourceConfigUpdate } from './config/provider-source-config.js';
143
143
  export { normalizeInputEnvelope, normalizeMessageParts, flattenMessageParts } from './providers/io-contracts.js';
package/dist/index.js CHANGED
@@ -30,6 +30,62 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // src/providers/auto-approve-modes.ts
34
+ function isKnownDangerousLaunchArg(arg) {
35
+ const normalized = arg.trim();
36
+ if (KNOWN_DANGEROUS_LAUNCH_ARGS.has(normalized)) return true;
37
+ return normalized.startsWith("--dangerously-skip-permissions=") || normalized.startsWith("--dangerously-bypass-approvals-and-sandbox=");
38
+ }
39
+ function deriveAutoApproveModeRisk(mode) {
40
+ return Array.isArray(mode.launchArgs) && mode.launchArgs.some(isKnownDangerousLaunchArg) ? "dangerous" : mode.risk;
41
+ }
42
+ function inactiveMode(modeId = "") {
43
+ return { active: false, strategy: "pty-parse-default", modeId };
44
+ }
45
+ function resolveConfiguredMode(provider, mode, settings) {
46
+ if (mode.strategy === "post-boot-command") return inactiveMode(mode.id);
47
+ if (settings?.launchedByCoordinator === true && settings.delegatedWorkerDangerousModeAllow !== true && deriveAutoApproveModeRisk(mode) === "dangerous") {
48
+ const fallback = provider.autoApproveModes?.modes.find((candidate) => candidate.strategy === "pty-parse-default" && deriveAutoApproveModeRisk(candidate) !== "dangerous");
49
+ return fallback ? { active: true, strategy: fallback.strategy, modeId: fallback.id } : inactiveMode(mode.id);
50
+ }
51
+ return { active: true, strategy: mode.strategy, modeId: mode.id };
52
+ }
53
+ function resolveProviderAutoApproveMode(provider, settings) {
54
+ const config = provider.autoApproveModes;
55
+ const explicitModeId = settings?.autoApproveMode;
56
+ if (typeof explicitModeId === "string") {
57
+ const mode = config?.modes.find((candidate) => candidate.id === explicitModeId);
58
+ if (!mode) return inactiveMode(explicitModeId);
59
+ return resolveConfiguredMode(provider, mode, settings);
60
+ }
61
+ const explicitLegacy = settings?.autoApprove;
62
+ const providerLegacyDefault = provider.settings?.autoApprove?.default;
63
+ const legacyActive = typeof explicitLegacy === "boolean" ? explicitLegacy : typeof providerLegacyDefault === "boolean" ? providerLegacyDefault : false;
64
+ if (!legacyActive) return inactiveMode();
65
+ if (!config) {
66
+ return { active: true, strategy: "pty-parse-default", modeId: "legacy" };
67
+ }
68
+ const defaultMode = config.modes.find((mode) => mode.id === config.default);
69
+ if (!defaultMode) return inactiveMode(config.default);
70
+ return resolveConfiguredMode(provider, defaultMode, settings);
71
+ }
72
+ function findProviderAutoApproveMode(provider, modeId) {
73
+ return provider?.autoApproveModes?.modes.find((mode) => mode.id === modeId);
74
+ }
75
+ var KNOWN_DANGEROUS_LAUNCH_ARGS;
76
+ var init_auto_approve_modes = __esm({
77
+ "src/providers/auto-approve-modes.ts"() {
78
+ "use strict";
79
+ KNOWN_DANGEROUS_LAUNCH_ARGS = /* @__PURE__ */ new Set([
80
+ "--dangerously-skip-permissions",
81
+ "--dangerously-bypass-approvals-and-sandbox",
82
+ "bypassPermissions",
83
+ "sandbox_mode=danger-full-access",
84
+ "approval_policy=never"
85
+ ]);
86
+ }
87
+ });
88
+
33
89
  // src/repo-mesh-types.ts
34
90
  function normalizeMeshSchedulingStrategy(value) {
35
91
  if (typeof value !== "string") return DEFAULT_MESH_SCHEDULING_STRATEGY;
@@ -116,6 +172,11 @@ function mergeAndNormalizePolicy(base, patch) {
116
172
  } else {
117
173
  delete policy.autoConvergeCodeChange;
118
174
  }
175
+ if (policy.delegatedWorkerDangerousModeAllow === true) {
176
+ policy.delegatedWorkerDangerousModeAllow = true;
177
+ } else {
178
+ delete policy.delegatedWorkerDangerousModeAllow;
179
+ }
119
180
  if (policy.coordinatorIdlePushPolicy === "auto_silent_on_dispatch") {
120
181
  policy.coordinatorIdlePushPolicy = "auto_silent_on_dispatch";
121
182
  } else {
@@ -123,14 +184,35 @@ function mergeAndNormalizePolicy(base, patch) {
123
184
  }
124
185
  return policy;
125
186
  }
126
- function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy) {
187
+ function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider) {
188
+ let enabled = true;
127
189
  if (typeof nodePolicy?.delegatedWorkerAutoApprove === "boolean") {
128
- return nodePolicy.delegatedWorkerAutoApprove;
190
+ enabled = nodePolicy.delegatedWorkerAutoApprove;
191
+ } else if (typeof meshPolicy?.delegatedWorkerAutoApprove === "boolean") {
192
+ enabled = meshPolicy.delegatedWorkerAutoApprove;
129
193
  }
130
- if (typeof meshPolicy?.delegatedWorkerAutoApprove === "boolean") {
131
- return meshPolicy.delegatedWorkerAutoApprove;
194
+ if (!enabled) return false;
195
+ const modes = provider?.autoApproveModes;
196
+ if (!modes) return true;
197
+ const defaultMode = modes.modes.find((mode) => mode.id === modes.default);
198
+ if (!defaultMode || defaultMode.strategy === "post-boot-command") return false;
199
+ const dangerousAllowed = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
200
+ if (deriveAutoApproveModeRisk(defaultMode) === "dangerous" && !dangerousAllowed) {
201
+ const ptyFallback = modes.modes.find((mode) => mode.strategy === "pty-parse-default" && deriveAutoApproveModeRisk(mode) !== "dangerous");
202
+ return ptyFallback?.id || false;
132
203
  }
133
- return true;
204
+ return defaultMode.id;
205
+ }
206
+ function resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy) {
207
+ if (typeof nodePolicy?.delegatedWorkerDangerousModeAllow === "boolean") {
208
+ return nodePolicy.delegatedWorkerDangerousModeAllow;
209
+ }
210
+ return meshPolicy?.delegatedWorkerDangerousModeAllow === true;
211
+ }
212
+ function delegatedWorkerAutoApproveSettings(meshPolicy, nodePolicy, provider) {
213
+ const resolved = resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider);
214
+ const delegatedWorkerDangerousModeAllow = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
215
+ return typeof resolved === "string" ? { autoApprove: void 0, autoApproveMode: resolved, delegatedWorkerDangerousModeAllow } : { autoApprove: resolved, autoApproveMode: void 0, delegatedWorkerDangerousModeAllow };
134
216
  }
135
217
  function resolveAllowSendKeysDestructive(meshPolicy, nodePolicy) {
136
218
  if (typeof nodePolicy?.allowSendKeysDestructive === "boolean") {
@@ -160,6 +242,7 @@ var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_
160
242
  var init_repo_mesh_types = __esm({
161
243
  "src/repo-mesh-types.ts"() {
162
244
  "use strict";
245
+ init_auto_approve_modes();
163
246
  MESH_SCHEDULING_STRATEGIES = [
164
247
  "first_eligible",
165
248
  "least_loaded",
@@ -187,6 +270,7 @@ var init_repo_mesh_types = __esm({
187
270
  // any specific session manually; that override is preserved per-device.
188
271
  spawnedSessionVisibility: "hidden",
189
272
  delegatedWorkerAutoApprove: true,
273
+ delegatedWorkerDangerousModeAllow: false,
190
274
  sessionCleanupOnNodeRemove: "preserve",
191
275
  // MAGI auto-launches a worker session per pinned replica target with no idle
192
276
  // session; those stay idle-LIVE after their turn. Default ON (stop_and_delete)
@@ -442,10 +526,10 @@ function readInjected(value) {
442
526
  }
443
527
  function getDaemonBuildInfo() {
444
528
  if (cached) return cached;
445
- const commit = readInjected(true ? "74f34080bcd7c145e55fd7e5fd492a40a4942bc4" : void 0) ?? "unknown";
446
- const commitShort = readInjected(true ? "74f34080" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
447
- const version = readInjected(true ? "1.0.18-rc.16" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
448
- const builtAt = readInjected(true ? "2026-07-23T02:29:46.281Z" : void 0);
529
+ const commit = readInjected(true ? "eeb3e1474488eb5543c443270208f3ca8958a86a" : void 0) ?? "unknown";
530
+ const commitShort = readInjected(true ? "eeb3e147" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
531
+ const version = readInjected(true ? "1.0.18-rc.17" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
532
+ const builtAt = readInjected(true ? "2026-07-23T03:30:50.962Z" : void 0);
449
533
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
450
534
  return cached;
451
535
  }
@@ -16832,7 +16916,11 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
16832
16916
  meshNodeFor: meshId,
16833
16917
  meshNodeId: nodeId,
16834
16918
  launchedByCoordinator: true,
16835
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
16919
+ ...delegatedWorkerAutoApproveSettings(
16920
+ mesh?.policy,
16921
+ node?.policy,
16922
+ components.providerLoader?.getMeta(providerType)
16923
+ ),
16836
16924
  ...localDaemonId ? { meshCoordinatorDaemonId: localDaemonId } : {},
16837
16925
  // COMPLETION-PROPAGATION F5: (re)stamp the coordinator SESSION anchor from THIS
16838
16926
  // task's sourceCoordinatorSessionId with PRIORITY — a manually-launched (or reused)
@@ -17605,8 +17693,12 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
17605
17693
  spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
17606
17694
  // Coordinator-dispatched worker: auto-approve unless mesh/node policy
17607
17695
  // opts out (default true). Lands in settingsOverride and beats the
17608
- // global per-provider-type autoApprove config (see shouldAutoApprove).
17609
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
17696
+ // global per-provider-type boolean/mode through explicit opposite-key clearing.
17697
+ ...delegatedWorkerAutoApproveSettings(
17698
+ mesh?.policy,
17699
+ node?.policy,
17700
+ components.providerLoader?.getMeta(resolved.providerType)
17701
+ ),
17610
17702
  launchedByCoordinator: true,
17611
17703
  autoLaunchedForQueueTaskId: task.id
17612
17704
  };
@@ -20446,6 +20538,7 @@ function buildAvailableProviders(providerLoader) {
20446
20538
  ...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
20447
20539
  ...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
20448
20540
  ...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
20541
+ ...provider.autoApproveModes !== void 0 ? { autoApproveModes: provider.autoApproveModes } : {},
20449
20542
  ...trust ? {
20450
20543
  trust,
20451
20544
  trustDescription: describeTrust2(trust),
@@ -21625,7 +21718,11 @@ function injectMeshSystemMessage(components, args) {
21625
21718
  spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
21626
21719
  // Coordinator-dispatched recovery relaunch: same auto-approve
21627
21720
  // policy as the primary worker launch path.
21628
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
21721
+ ...delegatedWorkerAutoApproveSettings(
21722
+ mesh?.policy,
21723
+ node?.policy,
21724
+ components.providerLoader?.getMeta(recoveryContext.failedProviderType)
21725
+ ),
21629
21726
  launchedByCoordinator: true
21630
21727
  }
21631
21728
  }).catch((e) => LOG.error("MeshRecovery", `Failed to auto-relaunch session for ${node.id}: ${e?.message}`));
@@ -24279,6 +24376,20 @@ var init_provider_schema = __esm({
24279
24376
  }
24280
24377
  }
24281
24378
  },
24379
+ autoApproveModes: {
24380
+ type: "object",
24381
+ description: "Provider-specific auto-approve choices and their launch/runtime strategy.",
24382
+ required: ["default", "modes"],
24383
+ additionalProperties: false,
24384
+ properties: {
24385
+ default: { type: "string", minLength: 1 },
24386
+ modes: {
24387
+ type: "array",
24388
+ minItems: 1,
24389
+ items: { $ref: "#/$defs/autoApproveMode" }
24390
+ }
24391
+ }
24392
+ },
24282
24393
  sendDelayMs: {
24283
24394
  type: "number",
24284
24395
  minimum: 0,
@@ -24652,6 +24763,36 @@ var init_provider_schema = __esm({
24652
24763
  }
24653
24764
  },
24654
24765
  $defs: {
24766
+ autoApproveMode: {
24767
+ type: "object",
24768
+ required: ["id", "label", "strategy", "risk"],
24769
+ additionalProperties: false,
24770
+ properties: {
24771
+ id: { type: "string", minLength: 1 },
24772
+ label: { type: "string", minLength: 1 },
24773
+ strategy: { enum: ["pty-parse-default", "launch-args", "post-boot-command"] },
24774
+ risk: { enum: ["safe", "caution", "dangerous"] },
24775
+ warning: { type: "string", minLength: 1 },
24776
+ launchArgs: {
24777
+ type: "array",
24778
+ items: { type: "string", minLength: 1 }
24779
+ },
24780
+ removeArgs: {
24781
+ type: "array",
24782
+ items: { type: "string", minLength: 1 }
24783
+ }
24784
+ },
24785
+ allOf: [
24786
+ {
24787
+ if: { properties: { strategy: { const: "launch-args" } }, required: ["strategy"] },
24788
+ then: { required: ["launchArgs"], properties: { launchArgs: { minItems: 1 } } }
24789
+ },
24790
+ {
24791
+ if: { properties: { risk: { const: "dangerous" } }, required: ["risk"] },
24792
+ then: { required: ["warning"] }
24793
+ }
24794
+ ]
24795
+ },
24655
24796
  patternList: {
24656
24797
  type: "array",
24657
24798
  items: {
@@ -30524,6 +30665,7 @@ __export(index_exports, {
30524
30665
  createSessionDelivery: () => createSessionDelivery,
30525
30666
  createWorktree: () => createWorktree,
30526
30667
  daemonIdsEquivalent: () => daemonIdsEquivalent,
30668
+ delegatedWorkerAutoApproveSettings: () => delegatedWorkerAutoApproveSettings,
30527
30669
  deleteDirectDispatchesByTaskId: () => deleteDirectDispatchesByTaskId,
30528
30670
  deleteMesh: () => deleteMesh,
30529
30671
  deriveMeshNodeHealthFromGit: () => deriveMeshNodeHealthFromGit,
@@ -30723,6 +30865,7 @@ __export(index_exports, {
30723
30865
  resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
30724
30866
  resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
30725
30867
  resolveDelegatedWorkerAutoApprove: () => resolveDelegatedWorkerAutoApprove,
30868
+ resolveDelegatedWorkerDangerousModeAllow: () => resolveDelegatedWorkerDangerousModeAllow,
30726
30869
  resolveDeliveryDecision: () => resolveDeliveryDecision,
30727
30870
  resolveEffectiveMeshNodeHealth: () => resolveEffectiveMeshNodeHealth,
30728
30871
  resolveGitRepository: () => resolveGitRepository,
@@ -49432,6 +49575,7 @@ function formatMarkerTimestamp(timestamp) {
49432
49575
  }
49433
49576
 
49434
49577
  // src/providers/cli-provider-instance.ts
49578
+ init_auto_approve_modes();
49435
49579
  function approvalModalSignature(message, affirmativeAnchor) {
49436
49580
  return [typeof message === "string" ? message.trim() : "", affirmativeAnchor].join("::");
49437
49581
  }
@@ -51412,7 +51556,7 @@ var CliProviderInstance = class _CliProviderInstance {
51412
51556
  * resolveModal, so a plain turn that never saw an approval always returns false.
51413
51557
  */
51414
51558
  inApprovalResumeGrace(now = Date.now()) {
51415
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return false;
51559
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return false;
51416
51560
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
51417
51561
  if (resolvedAt <= 0) return false;
51418
51562
  return now - resolvedAt < _CliProviderInstance.APPROVAL_RESUME_GRACE_MS;
@@ -51517,7 +51661,7 @@ var CliProviderInstance = class _CliProviderInstance {
51517
51661
  return;
51518
51662
  }
51519
51663
  const latestStatus = this.adapter.getStatus({ allowParse: false });
51520
- const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
51664
+ const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
51521
51665
  const latestVisibleStatus = latestAutoApproveActive || this.autoApproveBusy ? "generating" : latestStatus.status;
51522
51666
  LOG.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
51523
51667
  if (latestVisibleStatus !== "idle") {
@@ -51787,7 +51931,7 @@ var CliProviderInstance = class _CliProviderInstance {
51787
51931
  * session, where a human answers the prompt, is returned untouched).
51788
51932
  */
51789
51933
  stabilizeFlappingApprovalStatus(adapterStatus, now = Date.now()) {
51790
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return adapterStatus;
51934
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return adapterStatus;
51791
51935
  const rawStatus = adapterStatus?.status;
51792
51936
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
51793
51937
  if (rawStatus === "waiting_approval") {
@@ -51817,7 +51961,11 @@ var CliProviderInstance = class _CliProviderInstance {
51817
51961
  return adapterStatus;
51818
51962
  }
51819
51963
  maybeAutoApproveStatus(adapterStatus, now = Date.now()) {
51820
- if (adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove() && this.manualAttendance.isAttended(now)) {
51964
+ if (!this.shouldUsePtyAutoApprove()) {
51965
+ this.resetPtyAutoApproveState();
51966
+ return false;
51967
+ }
51968
+ if (adapterStatus?.status === "waiting_approval" && this.shouldUsePtyAutoApprove() && this.manualAttendance.isAttended(now)) {
51821
51969
  this.lastAutoApprovalSignature = "";
51822
51970
  this.pendingAutoApprovalSignature = "";
51823
51971
  this.pendingAutoApprovalSince = 0;
@@ -51832,7 +51980,7 @@ var CliProviderInstance = class _CliProviderInstance {
51832
51980
  }, this.manualAttendance.remainingMs(now) + 20);
51833
51981
  return false;
51834
51982
  }
51835
- const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove();
51983
+ const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
51836
51984
  if (!autoApproveActive) {
51837
51985
  this.lastAutoApprovalSignature = "";
51838
51986
  if (this.pendingAutoApprovalSince) {
@@ -52527,15 +52675,34 @@ ${buttons.join("\n")}`;
52527
52675
  get cliName() {
52528
52676
  return this.provider.name;
52529
52677
  }
52678
+ resolveAutoApproveMode() {
52679
+ return resolveProviderAutoApproveMode(this.provider, this.settings);
52680
+ }
52681
+ /** Legacy boolean view retained for internal/test compatibility. */
52530
52682
  shouldAutoApprove() {
52531
- if (typeof this.settings.autoApprove === "boolean") {
52532
- return this.settings.autoApprove;
52683
+ return this.resolveAutoApproveMode().active;
52684
+ }
52685
+ shouldUsePtyAutoApprove() {
52686
+ const resolved = this.resolveAutoApproveMode();
52687
+ return this.shouldAutoApprove() && resolved.strategy === "pty-parse-default";
52688
+ }
52689
+ resetPtyAutoApproveState() {
52690
+ this.lastAutoApprovalSignature = "";
52691
+ this.pendingAutoApprovalSignature = "";
52692
+ this.pendingAutoApprovalSince = 0;
52693
+ this.autoApproveInactiveSince = 0;
52694
+ this.autoApproveMaskSince = 0;
52695
+ this.stalledApprovalNudgeEpisode = 0;
52696
+ this.autoApproveLastModalSeenAt = 0;
52697
+ this.autoApproveBusy = false;
52698
+ if (this.autoApproveSettleTimer) {
52699
+ clearTimeout(this.autoApproveSettleTimer);
52700
+ this.autoApproveSettleTimer = null;
52533
52701
  }
52534
- const providerDefault = this.provider.settings?.autoApprove?.default;
52535
- if (typeof providerDefault === "boolean") {
52536
- return providerDefault;
52702
+ if (this.autoApproveBusyTimer) {
52703
+ clearTimeout(this.autoApproveBusyTimer);
52704
+ this.autoApproveBusyTimer = null;
52537
52705
  }
52538
- return false;
52539
52706
  }
52540
52707
  /** @see ProviderInstance.noteManualInteraction */
52541
52708
  noteManualInteraction(now = Date.now(), opts) {
@@ -52551,7 +52718,7 @@ ${buttons.join("\n")}`;
52551
52718
  * CLI-specific modal text.
52552
52719
  */
52553
52720
  autoApproveEffectivelyActive(status, now = Date.now()) {
52554
- return status === "waiting_approval" && this.shouldAutoApprove() && !this.manualAttendance.isAttended(now);
52721
+ return status === "waiting_approval" && this.shouldUsePtyAutoApprove() && !this.manualAttendance.isAttended(now);
52555
52722
  }
52556
52723
  // STATUS-MISMATCH: true once the current auto-approve episode has been masking
52557
52724
  // waiting_approval behind `generating` for longer than AUTO_APPROVE_MASK_STALL_MS without
@@ -52561,7 +52728,7 @@ ${buttons.join("\n")}`;
52561
52728
  // maybeAutoApproveStatus (driven by getState + the recheck timer during a waiting episode);
52562
52729
  // this read is side-effect-free so getStatusMetadata can consult it too.
52563
52730
  autoApproveMaskStalled(now = Date.now()) {
52564
- return this.autoApproveMaskSince > 0 && now - this.autoApproveMaskSince > _CliProviderInstance.AUTO_APPROVE_MASK_STALL_MS;
52731
+ return this.shouldUsePtyAutoApprove() && this.autoApproveMaskSince > 0 && now - this.autoApproveMaskSince > _CliProviderInstance.AUTO_APPROVE_MASK_STALL_MS;
52565
52732
  }
52566
52733
  /**
52567
52734
  * NOTIF-APPROVAL-MASKED (Q1b): surface a delegated worker's STALLED auto-approve modal
@@ -52585,6 +52752,7 @@ ${buttons.join("\n")}`;
52585
52752
  * mask-clock value) so a modal that flaps between parsed/unparsed states is announced once.
52586
52753
  */
52587
52754
  maybeEmitStalledApprovalNudge(adapterStatus, now) {
52755
+ if (!this.shouldUsePtyAutoApprove()) return;
52588
52756
  if (!this.isMeshWorkerSession()) return;
52589
52757
  if (adapterStatus?.status !== "waiting_approval") return;
52590
52758
  if (!this.autoApproveMaskStalled(now)) return;
@@ -54125,6 +54293,7 @@ function shouldRestoreHostedRuntime(record, managerTag) {
54125
54293
  }
54126
54294
 
54127
54295
  // src/commands/cli-manager.ts
54296
+ init_auto_approve_modes();
54128
54297
  function isExplicitCommand(command) {
54129
54298
  const trimmed = command.trim();
54130
54299
  return path30.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
@@ -54351,6 +54520,24 @@ function expandThinkingLaunchArgs(template, level, levelMap) {
54351
54520
  const mapped = levelMap && typeof levelMap[raw] === "string" && levelMap[raw].trim() ? levelMap[raw].trim() : raw;
54352
54521
  return template.map((part) => part.includes("{{level}}") ? part.replace("{{level}}", mapped) : part);
54353
54522
  }
54523
+ function matchesRemovedLaunchArg(arg, removeArg) {
54524
+ return arg === removeArg || removeArg.startsWith("--") && arg.startsWith(`${removeArg}=`);
54525
+ }
54526
+ function applyAutoApproveModeLaunchArgs(provider, cliArgs, settings) {
54527
+ if (!provider) return { provider, cliArgs };
54528
+ const resolved = resolveProviderAutoApproveMode(provider, settings);
54529
+ if (!resolved.active || resolved.strategy !== "launch-args") return { provider, cliArgs };
54530
+ const mode = findProviderAutoApproveMode(provider, resolved.modeId);
54531
+ if (!mode || !Array.isArray(mode.launchArgs) || mode.launchArgs.length === 0) return { provider, cliArgs };
54532
+ const removeArgs = Array.isArray(mode.removeArgs) ? mode.removeArgs : [];
54533
+ const baseArgs = provider.spawn?.args;
54534
+ const filteredBaseArgs = Array.isArray(baseArgs) && removeArgs.length > 0 ? baseArgs.filter((arg) => !removeArgs.some((removeArg) => matchesRemovedLaunchArg(arg, removeArg))) : baseArgs;
54535
+ const launchProvider = filteredBaseArgs === baseArgs ? provider : { ...provider, spawn: { ...provider.spawn, args: filteredBaseArgs } };
54536
+ return {
54537
+ provider: launchProvider,
54538
+ cliArgs: [...mode.launchArgs, ...cliArgs || []]
54539
+ };
54540
+ }
54354
54541
  function readSubcommandSessionId(args, subcommands) {
54355
54542
  const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
54356
54543
  if (resumeIndex < 0) return void 0;
@@ -54781,22 +54968,30 @@ Run 'adhdev doctor' for detailed diagnostics.`
54781
54968
  if (provider) {
54782
54969
  console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
54783
54970
  }
54784
- const modelLaunchArgs = expandModelLaunchArgs(provider?.modelLaunchArgs, initialModel);
54785
- const cliArgsWithModel = modelLaunchArgs ? [...modelLaunchArgs, ...cliArgs || []] : cliArgs;
54971
+ const launchSettings = {
54972
+ ...this.providerLoader.getSettings(normalizedType),
54973
+ ...options?.settingsOverride || {}
54974
+ };
54975
+ const versionResolvedProvider = provider ? this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider : void 0;
54976
+ const autoApproveLaunch = applyAutoApproveModeLaunchArgs(versionResolvedProvider, cliArgs, launchSettings);
54977
+ const launchProvider = autoApproveLaunch.provider || provider;
54978
+ const cliArgsWithAutoApprove = autoApproveLaunch.cliArgs;
54979
+ const modelLaunchArgs = expandModelLaunchArgs(launchProvider?.modelLaunchArgs, initialModel);
54980
+ const cliArgsWithModel = modelLaunchArgs ? [...modelLaunchArgs, ...cliArgsWithAutoApprove || []] : cliArgsWithAutoApprove;
54786
54981
  if (initialModel && !modelLaunchArgs) {
54787
54982
  LOG.warn("CLI", `[${normalizedType}] initialModel='${initialModel}' requested but provider declares no modelLaunchArgs template \u2014 launching without model selection.`);
54788
54983
  }
54789
54984
  const initialThinkingLevel = options?.initialThinkingLevel;
54790
- const thinkingLaunchArgs = expandThinkingLaunchArgs(provider?.thinkingLaunchArgs, initialThinkingLevel, provider?.thinkingLevelMap);
54985
+ const thinkingLaunchArgs = expandThinkingLaunchArgs(launchProvider?.thinkingLaunchArgs, initialThinkingLevel, launchProvider?.thinkingLevelMap);
54791
54986
  const cliArgsWithBrain = thinkingLaunchArgs ? [...thinkingLaunchArgs, ...cliArgsWithModel || []] : cliArgsWithModel;
54792
54987
  if (initialThinkingLevel && !thinkingLaunchArgs) {
54793
54988
  LOG.warn("CLI", `[${normalizedType}] initialThinkingLevel='${initialThinkingLevel}' requested but provider declares no thinkingLaunchArgs template \u2014 launching without thinking-level selection.`);
54794
54989
  }
54795
- const sessionBinding = resolveCliSessionBinding(provider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
54990
+ const sessionBinding = resolveCliSessionBinding(launchProvider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
54796
54991
  const resolvedCliArgs = sessionBinding.cliArgs;
54797
54992
  const instanceManager = this.deps.getInstanceManager();
54798
- if (provider && instanceManager) {
54799
- const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
54993
+ if (launchProvider && instanceManager) {
54994
+ const resolvedProvider = launchProvider;
54800
54995
  await this.registerCliInstance(
54801
54996
  key2,
54802
54997
  normalizedType,
@@ -54804,7 +54999,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
54804
54999
  resolvedDir,
54805
55000
  resolvedCliArgs,
54806
55001
  resolvedProvider,
54807
- { ...this.providerLoader.getSettings(normalizedType), ...options?.settingsOverride || {} },
55002
+ launchSettings,
54808
55003
  false,
54809
55004
  {
54810
55005
  providerSessionId: sessionBinding.providerSessionId,
@@ -55643,6 +55838,7 @@ init_hash();
55643
55838
  init_logger();
55644
55839
 
55645
55840
  // src/providers/provider-schema.ts
55841
+ init_auto_approve_modes();
55646
55842
  init_open_panel_support();
55647
55843
  var VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
55648
55844
  var VALID_INPUT_STRATEGIES2 = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
@@ -55708,6 +55904,7 @@ var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
55708
55904
  "providerVersion",
55709
55905
  "status",
55710
55906
  "details",
55907
+ "autoApproveModes",
55711
55908
  "modelLaunchArgs",
55712
55909
  "modelOptions",
55713
55910
  "thinkingLaunchArgs",
@@ -55769,6 +55966,7 @@ function validateProviderDefinition(raw) {
55769
55966
  validateCapabilities(provider, controls, errors);
55770
55967
  validateNativeHistory(provider.nativeHistory, errors);
55771
55968
  validateMeshCoordinator(provider.meshCoordinator, errors);
55969
+ validateAutoApproveModes(provider.autoApproveModes, errors);
55772
55970
  for (const control of controls) {
55773
55971
  validateControl(control, errors);
55774
55972
  }
@@ -55777,6 +55975,75 @@ function validateProviderDefinition(raw) {
55777
55975
  }
55778
55976
  return { errors, warnings };
55779
55977
  }
55978
+ function validateAutoApproveModes(raw, errors) {
55979
+ if (raw === void 0) return;
55980
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
55981
+ errors.push("autoApproveModes must be an object");
55982
+ return;
55983
+ }
55984
+ const config = raw;
55985
+ const defaultModeId = typeof config.default === "string" ? config.default.trim() : "";
55986
+ if (!defaultModeId) {
55987
+ errors.push("autoApproveModes.default must be a non-empty string");
55988
+ } else {
55989
+ config.default = defaultModeId;
55990
+ }
55991
+ if (!Array.isArray(config.modes) || config.modes.length === 0) {
55992
+ errors.push("autoApproveModes.modes must be a non-empty array");
55993
+ return;
55994
+ }
55995
+ const ids = /* @__PURE__ */ new Set();
55996
+ for (const [index, rawMode] of config.modes.entries()) {
55997
+ const prefix = `autoApproveModes.modes[${index}]`;
55998
+ if (!rawMode || typeof rawMode !== "object" || Array.isArray(rawMode)) {
55999
+ errors.push(`${prefix} must be an object`);
56000
+ continue;
56001
+ }
56002
+ const mode = rawMode;
56003
+ const id = typeof mode.id === "string" ? mode.id.trim() : "";
56004
+ if (!id) {
56005
+ errors.push(`${prefix}.id must be a non-empty string`);
56006
+ } else if (ids.has(id)) {
56007
+ errors.push(`${prefix}.id must be unique (duplicate: ${id})`);
56008
+ } else {
56009
+ ids.add(id);
56010
+ mode.id = id;
56011
+ }
56012
+ if (typeof mode.label !== "string" || !mode.label.trim()) {
56013
+ errors.push(`${prefix}.label must be a non-empty string`);
56014
+ }
56015
+ const strategy = mode.strategy;
56016
+ if (!["pty-parse-default", "launch-args", "post-boot-command"].includes(String(strategy))) {
56017
+ errors.push(`${prefix}.strategy must be one of: pty-parse-default, launch-args, post-boot-command`);
56018
+ } else if (strategy === "post-boot-command") {
56019
+ errors.push(`${prefix}.strategy post-boot-command is reserved and unsupported in v1`);
56020
+ }
56021
+ const risk = mode.risk;
56022
+ if (!["safe", "caution", "dangerous"].includes(String(risk))) {
56023
+ errors.push(`${prefix}.risk must be one of: safe, caution, dangerous`);
56024
+ }
56025
+ for (const field of ["launchArgs", "removeArgs"]) {
56026
+ const value = mode[field];
56027
+ if (value !== void 0 && (!Array.isArray(value) || value.some((arg) => typeof arg !== "string" || !arg.trim()))) {
56028
+ errors.push(`${prefix}.${field} must be an array of non-empty strings when provided`);
56029
+ }
56030
+ }
56031
+ if (strategy === "launch-args" && (!Array.isArray(mode.launchArgs) || mode.launchArgs.length === 0)) {
56032
+ errors.push(`${prefix}.launchArgs must be a non-empty array for launch-args strategy`);
56033
+ }
56034
+ if (["safe", "caution", "dangerous"].includes(String(risk)) && deriveAutoApproveModeRisk(mode) === "dangerous") {
56035
+ mode.risk = "dangerous";
56036
+ }
56037
+ if (mode.risk === "dangerous" && (typeof mode.warning !== "string" || !mode.warning.trim())) {
56038
+ errors.push(`${prefix}.warning is required for dangerous modes`);
56039
+ } else if (mode.warning !== void 0 && (typeof mode.warning !== "string" || !mode.warning.trim())) {
56040
+ errors.push(`${prefix}.warning must be a non-empty string when provided`);
56041
+ }
56042
+ }
56043
+ if (defaultModeId && !ids.has(defaultModeId)) {
56044
+ errors.push(`autoApproveModes.default must reference an existing mode id: ${defaultModeId}`);
56045
+ }
56046
+ }
55780
56047
  function validateCapabilities(provider, controls, errors) {
55781
56048
  const capabilities = provider.capabilities;
55782
56049
  if (provider.contractVersion === 2) {
@@ -76618,6 +76885,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76618
76885
  createSessionDelivery,
76619
76886
  createWorktree,
76620
76887
  daemonIdsEquivalent,
76888
+ delegatedWorkerAutoApproveSettings,
76621
76889
  deleteDirectDispatchesByTaskId,
76622
76890
  deleteMesh,
76623
76891
  deriveMeshNodeHealthFromGit,
@@ -76817,6 +77085,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76817
77085
  resolveCurrentGlobalInstallSurface,
76818
77086
  resolveDebugRuntimeConfig,
76819
77087
  resolveDelegatedWorkerAutoApprove,
77088
+ resolveDelegatedWorkerDangerousModeAllow,
76820
77089
  resolveDeliveryDecision,
76821
77090
  resolveEffectiveMeshNodeHealth,
76822
77091
  resolveGitRepository,