@adhdev/daemon-core 1.0.18-rc.15 → 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.
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 ? "64f056340da99d3b28464efcf5c05fe643e5db63" : void 0) ?? "unknown";
446
- const commitShort = readInjected(true ? "64f05634" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
447
- const version = readInjected(true ? "1.0.18-rc.15" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
448
- const builtAt = readInjected(true ? "2026-07-23T00:51:36.808Z" : 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
  };
@@ -19182,6 +19274,26 @@ function selectFinalAssistantTurnEndMessage(messages) {
19182
19274
  }
19183
19275
  return null;
19184
19276
  }
19277
+ function hasTrailingToolActivityAfterFinalAssistant(messages) {
19278
+ if (!Array.isArray(messages) || messages.length === 0) return false;
19279
+ let sawTrailingToolActivity = false;
19280
+ for (let i = messages.length - 1; i >= 0; i--) {
19281
+ const msg = messages[i];
19282
+ if (!msg) continue;
19283
+ const classification = classifyChatMessageVisibility(msg);
19284
+ if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
19285
+ if (flattenContent(msg.content).trim()) return sawTrailingToolActivity;
19286
+ return false;
19287
+ }
19288
+ if (classification.isUserFacing) {
19289
+ return false;
19290
+ }
19291
+ if (classification.kind === "tool" || classification.kind === "terminal") {
19292
+ sawTrailingToolActivity = true;
19293
+ }
19294
+ }
19295
+ return false;
19296
+ }
19185
19297
  function canonicalizeKindHint(value) {
19186
19298
  return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
19187
19299
  }
@@ -20426,6 +20538,7 @@ function buildAvailableProviders(providerLoader) {
20426
20538
  ...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
20427
20539
  ...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
20428
20540
  ...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
20541
+ ...provider.autoApproveModes !== void 0 ? { autoApproveModes: provider.autoApproveModes } : {},
20429
20542
  ...trust ? {
20430
20543
  trust,
20431
20544
  trustDescription: describeTrust2(trust),
@@ -21605,7 +21718,11 @@ function injectMeshSystemMessage(components, args) {
21605
21718
  spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
21606
21719
  // Coordinator-dispatched recovery relaunch: same auto-approve
21607
21720
  // policy as the primary worker launch path.
21608
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
21721
+ ...delegatedWorkerAutoApproveSettings(
21722
+ mesh?.policy,
21723
+ node?.policy,
21724
+ components.providerLoader?.getMeta(recoveryContext.failedProviderType)
21725
+ ),
21609
21726
  launchedByCoordinator: true
21610
21727
  }
21611
21728
  }).catch((e) => LOG.error("MeshRecovery", `Failed to auto-relaunch session for ${node.id}: ${e?.message}`));
@@ -22873,6 +22990,7 @@ async function pollAssignedTaskTerminalEvidence(components, mesh, row) {
22873
22990
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
22874
22991
  const evidence = extractFinalAssistantSummaryEvidence(messages);
22875
22992
  if (!evidence.finalSummary) return null;
22993
+ if (hasTrailingToolActivityAfterFinalAssistant(messages)) return null;
22876
22994
  const dispatchedAtMs = Date.parse(readNonEmptyString(row.dispatchTimestamp));
22877
22995
  const transcriptAtMs = Date.parse(evidence.transcriptMessageAt ?? "");
22878
22996
  if (!(Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs >= dispatchedAtMs)) {
@@ -23165,6 +23283,52 @@ function assignedRowLiveStatusIsAwaitingApproval(mesh, nodeId, sessionId) {
23165
23283
  return false;
23166
23284
  }
23167
23285
  }
23286
+ function resolveLocalSessionPurePty(components, sessionId) {
23287
+ try {
23288
+ const instances = components.instanceManager?.getByCategory?.("cli") || [];
23289
+ const inst = instances.find((i) => {
23290
+ const sid = readNonEmptyString(i?.getState?.().instanceId);
23291
+ return sid && sessionIdsEquivalent(sid, sessionId);
23292
+ });
23293
+ if (!inst) return void 0;
23294
+ const provider = inst.provider;
23295
+ if (!provider || typeof provider !== "object") return void 0;
23296
+ return isPurePtyTranscriptProvider(provider);
23297
+ } catch {
23298
+ return void 0;
23299
+ }
23300
+ }
23301
+ async function evaluateEarlyIdleTranscriptArm(components, mesh, store, row, localDaemonId, selfIds = []) {
23302
+ const sessionId = readNonEmptyString(row.assignedSessionId);
23303
+ if (!sessionId) return false;
23304
+ const verdict = resolveSessionBusyVerdict(components, sessionId);
23305
+ if (verdict === "GENERATING") return false;
23306
+ if (verdict === "UNKNOWN") {
23307
+ const nodeId = readNonEmptyString(row.assignedNodeId);
23308
+ const node = (mesh.nodes ?? []).find((n) => n.id === nodeId);
23309
+ const liveStatus = nodeId ? readNonEmptyString(sessionStatusFromNodes(mesh.nodes, nodeId, sessionId).status).toLowerCase() : "";
23310
+ if (liveStatus && liveStatus !== "idle") return false;
23311
+ if (!liveStatus) {
23312
+ const nodeDaemonId = readNonEmptyString(node?.daemonId);
23313
+ const isLocalNode = !nodeDaemonId || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || daemonIdListIncludes(selfIds, nodeDaemonId) || !!components.instanceManager?.getInstance?.(sessionId);
23314
+ const providerType = readNonEmptyString(row.assignedProviderType);
23315
+ const readArgs = {
23316
+ sessionId,
23317
+ targetSessionId: sessionId,
23318
+ tailLimit: 1,
23319
+ ...node?.workspace ? { workspace: node.workspace } : {},
23320
+ ...providerType ? { agentType: providerType, providerType } : {}
23321
+ };
23322
+ const probedStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
23323
+ if (probedStatus !== "idle") return false;
23324
+ }
23325
+ }
23326
+ if (store.taskDeliveryConsumed(mesh.id, row.id)) return true;
23327
+ const localPurePty = resolveLocalSessionPurePty(components, sessionId);
23328
+ if (localPurePty === true) return true;
23329
+ if (localPurePty === false) return false;
23330
+ return verdict === "UNKNOWN";
23331
+ }
23168
23332
  async function recoverStrandedAssignedDispatches(components, mesh, store, localDaemonId, selfIds = []) {
23169
23333
  const meshId = mesh.id;
23170
23334
  const assigned = getQueue(meshId, { status: ["assigned"] });
@@ -23186,7 +23350,8 @@ async function recoverStrandedAssignedDispatches(components, mesh, store, localD
23186
23350
  if (!Number.isFinite(dispatchedAtMs)) continue;
23187
23351
  const ageMs = nowMs - dispatchedAtMs;
23188
23352
  const idleTranscriptStreakKey = `${meshId}::${row.id}`;
23189
- if (store.taskHasConfirmedDelivery(meshId, row.id) && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id }) && readNonEmptyString(row.assignedSessionId) && resolveSessionBusyVerdict(components, row.assignedSessionId) !== "GENERATING") {
23353
+ const earlyArm = store.taskHasConfirmedDelivery(meshId, row.id) && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id }) && readNonEmptyString(row.assignedSessionId) ? await evaluateEarlyIdleTranscriptArm(components, mesh, store, row, localDaemonId, selfIds) : false;
23354
+ if (earlyArm) {
23190
23355
  const since = assignedIdleFinalAssistantSince.get(idleTranscriptStreakKey);
23191
23356
  if (since === void 0) {
23192
23357
  assignedIdleFinalAssistantSince.set(idleTranscriptStreakKey, nowMs);
@@ -23925,6 +24090,7 @@ var init_mesh_reconcile_loop = __esm({
23925
24090
  init_mesh_reconcile_identity();
23926
24091
  init_mesh_reconcile_config();
23927
24092
  init_mesh_remote_event_pull();
24093
+ init_provider_cli_shared();
23928
24094
  init_mesh_disk_retention();
23929
24095
  init_mesh_completion_synthesis();
23930
24096
  init_mesh_active_work();
@@ -24210,6 +24376,20 @@ var init_provider_schema = __esm({
24210
24376
  }
24211
24377
  }
24212
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
+ },
24213
24393
  sendDelayMs: {
24214
24394
  type: "number",
24215
24395
  minimum: 0,
@@ -24583,6 +24763,36 @@ var init_provider_schema = __esm({
24583
24763
  }
24584
24764
  },
24585
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
+ },
24586
24796
  patternList: {
24587
24797
  type: "array",
24588
24798
  items: {
@@ -30455,6 +30665,7 @@ __export(index_exports, {
30455
30665
  createSessionDelivery: () => createSessionDelivery,
30456
30666
  createWorktree: () => createWorktree,
30457
30667
  daemonIdsEquivalent: () => daemonIdsEquivalent,
30668
+ delegatedWorkerAutoApproveSettings: () => delegatedWorkerAutoApproveSettings,
30458
30669
  deleteDirectDispatchesByTaskId: () => deleteDirectDispatchesByTaskId,
30459
30670
  deleteMesh: () => deleteMesh,
30460
30671
  deriveMeshNodeHealthFromGit: () => deriveMeshNodeHealthFromGit,
@@ -30654,6 +30865,7 @@ __export(index_exports, {
30654
30865
  resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
30655
30866
  resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
30656
30867
  resolveDelegatedWorkerAutoApprove: () => resolveDelegatedWorkerAutoApprove,
30868
+ resolveDelegatedWorkerDangerousModeAllow: () => resolveDelegatedWorkerDangerousModeAllow,
30657
30869
  resolveDeliveryDecision: () => resolveDeliveryDecision,
30658
30870
  resolveEffectiveMeshNodeHealth: () => resolveEffectiveMeshNodeHealth,
30659
30871
  resolveGitRepository: () => resolveGitRepository,
@@ -49363,6 +49575,7 @@ function formatMarkerTimestamp(timestamp) {
49363
49575
  }
49364
49576
 
49365
49577
  // src/providers/cli-provider-instance.ts
49578
+ init_auto_approve_modes();
49366
49579
  function approvalModalSignature(message, affirmativeAnchor) {
49367
49580
  return [typeof message === "string" ? message.trim() : "", affirmativeAnchor].join("::");
49368
49581
  }
@@ -51343,7 +51556,7 @@ var CliProviderInstance = class _CliProviderInstance {
51343
51556
  * resolveModal, so a plain turn that never saw an approval always returns false.
51344
51557
  */
51345
51558
  inApprovalResumeGrace(now = Date.now()) {
51346
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return false;
51559
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return false;
51347
51560
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
51348
51561
  if (resolvedAt <= 0) return false;
51349
51562
  return now - resolvedAt < _CliProviderInstance.APPROVAL_RESUME_GRACE_MS;
@@ -51448,7 +51661,7 @@ var CliProviderInstance = class _CliProviderInstance {
51448
51661
  return;
51449
51662
  }
51450
51663
  const latestStatus = this.adapter.getStatus({ allowParse: false });
51451
- const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
51664
+ const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
51452
51665
  const latestVisibleStatus = latestAutoApproveActive || this.autoApproveBusy ? "generating" : latestStatus.status;
51453
51666
  LOG.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
51454
51667
  if (latestVisibleStatus !== "idle") {
@@ -51718,7 +51931,7 @@ var CliProviderInstance = class _CliProviderInstance {
51718
51931
  * session, where a human answers the prompt, is returned untouched).
51719
51932
  */
51720
51933
  stabilizeFlappingApprovalStatus(adapterStatus, now = Date.now()) {
51721
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return adapterStatus;
51934
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return adapterStatus;
51722
51935
  const rawStatus = adapterStatus?.status;
51723
51936
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
51724
51937
  if (rawStatus === "waiting_approval") {
@@ -51748,7 +51961,11 @@ var CliProviderInstance = class _CliProviderInstance {
51748
51961
  return adapterStatus;
51749
51962
  }
51750
51963
  maybeAutoApproveStatus(adapterStatus, now = Date.now()) {
51751
- 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)) {
51752
51969
  this.lastAutoApprovalSignature = "";
51753
51970
  this.pendingAutoApprovalSignature = "";
51754
51971
  this.pendingAutoApprovalSince = 0;
@@ -51763,7 +51980,7 @@ var CliProviderInstance = class _CliProviderInstance {
51763
51980
  }, this.manualAttendance.remainingMs(now) + 20);
51764
51981
  return false;
51765
51982
  }
51766
- const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove();
51983
+ const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
51767
51984
  if (!autoApproveActive) {
51768
51985
  this.lastAutoApprovalSignature = "";
51769
51986
  if (this.pendingAutoApprovalSince) {
@@ -52458,15 +52675,34 @@ ${buttons.join("\n")}`;
52458
52675
  get cliName() {
52459
52676
  return this.provider.name;
52460
52677
  }
52678
+ resolveAutoApproveMode() {
52679
+ return resolveProviderAutoApproveMode(this.provider, this.settings);
52680
+ }
52681
+ /** Legacy boolean view retained for internal/test compatibility. */
52461
52682
  shouldAutoApprove() {
52462
- if (typeof this.settings.autoApprove === "boolean") {
52463
- 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;
52464
52701
  }
52465
- const providerDefault = this.provider.settings?.autoApprove?.default;
52466
- if (typeof providerDefault === "boolean") {
52467
- return providerDefault;
52702
+ if (this.autoApproveBusyTimer) {
52703
+ clearTimeout(this.autoApproveBusyTimer);
52704
+ this.autoApproveBusyTimer = null;
52468
52705
  }
52469
- return false;
52470
52706
  }
52471
52707
  /** @see ProviderInstance.noteManualInteraction */
52472
52708
  noteManualInteraction(now = Date.now(), opts) {
@@ -52482,7 +52718,7 @@ ${buttons.join("\n")}`;
52482
52718
  * CLI-specific modal text.
52483
52719
  */
52484
52720
  autoApproveEffectivelyActive(status, now = Date.now()) {
52485
- return status === "waiting_approval" && this.shouldAutoApprove() && !this.manualAttendance.isAttended(now);
52721
+ return status === "waiting_approval" && this.shouldUsePtyAutoApprove() && !this.manualAttendance.isAttended(now);
52486
52722
  }
52487
52723
  // STATUS-MISMATCH: true once the current auto-approve episode has been masking
52488
52724
  // waiting_approval behind `generating` for longer than AUTO_APPROVE_MASK_STALL_MS without
@@ -52492,7 +52728,7 @@ ${buttons.join("\n")}`;
52492
52728
  // maybeAutoApproveStatus (driven by getState + the recheck timer during a waiting episode);
52493
52729
  // this read is side-effect-free so getStatusMetadata can consult it too.
52494
52730
  autoApproveMaskStalled(now = Date.now()) {
52495
- 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;
52496
52732
  }
52497
52733
  /**
52498
52734
  * NOTIF-APPROVAL-MASKED (Q1b): surface a delegated worker's STALLED auto-approve modal
@@ -52516,6 +52752,7 @@ ${buttons.join("\n")}`;
52516
52752
  * mask-clock value) so a modal that flaps between parsed/unparsed states is announced once.
52517
52753
  */
52518
52754
  maybeEmitStalledApprovalNudge(adapterStatus, now) {
52755
+ if (!this.shouldUsePtyAutoApprove()) return;
52519
52756
  if (!this.isMeshWorkerSession()) return;
52520
52757
  if (adapterStatus?.status !== "waiting_approval") return;
52521
52758
  if (!this.autoApproveMaskStalled(now)) return;
@@ -54056,6 +54293,7 @@ function shouldRestoreHostedRuntime(record, managerTag) {
54056
54293
  }
54057
54294
 
54058
54295
  // src/commands/cli-manager.ts
54296
+ init_auto_approve_modes();
54059
54297
  function isExplicitCommand(command) {
54060
54298
  const trimmed = command.trim();
54061
54299
  return path30.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
@@ -54282,6 +54520,24 @@ function expandThinkingLaunchArgs(template, level, levelMap) {
54282
54520
  const mapped = levelMap && typeof levelMap[raw] === "string" && levelMap[raw].trim() ? levelMap[raw].trim() : raw;
54283
54521
  return template.map((part) => part.includes("{{level}}") ? part.replace("{{level}}", mapped) : part);
54284
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
+ }
54285
54541
  function readSubcommandSessionId(args, subcommands) {
54286
54542
  const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
54287
54543
  if (resumeIndex < 0) return void 0;
@@ -54712,22 +54968,30 @@ Run 'adhdev doctor' for detailed diagnostics.`
54712
54968
  if (provider) {
54713
54969
  console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
54714
54970
  }
54715
- const modelLaunchArgs = expandModelLaunchArgs(provider?.modelLaunchArgs, initialModel);
54716
- 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;
54717
54981
  if (initialModel && !modelLaunchArgs) {
54718
54982
  LOG.warn("CLI", `[${normalizedType}] initialModel='${initialModel}' requested but provider declares no modelLaunchArgs template \u2014 launching without model selection.`);
54719
54983
  }
54720
54984
  const initialThinkingLevel = options?.initialThinkingLevel;
54721
- const thinkingLaunchArgs = expandThinkingLaunchArgs(provider?.thinkingLaunchArgs, initialThinkingLevel, provider?.thinkingLevelMap);
54985
+ const thinkingLaunchArgs = expandThinkingLaunchArgs(launchProvider?.thinkingLaunchArgs, initialThinkingLevel, launchProvider?.thinkingLevelMap);
54722
54986
  const cliArgsWithBrain = thinkingLaunchArgs ? [...thinkingLaunchArgs, ...cliArgsWithModel || []] : cliArgsWithModel;
54723
54987
  if (initialThinkingLevel && !thinkingLaunchArgs) {
54724
54988
  LOG.warn("CLI", `[${normalizedType}] initialThinkingLevel='${initialThinkingLevel}' requested but provider declares no thinkingLaunchArgs template \u2014 launching without thinking-level selection.`);
54725
54989
  }
54726
- const sessionBinding = resolveCliSessionBinding(provider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
54990
+ const sessionBinding = resolveCliSessionBinding(launchProvider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
54727
54991
  const resolvedCliArgs = sessionBinding.cliArgs;
54728
54992
  const instanceManager = this.deps.getInstanceManager();
54729
- if (provider && instanceManager) {
54730
- const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
54993
+ if (launchProvider && instanceManager) {
54994
+ const resolvedProvider = launchProvider;
54731
54995
  await this.registerCliInstance(
54732
54996
  key2,
54733
54997
  normalizedType,
@@ -54735,7 +54999,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
54735
54999
  resolvedDir,
54736
55000
  resolvedCliArgs,
54737
55001
  resolvedProvider,
54738
- { ...this.providerLoader.getSettings(normalizedType), ...options?.settingsOverride || {} },
55002
+ launchSettings,
54739
55003
  false,
54740
55004
  {
54741
55005
  providerSessionId: sessionBinding.providerSessionId,
@@ -55574,6 +55838,7 @@ init_hash();
55574
55838
  init_logger();
55575
55839
 
55576
55840
  // src/providers/provider-schema.ts
55841
+ init_auto_approve_modes();
55577
55842
  init_open_panel_support();
55578
55843
  var VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
55579
55844
  var VALID_INPUT_STRATEGIES2 = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
@@ -55639,6 +55904,7 @@ var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
55639
55904
  "providerVersion",
55640
55905
  "status",
55641
55906
  "details",
55907
+ "autoApproveModes",
55642
55908
  "modelLaunchArgs",
55643
55909
  "modelOptions",
55644
55910
  "thinkingLaunchArgs",
@@ -55700,6 +55966,7 @@ function validateProviderDefinition(raw) {
55700
55966
  validateCapabilities(provider, controls, errors);
55701
55967
  validateNativeHistory(provider.nativeHistory, errors);
55702
55968
  validateMeshCoordinator(provider.meshCoordinator, errors);
55969
+ validateAutoApproveModes(provider.autoApproveModes, errors);
55703
55970
  for (const control of controls) {
55704
55971
  validateControl(control, errors);
55705
55972
  }
@@ -55708,6 +55975,75 @@ function validateProviderDefinition(raw) {
55708
55975
  }
55709
55976
  return { errors, warnings };
55710
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
+ }
55711
56047
  function validateCapabilities(provider, controls, errors) {
55712
56048
  const capabilities = provider.capabilities;
55713
56049
  if (provider.contractVersion === 2) {
@@ -76549,6 +76885,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76549
76885
  createSessionDelivery,
76550
76886
  createWorktree,
76551
76887
  daemonIdsEquivalent,
76888
+ delegatedWorkerAutoApproveSettings,
76552
76889
  deleteDirectDispatchesByTaskId,
76553
76890
  deleteMesh,
76554
76891
  deriveMeshNodeHealthFromGit,
@@ -76748,6 +77085,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76748
77085
  resolveCurrentGlobalInstallSurface,
76749
77086
  resolveDebugRuntimeConfig,
76750
77087
  resolveDelegatedWorkerAutoApprove,
77088
+ resolveDelegatedWorkerDangerousModeAllow,
76751
77089
  resolveDeliveryDecision,
76752
77090
  resolveEffectiveMeshNodeHealth,
76753
77091
  resolveGitRepository,