@adhdev/daemon-standalone 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
@@ -29838,6 +29838,60 @@ var require_dist3 = __commonJS({
29838
29838
  mod
29839
29839
  ));
29840
29840
  var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
29841
+ function isKnownDangerousLaunchArg(arg) {
29842
+ const normalized = arg.trim();
29843
+ if (KNOWN_DANGEROUS_LAUNCH_ARGS.has(normalized)) return true;
29844
+ return normalized.startsWith("--dangerously-skip-permissions=") || normalized.startsWith("--dangerously-bypass-approvals-and-sandbox=");
29845
+ }
29846
+ function deriveAutoApproveModeRisk(mode) {
29847
+ return Array.isArray(mode.launchArgs) && mode.launchArgs.some(isKnownDangerousLaunchArg) ? "dangerous" : mode.risk;
29848
+ }
29849
+ function inactiveMode(modeId = "") {
29850
+ return { active: false, strategy: "pty-parse-default", modeId };
29851
+ }
29852
+ function resolveConfiguredMode(provider, mode, settings) {
29853
+ if (mode.strategy === "post-boot-command") return inactiveMode(mode.id);
29854
+ if (settings?.launchedByCoordinator === true && settings.delegatedWorkerDangerousModeAllow !== true && deriveAutoApproveModeRisk(mode) === "dangerous") {
29855
+ const fallback = provider.autoApproveModes?.modes.find((candidate) => candidate.strategy === "pty-parse-default" && deriveAutoApproveModeRisk(candidate) !== "dangerous");
29856
+ return fallback ? { active: true, strategy: fallback.strategy, modeId: fallback.id } : inactiveMode(mode.id);
29857
+ }
29858
+ return { active: true, strategy: mode.strategy, modeId: mode.id };
29859
+ }
29860
+ function resolveProviderAutoApproveMode(provider, settings) {
29861
+ const config2 = provider.autoApproveModes;
29862
+ const explicitModeId = settings?.autoApproveMode;
29863
+ if (typeof explicitModeId === "string") {
29864
+ const mode = config2?.modes.find((candidate) => candidate.id === explicitModeId);
29865
+ if (!mode) return inactiveMode(explicitModeId);
29866
+ return resolveConfiguredMode(provider, mode, settings);
29867
+ }
29868
+ const explicitLegacy = settings?.autoApprove;
29869
+ const providerLegacyDefault = provider.settings?.autoApprove?.default;
29870
+ const legacyActive = typeof explicitLegacy === "boolean" ? explicitLegacy : typeof providerLegacyDefault === "boolean" ? providerLegacyDefault : false;
29871
+ if (!legacyActive) return inactiveMode();
29872
+ if (!config2) {
29873
+ return { active: true, strategy: "pty-parse-default", modeId: "legacy" };
29874
+ }
29875
+ const defaultMode = config2.modes.find((mode) => mode.id === config2.default);
29876
+ if (!defaultMode) return inactiveMode(config2.default);
29877
+ return resolveConfiguredMode(provider, defaultMode, settings);
29878
+ }
29879
+ function findProviderAutoApproveMode(provider, modeId) {
29880
+ return provider?.autoApproveModes?.modes.find((mode) => mode.id === modeId);
29881
+ }
29882
+ var KNOWN_DANGEROUS_LAUNCH_ARGS;
29883
+ var init_auto_approve_modes = __esm2({
29884
+ "src/providers/auto-approve-modes.ts"() {
29885
+ "use strict";
29886
+ KNOWN_DANGEROUS_LAUNCH_ARGS = /* @__PURE__ */ new Set([
29887
+ "--dangerously-skip-permissions",
29888
+ "--dangerously-bypass-approvals-and-sandbox",
29889
+ "bypassPermissions",
29890
+ "sandbox_mode=danger-full-access",
29891
+ "approval_policy=never"
29892
+ ]);
29893
+ }
29894
+ });
29841
29895
  function normalizeMeshSchedulingStrategy(value) {
29842
29896
  if (typeof value !== "string") return DEFAULT_MESH_SCHEDULING_STRATEGY;
29843
29897
  const trimmed = value.trim();
@@ -29923,6 +29977,11 @@ var require_dist3 = __commonJS({
29923
29977
  } else {
29924
29978
  delete policy.autoConvergeCodeChange;
29925
29979
  }
29980
+ if (policy.delegatedWorkerDangerousModeAllow === true) {
29981
+ policy.delegatedWorkerDangerousModeAllow = true;
29982
+ } else {
29983
+ delete policy.delegatedWorkerDangerousModeAllow;
29984
+ }
29926
29985
  if (policy.coordinatorIdlePushPolicy === "auto_silent_on_dispatch") {
29927
29986
  policy.coordinatorIdlePushPolicy = "auto_silent_on_dispatch";
29928
29987
  } else {
@@ -29930,14 +29989,35 @@ var require_dist3 = __commonJS({
29930
29989
  }
29931
29990
  return policy;
29932
29991
  }
29933
- function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy) {
29992
+ function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider) {
29993
+ let enabled = true;
29934
29994
  if (typeof nodePolicy?.delegatedWorkerAutoApprove === "boolean") {
29935
- return nodePolicy.delegatedWorkerAutoApprove;
29995
+ enabled = nodePolicy.delegatedWorkerAutoApprove;
29996
+ } else if (typeof meshPolicy?.delegatedWorkerAutoApprove === "boolean") {
29997
+ enabled = meshPolicy.delegatedWorkerAutoApprove;
29936
29998
  }
29937
- if (typeof meshPolicy?.delegatedWorkerAutoApprove === "boolean") {
29938
- return meshPolicy.delegatedWorkerAutoApprove;
29999
+ if (!enabled) return false;
30000
+ const modes = provider?.autoApproveModes;
30001
+ if (!modes) return true;
30002
+ const defaultMode = modes.modes.find((mode) => mode.id === modes.default);
30003
+ if (!defaultMode || defaultMode.strategy === "post-boot-command") return false;
30004
+ const dangerousAllowed = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
30005
+ if (deriveAutoApproveModeRisk(defaultMode) === "dangerous" && !dangerousAllowed) {
30006
+ const ptyFallback = modes.modes.find((mode) => mode.strategy === "pty-parse-default" && deriveAutoApproveModeRisk(mode) !== "dangerous");
30007
+ return ptyFallback?.id || false;
29939
30008
  }
29940
- return true;
30009
+ return defaultMode.id;
30010
+ }
30011
+ function resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy) {
30012
+ if (typeof nodePolicy?.delegatedWorkerDangerousModeAllow === "boolean") {
30013
+ return nodePolicy.delegatedWorkerDangerousModeAllow;
30014
+ }
30015
+ return meshPolicy?.delegatedWorkerDangerousModeAllow === true;
30016
+ }
30017
+ function delegatedWorkerAutoApproveSettings(meshPolicy, nodePolicy, provider) {
30018
+ const resolved = resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider);
30019
+ const delegatedWorkerDangerousModeAllow = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
30020
+ return typeof resolved === "string" ? { autoApprove: void 0, autoApproveMode: resolved, delegatedWorkerDangerousModeAllow } : { autoApprove: resolved, autoApproveMode: void 0, delegatedWorkerDangerousModeAllow };
29941
30021
  }
29942
30022
  function resolveAllowSendKeysDestructive(meshPolicy, nodePolicy) {
29943
30023
  if (typeof nodePolicy?.allowSendKeysDestructive === "boolean") {
@@ -29978,6 +30058,7 @@ var require_dist3 = __commonJS({
29978
30058
  var init_repo_mesh_types = __esm2({
29979
30059
  "src/repo-mesh-types.ts"() {
29980
30060
  "use strict";
30061
+ init_auto_approve_modes();
29981
30062
  MESH_SCHEDULING_STRATEGIES = [
29982
30063
  "first_eligible",
29983
30064
  "least_loaded",
@@ -30005,6 +30086,7 @@ var require_dist3 = __commonJS({
30005
30086
  // any specific session manually; that override is preserved per-device.
30006
30087
  spawnedSessionVisibility: "hidden",
30007
30088
  delegatedWorkerAutoApprove: true,
30089
+ delegatedWorkerDangerousModeAllow: false,
30008
30090
  sessionCleanupOnNodeRemove: "preserve",
30009
30091
  // MAGI auto-launches a worker session per pinned replica target with no idle
30010
30092
  // session; those stay idle-LIVE after their turn. Default ON (stop_and_delete)
@@ -30265,10 +30347,10 @@ var require_dist3 = __commonJS({
30265
30347
  }
30266
30348
  function getDaemonBuildInfo() {
30267
30349
  if (cached2) return cached2;
30268
- const commit = readInjected(true ? "64f056340da99d3b28464efcf5c05fe643e5db63" : void 0) ?? "unknown";
30269
- const commitShort = readInjected(true ? "64f05634" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30270
- const version2 = readInjected(true ? "1.0.18-rc.15" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30271
- const builtAt = readInjected(true ? "2026-07-23T00:53:09.129Z" : void 0);
30350
+ const commit = readInjected(true ? "eeb3e1474488eb5543c443270208f3ca8958a86a" : void 0) ?? "unknown";
30351
+ const commitShort = readInjected(true ? "eeb3e147" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30352
+ const version2 = readInjected(true ? "1.0.18-rc.17" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30353
+ const builtAt = readInjected(true ? "2026-07-23T03:31:27.486Z" : void 0);
30272
30354
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
30273
30355
  return cached2;
30274
30356
  }
@@ -46790,7 +46872,11 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
46790
46872
  meshNodeFor: meshId,
46791
46873
  meshNodeId: nodeId,
46792
46874
  launchedByCoordinator: true,
46793
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
46875
+ ...delegatedWorkerAutoApproveSettings(
46876
+ mesh?.policy,
46877
+ node?.policy,
46878
+ components.providerLoader?.getMeta(providerType)
46879
+ ),
46794
46880
  ...localDaemonId ? { meshCoordinatorDaemonId: localDaemonId } : {},
46795
46881
  // COMPLETION-PROPAGATION F5: (re)stamp the coordinator SESSION anchor from THIS
46796
46882
  // task's sourceCoordinatorSessionId with PRIORITY — a manually-launched (or reused)
@@ -47563,8 +47649,12 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
47563
47649
  spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
47564
47650
  // Coordinator-dispatched worker: auto-approve unless mesh/node policy
47565
47651
  // opts out (default true). Lands in settingsOverride and beats the
47566
- // global per-provider-type autoApprove config (see shouldAutoApprove).
47567
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
47652
+ // global per-provider-type boolean/mode through explicit opposite-key clearing.
47653
+ ...delegatedWorkerAutoApproveSettings(
47654
+ mesh?.policy,
47655
+ node?.policy,
47656
+ components.providerLoader?.getMeta(resolved.providerType)
47657
+ ),
47568
47658
  launchedByCoordinator: true,
47569
47659
  autoLaunchedForQueueTaskId: task.id
47570
47660
  };
@@ -49165,6 +49255,26 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
49165
49255
  }
49166
49256
  return null;
49167
49257
  }
49258
+ function hasTrailingToolActivityAfterFinalAssistant(messages) {
49259
+ if (!Array.isArray(messages) || messages.length === 0) return false;
49260
+ let sawTrailingToolActivity = false;
49261
+ for (let i = messages.length - 1; i >= 0; i--) {
49262
+ const msg = messages[i];
49263
+ if (!msg) continue;
49264
+ const classification = classifyChatMessageVisibility(msg);
49265
+ if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
49266
+ if (flattenContent(msg.content).trim()) return sawTrailingToolActivity;
49267
+ return false;
49268
+ }
49269
+ if (classification.isUserFacing) {
49270
+ return false;
49271
+ }
49272
+ if (classification.kind === "tool" || classification.kind === "terminal") {
49273
+ sawTrailingToolActivity = true;
49274
+ }
49275
+ }
49276
+ return false;
49277
+ }
49168
49278
  function canonicalizeKindHint(value) {
49169
49279
  return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
49170
49280
  }
@@ -50416,6 +50526,7 @@ ${cleanBody}`;
50416
50526
  ...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
50417
50527
  ...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
50418
50528
  ...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
50529
+ ...provider.autoApproveModes !== void 0 ? { autoApproveModes: provider.autoApproveModes } : {},
50419
50530
  ...trust ? {
50420
50531
  trust,
50421
50532
  trustDescription: describeTrust2(trust),
@@ -51595,7 +51706,11 @@ ${cleanBody}`;
51595
51706
  spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
51596
51707
  // Coordinator-dispatched recovery relaunch: same auto-approve
51597
51708
  // policy as the primary worker launch path.
51598
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
51709
+ ...delegatedWorkerAutoApproveSettings(
51710
+ mesh?.policy,
51711
+ node?.policy,
51712
+ components.providerLoader?.getMeta(recoveryContext.failedProviderType)
51713
+ ),
51599
51714
  launchedByCoordinator: true
51600
51715
  }
51601
51716
  }).catch((e) => LOG2.error("MeshRecovery", `Failed to auto-relaunch session for ${node.id}: ${e?.message}`));
@@ -52864,6 +52979,7 @@ ${cleanBody}`;
52864
52979
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
52865
52980
  const evidence = extractFinalAssistantSummaryEvidence(messages);
52866
52981
  if (!evidence.finalSummary) return null;
52982
+ if (hasTrailingToolActivityAfterFinalAssistant(messages)) return null;
52867
52983
  const dispatchedAtMs = Date.parse(readNonEmptyString(row.dispatchTimestamp));
52868
52984
  const transcriptAtMs = Date.parse(evidence.transcriptMessageAt ?? "");
52869
52985
  if (!(Number.isFinite(dispatchedAtMs) && Number.isFinite(transcriptAtMs) && transcriptAtMs >= dispatchedAtMs)) {
@@ -53154,6 +53270,52 @@ ${cleanBody}`;
53154
53270
  return false;
53155
53271
  }
53156
53272
  }
53273
+ function resolveLocalSessionPurePty(components, sessionId) {
53274
+ try {
53275
+ const instances = components.instanceManager?.getByCategory?.("cli") || [];
53276
+ const inst = instances.find((i) => {
53277
+ const sid = readNonEmptyString(i?.getState?.().instanceId);
53278
+ return sid && sessionIdsEquivalent(sid, sessionId);
53279
+ });
53280
+ if (!inst) return void 0;
53281
+ const provider = inst.provider;
53282
+ if (!provider || typeof provider !== "object") return void 0;
53283
+ return isPurePtyTranscriptProvider(provider);
53284
+ } catch {
53285
+ return void 0;
53286
+ }
53287
+ }
53288
+ async function evaluateEarlyIdleTranscriptArm(components, mesh, store, row, localDaemonId, selfIds = []) {
53289
+ const sessionId = readNonEmptyString(row.assignedSessionId);
53290
+ if (!sessionId) return false;
53291
+ const verdict = resolveSessionBusyVerdict(components, sessionId);
53292
+ if (verdict === "GENERATING") return false;
53293
+ if (verdict === "UNKNOWN") {
53294
+ const nodeId = readNonEmptyString(row.assignedNodeId);
53295
+ const node = (mesh.nodes ?? []).find((n) => n.id === nodeId);
53296
+ const liveStatus = nodeId ? readNonEmptyString(sessionStatusFromNodes(mesh.nodes, nodeId, sessionId).status).toLowerCase() : "";
53297
+ if (liveStatus && liveStatus !== "idle") return false;
53298
+ if (!liveStatus) {
53299
+ const nodeDaemonId = readNonEmptyString(node?.daemonId);
53300
+ const isLocalNode = !nodeDaemonId || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || daemonIdListIncludes(selfIds, nodeDaemonId) || !!components.instanceManager?.getInstance?.(sessionId);
53301
+ const providerType = readNonEmptyString(row.assignedProviderType);
53302
+ const readArgs = {
53303
+ sessionId,
53304
+ targetSessionId: sessionId,
53305
+ tailLimit: 1,
53306
+ ...node?.workspace ? { workspace: node.workspace } : {},
53307
+ ...providerType ? { agentType: providerType, providerType } : {}
53308
+ };
53309
+ const probedStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
53310
+ if (probedStatus !== "idle") return false;
53311
+ }
53312
+ }
53313
+ if (store.taskDeliveryConsumed(mesh.id, row.id)) return true;
53314
+ const localPurePty = resolveLocalSessionPurePty(components, sessionId);
53315
+ if (localPurePty === true) return true;
53316
+ if (localPurePty === false) return false;
53317
+ return verdict === "UNKNOWN";
53318
+ }
53157
53319
  async function recoverStrandedAssignedDispatches(components, mesh, store, localDaemonId, selfIds = []) {
53158
53320
  const meshId = mesh.id;
53159
53321
  const assigned = getQueue(meshId, { status: ["assigned"] });
@@ -53175,7 +53337,8 @@ ${cleanBody}`;
53175
53337
  if (!Number.isFinite(dispatchedAtMs)) continue;
53176
53338
  const ageMs = nowMs - dispatchedAtMs;
53177
53339
  const idleTranscriptStreakKey = `${meshId}::${row.id}`;
53178
- if (store.taskHasConfirmedDelivery(meshId, row.id) && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id }) && readNonEmptyString(row.assignedSessionId) && resolveSessionBusyVerdict(components, row.assignedSessionId) !== "GENERATING") {
53340
+ const earlyArm = store.taskHasConfirmedDelivery(meshId, row.id) && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id }) && readNonEmptyString(row.assignedSessionId) ? await evaluateEarlyIdleTranscriptArm(components, mesh, store, row, localDaemonId, selfIds) : false;
53341
+ if (earlyArm) {
53179
53342
  const since = assignedIdleFinalAssistantSince.get(idleTranscriptStreakKey);
53180
53343
  if (since === void 0) {
53181
53344
  assignedIdleFinalAssistantSince.set(idleTranscriptStreakKey, nowMs);
@@ -53932,6 +54095,7 @@ ${cleanBody}`;
53932
54095
  init_mesh_reconcile_identity();
53933
54096
  init_mesh_reconcile_config();
53934
54097
  init_mesh_remote_event_pull();
54098
+ init_provider_cli_shared();
53935
54099
  init_mesh_disk_retention();
53936
54100
  init_mesh_completion_synthesis();
53937
54101
  init_mesh_active_work();
@@ -54211,6 +54375,20 @@ ${cleanBody}`;
54211
54375
  }
54212
54376
  }
54213
54377
  },
54378
+ autoApproveModes: {
54379
+ type: "object",
54380
+ description: "Provider-specific auto-approve choices and their launch/runtime strategy.",
54381
+ required: ["default", "modes"],
54382
+ additionalProperties: false,
54383
+ properties: {
54384
+ default: { type: "string", minLength: 1 },
54385
+ modes: {
54386
+ type: "array",
54387
+ minItems: 1,
54388
+ items: { $ref: "#/$defs/autoApproveMode" }
54389
+ }
54390
+ }
54391
+ },
54214
54392
  sendDelayMs: {
54215
54393
  type: "number",
54216
54394
  minimum: 0,
@@ -54584,6 +54762,36 @@ ${cleanBody}`;
54584
54762
  }
54585
54763
  },
54586
54764
  $defs: {
54765
+ autoApproveMode: {
54766
+ type: "object",
54767
+ required: ["id", "label", "strategy", "risk"],
54768
+ additionalProperties: false,
54769
+ properties: {
54770
+ id: { type: "string", minLength: 1 },
54771
+ label: { type: "string", minLength: 1 },
54772
+ strategy: { enum: ["pty-parse-default", "launch-args", "post-boot-command"] },
54773
+ risk: { enum: ["safe", "caution", "dangerous"] },
54774
+ warning: { type: "string", minLength: 1 },
54775
+ launchArgs: {
54776
+ type: "array",
54777
+ items: { type: "string", minLength: 1 }
54778
+ },
54779
+ removeArgs: {
54780
+ type: "array",
54781
+ items: { type: "string", minLength: 1 }
54782
+ }
54783
+ },
54784
+ allOf: [
54785
+ {
54786
+ if: { properties: { strategy: { const: "launch-args" } }, required: ["strategy"] },
54787
+ then: { required: ["launchArgs"], properties: { launchArgs: { minItems: 1 } } }
54788
+ },
54789
+ {
54790
+ if: { properties: { risk: { const: "dangerous" } }, required: ["risk"] },
54791
+ then: { required: ["warning"] }
54792
+ }
54793
+ ]
54794
+ },
54587
54795
  patternList: {
54588
54796
  type: "array",
54589
54797
  items: {
@@ -60463,6 +60671,7 @@ ${lastSnapshot}`;
60463
60671
  createSessionDelivery: () => createSessionDelivery,
60464
60672
  createWorktree: () => createWorktree,
60465
60673
  daemonIdsEquivalent: () => daemonIdsEquivalent,
60674
+ delegatedWorkerAutoApproveSettings: () => delegatedWorkerAutoApproveSettings,
60466
60675
  deleteDirectDispatchesByTaskId: () => deleteDirectDispatchesByTaskId,
60467
60676
  deleteMesh: () => deleteMesh,
60468
60677
  deriveMeshNodeHealthFromGit: () => deriveMeshNodeHealthFromGit,
@@ -60662,6 +60871,7 @@ ${lastSnapshot}`;
60662
60871
  resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
60663
60872
  resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
60664
60873
  resolveDelegatedWorkerAutoApprove: () => resolveDelegatedWorkerAutoApprove,
60874
+ resolveDelegatedWorkerDangerousModeAllow: () => resolveDelegatedWorkerDangerousModeAllow,
60665
60875
  resolveDeliveryDecision: () => resolveDeliveryDecision,
60666
60876
  resolveEffectiveMeshNodeHealth: () => resolveEffectiveMeshNodeHealth,
60667
60877
  resolveGitRepository: () => resolveGitRepository,
@@ -79151,6 +79361,7 @@ ${body}
79151
79361
  const pad = (value) => String(value).padStart(2, "0");
79152
79362
  return `${date5.getFullYear()}-${pad(date5.getMonth() + 1)}-${pad(date5.getDate())} ${pad(date5.getHours())}:${pad(date5.getMinutes())}:${pad(date5.getSeconds())}`;
79153
79363
  }
79364
+ init_auto_approve_modes();
79154
79365
  function approvalModalSignature(message, affirmativeAnchor) {
79155
79366
  return [typeof message === "string" ? message.trim() : "", affirmativeAnchor].join("::");
79156
79367
  }
@@ -81131,7 +81342,7 @@ ${body}
81131
81342
  * resolveModal, so a plain turn that never saw an approval always returns false.
81132
81343
  */
81133
81344
  inApprovalResumeGrace(now = Date.now()) {
81134
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return false;
81345
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return false;
81135
81346
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
81136
81347
  if (resolvedAt <= 0) return false;
81137
81348
  return now - resolvedAt < _CliProviderInstance.APPROVAL_RESUME_GRACE_MS;
@@ -81236,7 +81447,7 @@ ${body}
81236
81447
  return;
81237
81448
  }
81238
81449
  const latestStatus = this.adapter.getStatus({ allowParse: false });
81239
- const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
81450
+ const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
81240
81451
  const latestVisibleStatus = latestAutoApproveActive || this.autoApproveBusy ? "generating" : latestStatus.status;
81241
81452
  LOG2.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
81242
81453
  if (latestVisibleStatus !== "idle") {
@@ -81506,7 +81717,7 @@ ${body}
81506
81717
  * session, where a human answers the prompt, is returned untouched).
81507
81718
  */
81508
81719
  stabilizeFlappingApprovalStatus(adapterStatus, now = Date.now()) {
81509
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return adapterStatus;
81720
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return adapterStatus;
81510
81721
  const rawStatus = adapterStatus?.status;
81511
81722
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
81512
81723
  if (rawStatus === "waiting_approval") {
@@ -81536,7 +81747,11 @@ ${body}
81536
81747
  return adapterStatus;
81537
81748
  }
81538
81749
  maybeAutoApproveStatus(adapterStatus, now = Date.now()) {
81539
- if (adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove() && this.manualAttendance.isAttended(now)) {
81750
+ if (!this.shouldUsePtyAutoApprove()) {
81751
+ this.resetPtyAutoApproveState();
81752
+ return false;
81753
+ }
81754
+ if (adapterStatus?.status === "waiting_approval" && this.shouldUsePtyAutoApprove() && this.manualAttendance.isAttended(now)) {
81540
81755
  this.lastAutoApprovalSignature = "";
81541
81756
  this.pendingAutoApprovalSignature = "";
81542
81757
  this.pendingAutoApprovalSince = 0;
@@ -81551,7 +81766,7 @@ ${body}
81551
81766
  }, this.manualAttendance.remainingMs(now) + 20);
81552
81767
  return false;
81553
81768
  }
81554
- const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove();
81769
+ const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
81555
81770
  if (!autoApproveActive) {
81556
81771
  this.lastAutoApprovalSignature = "";
81557
81772
  if (this.pendingAutoApprovalSince) {
@@ -82246,15 +82461,34 @@ ${buttons.join("\n")}`;
82246
82461
  get cliName() {
82247
82462
  return this.provider.name;
82248
82463
  }
82464
+ resolveAutoApproveMode() {
82465
+ return resolveProviderAutoApproveMode(this.provider, this.settings);
82466
+ }
82467
+ /** Legacy boolean view retained for internal/test compatibility. */
82249
82468
  shouldAutoApprove() {
82250
- if (typeof this.settings.autoApprove === "boolean") {
82251
- return this.settings.autoApprove;
82469
+ return this.resolveAutoApproveMode().active;
82470
+ }
82471
+ shouldUsePtyAutoApprove() {
82472
+ const resolved = this.resolveAutoApproveMode();
82473
+ return this.shouldAutoApprove() && resolved.strategy === "pty-parse-default";
82474
+ }
82475
+ resetPtyAutoApproveState() {
82476
+ this.lastAutoApprovalSignature = "";
82477
+ this.pendingAutoApprovalSignature = "";
82478
+ this.pendingAutoApprovalSince = 0;
82479
+ this.autoApproveInactiveSince = 0;
82480
+ this.autoApproveMaskSince = 0;
82481
+ this.stalledApprovalNudgeEpisode = 0;
82482
+ this.autoApproveLastModalSeenAt = 0;
82483
+ this.autoApproveBusy = false;
82484
+ if (this.autoApproveSettleTimer) {
82485
+ clearTimeout(this.autoApproveSettleTimer);
82486
+ this.autoApproveSettleTimer = null;
82252
82487
  }
82253
- const providerDefault = this.provider.settings?.autoApprove?.default;
82254
- if (typeof providerDefault === "boolean") {
82255
- return providerDefault;
82488
+ if (this.autoApproveBusyTimer) {
82489
+ clearTimeout(this.autoApproveBusyTimer);
82490
+ this.autoApproveBusyTimer = null;
82256
82491
  }
82257
- return false;
82258
82492
  }
82259
82493
  /** @see ProviderInstance.noteManualInteraction */
82260
82494
  noteManualInteraction(now = Date.now(), opts) {
@@ -82270,7 +82504,7 @@ ${buttons.join("\n")}`;
82270
82504
  * CLI-specific modal text.
82271
82505
  */
82272
82506
  autoApproveEffectivelyActive(status, now = Date.now()) {
82273
- return status === "waiting_approval" && this.shouldAutoApprove() && !this.manualAttendance.isAttended(now);
82507
+ return status === "waiting_approval" && this.shouldUsePtyAutoApprove() && !this.manualAttendance.isAttended(now);
82274
82508
  }
82275
82509
  // STATUS-MISMATCH: true once the current auto-approve episode has been masking
82276
82510
  // waiting_approval behind `generating` for longer than AUTO_APPROVE_MASK_STALL_MS without
@@ -82280,7 +82514,7 @@ ${buttons.join("\n")}`;
82280
82514
  // maybeAutoApproveStatus (driven by getState + the recheck timer during a waiting episode);
82281
82515
  // this read is side-effect-free so getStatusMetadata can consult it too.
82282
82516
  autoApproveMaskStalled(now = Date.now()) {
82283
- return this.autoApproveMaskSince > 0 && now - this.autoApproveMaskSince > _CliProviderInstance.AUTO_APPROVE_MASK_STALL_MS;
82517
+ return this.shouldUsePtyAutoApprove() && this.autoApproveMaskSince > 0 && now - this.autoApproveMaskSince > _CliProviderInstance.AUTO_APPROVE_MASK_STALL_MS;
82284
82518
  }
82285
82519
  /**
82286
82520
  * NOTIF-APPROVAL-MASKED (Q1b): surface a delegated worker's STALLED auto-approve modal
@@ -82304,6 +82538,7 @@ ${buttons.join("\n")}`;
82304
82538
  * mask-clock value) so a modal that flaps between parsed/unparsed states is announced once.
82305
82539
  */
82306
82540
  maybeEmitStalledApprovalNudge(adapterStatus, now) {
82541
+ if (!this.shouldUsePtyAutoApprove()) return;
82307
82542
  if (!this.isMeshWorkerSession()) return;
82308
82543
  if (adapterStatus?.status !== "waiting_approval") return;
82309
82544
  if (!this.autoApproveMaskStalled(now)) return;
@@ -83836,6 +84071,7 @@ ${rawInput}` : rawInput;
83836
84071
  if (!managedBy) return true;
83837
84072
  return managedBy === managerTag;
83838
84073
  }
84074
+ init_auto_approve_modes();
83839
84075
  function isExplicitCommand(command) {
83840
84076
  const trimmed = command.trim();
83841
84077
  return path30.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
@@ -84062,6 +84298,24 @@ ${rawInput}` : rawInput;
84062
84298
  const mapped = levelMap && typeof levelMap[raw] === "string" && levelMap[raw].trim() ? levelMap[raw].trim() : raw;
84063
84299
  return template.map((part) => part.includes("{{level}}") ? part.replace("{{level}}", mapped) : part);
84064
84300
  }
84301
+ function matchesRemovedLaunchArg(arg, removeArg) {
84302
+ return arg === removeArg || removeArg.startsWith("--") && arg.startsWith(`${removeArg}=`);
84303
+ }
84304
+ function applyAutoApproveModeLaunchArgs(provider, cliArgs, settings) {
84305
+ if (!provider) return { provider, cliArgs };
84306
+ const resolved = resolveProviderAutoApproveMode(provider, settings);
84307
+ if (!resolved.active || resolved.strategy !== "launch-args") return { provider, cliArgs };
84308
+ const mode = findProviderAutoApproveMode(provider, resolved.modeId);
84309
+ if (!mode || !Array.isArray(mode.launchArgs) || mode.launchArgs.length === 0) return { provider, cliArgs };
84310
+ const removeArgs = Array.isArray(mode.removeArgs) ? mode.removeArgs : [];
84311
+ const baseArgs = provider.spawn?.args;
84312
+ const filteredBaseArgs = Array.isArray(baseArgs) && removeArgs.length > 0 ? baseArgs.filter((arg) => !removeArgs.some((removeArg) => matchesRemovedLaunchArg(arg, removeArg))) : baseArgs;
84313
+ const launchProvider = filteredBaseArgs === baseArgs ? provider : { ...provider, spawn: { ...provider.spawn, args: filteredBaseArgs } };
84314
+ return {
84315
+ provider: launchProvider,
84316
+ cliArgs: [...mode.launchArgs, ...cliArgs || []]
84317
+ };
84318
+ }
84065
84319
  function readSubcommandSessionId(args, subcommands) {
84066
84320
  const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
84067
84321
  if (resumeIndex < 0) return void 0;
@@ -84492,22 +84746,30 @@ Run 'adhdev doctor' for detailed diagnostics.`
84492
84746
  if (provider) {
84493
84747
  console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
84494
84748
  }
84495
- const modelLaunchArgs = expandModelLaunchArgs(provider?.modelLaunchArgs, initialModel);
84496
- const cliArgsWithModel = modelLaunchArgs ? [...modelLaunchArgs, ...cliArgs || []] : cliArgs;
84749
+ const launchSettings = {
84750
+ ...this.providerLoader.getSettings(normalizedType),
84751
+ ...options?.settingsOverride || {}
84752
+ };
84753
+ const versionResolvedProvider = provider ? this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider : void 0;
84754
+ const autoApproveLaunch = applyAutoApproveModeLaunchArgs(versionResolvedProvider, cliArgs, launchSettings);
84755
+ const launchProvider = autoApproveLaunch.provider || provider;
84756
+ const cliArgsWithAutoApprove = autoApproveLaunch.cliArgs;
84757
+ const modelLaunchArgs = expandModelLaunchArgs(launchProvider?.modelLaunchArgs, initialModel);
84758
+ const cliArgsWithModel = modelLaunchArgs ? [...modelLaunchArgs, ...cliArgsWithAutoApprove || []] : cliArgsWithAutoApprove;
84497
84759
  if (initialModel && !modelLaunchArgs) {
84498
84760
  LOG2.warn("CLI", `[${normalizedType}] initialModel='${initialModel}' requested but provider declares no modelLaunchArgs template \u2014 launching without model selection.`);
84499
84761
  }
84500
84762
  const initialThinkingLevel = options?.initialThinkingLevel;
84501
- const thinkingLaunchArgs = expandThinkingLaunchArgs(provider?.thinkingLaunchArgs, initialThinkingLevel, provider?.thinkingLevelMap);
84763
+ const thinkingLaunchArgs = expandThinkingLaunchArgs(launchProvider?.thinkingLaunchArgs, initialThinkingLevel, launchProvider?.thinkingLevelMap);
84502
84764
  const cliArgsWithBrain = thinkingLaunchArgs ? [...thinkingLaunchArgs, ...cliArgsWithModel || []] : cliArgsWithModel;
84503
84765
  if (initialThinkingLevel && !thinkingLaunchArgs) {
84504
84766
  LOG2.warn("CLI", `[${normalizedType}] initialThinkingLevel='${initialThinkingLevel}' requested but provider declares no thinkingLaunchArgs template \u2014 launching without thinking-level selection.`);
84505
84767
  }
84506
- const sessionBinding = resolveCliSessionBinding(provider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
84768
+ const sessionBinding = resolveCliSessionBinding(launchProvider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
84507
84769
  const resolvedCliArgs = sessionBinding.cliArgs;
84508
84770
  const instanceManager = this.deps.getInstanceManager();
84509
- if (provider && instanceManager) {
84510
- const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
84771
+ if (launchProvider && instanceManager) {
84772
+ const resolvedProvider = launchProvider;
84511
84773
  await this.registerCliInstance(
84512
84774
  key2,
84513
84775
  normalizedType,
@@ -84515,7 +84777,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
84515
84777
  resolvedDir,
84516
84778
  resolvedCliArgs,
84517
84779
  resolvedProvider,
84518
- { ...this.providerLoader.getSettings(normalizedType), ...options?.settingsOverride || {} },
84780
+ launchSettings,
84519
84781
  false,
84520
84782
  {
84521
84783
  providerSessionId: sessionBinding.providerSessionId,
@@ -85346,6 +85608,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
85346
85608
  var chokidar = __toESM2(require_chokidar());
85347
85609
  init_hash();
85348
85610
  init_logger();
85611
+ init_auto_approve_modes();
85349
85612
  init_open_panel_support();
85350
85613
  var VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
85351
85614
  var VALID_INPUT_STRATEGIES2 = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
@@ -85411,6 +85674,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
85411
85674
  "providerVersion",
85412
85675
  "status",
85413
85676
  "details",
85677
+ "autoApproveModes",
85414
85678
  "modelLaunchArgs",
85415
85679
  "modelOptions",
85416
85680
  "thinkingLaunchArgs",
@@ -85472,6 +85736,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
85472
85736
  validateCapabilities(provider, controls, errors);
85473
85737
  validateNativeHistory(provider.nativeHistory, errors);
85474
85738
  validateMeshCoordinator(provider.meshCoordinator, errors);
85739
+ validateAutoApproveModes(provider.autoApproveModes, errors);
85475
85740
  for (const control of controls) {
85476
85741
  validateControl(control, errors);
85477
85742
  }
@@ -85480,6 +85745,75 @@ Run 'adhdev doctor' for detailed diagnostics.`
85480
85745
  }
85481
85746
  return { errors, warnings };
85482
85747
  }
85748
+ function validateAutoApproveModes(raw, errors) {
85749
+ if (raw === void 0) return;
85750
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
85751
+ errors.push("autoApproveModes must be an object");
85752
+ return;
85753
+ }
85754
+ const config2 = raw;
85755
+ const defaultModeId = typeof config2.default === "string" ? config2.default.trim() : "";
85756
+ if (!defaultModeId) {
85757
+ errors.push("autoApproveModes.default must be a non-empty string");
85758
+ } else {
85759
+ config2.default = defaultModeId;
85760
+ }
85761
+ if (!Array.isArray(config2.modes) || config2.modes.length === 0) {
85762
+ errors.push("autoApproveModes.modes must be a non-empty array");
85763
+ return;
85764
+ }
85765
+ const ids = /* @__PURE__ */ new Set();
85766
+ for (const [index, rawMode] of config2.modes.entries()) {
85767
+ const prefix = `autoApproveModes.modes[${index}]`;
85768
+ if (!rawMode || typeof rawMode !== "object" || Array.isArray(rawMode)) {
85769
+ errors.push(`${prefix} must be an object`);
85770
+ continue;
85771
+ }
85772
+ const mode = rawMode;
85773
+ const id = typeof mode.id === "string" ? mode.id.trim() : "";
85774
+ if (!id) {
85775
+ errors.push(`${prefix}.id must be a non-empty string`);
85776
+ } else if (ids.has(id)) {
85777
+ errors.push(`${prefix}.id must be unique (duplicate: ${id})`);
85778
+ } else {
85779
+ ids.add(id);
85780
+ mode.id = id;
85781
+ }
85782
+ if (typeof mode.label !== "string" || !mode.label.trim()) {
85783
+ errors.push(`${prefix}.label must be a non-empty string`);
85784
+ }
85785
+ const strategy = mode.strategy;
85786
+ if (!["pty-parse-default", "launch-args", "post-boot-command"].includes(String(strategy))) {
85787
+ errors.push(`${prefix}.strategy must be one of: pty-parse-default, launch-args, post-boot-command`);
85788
+ } else if (strategy === "post-boot-command") {
85789
+ errors.push(`${prefix}.strategy post-boot-command is reserved and unsupported in v1`);
85790
+ }
85791
+ const risk = mode.risk;
85792
+ if (!["safe", "caution", "dangerous"].includes(String(risk))) {
85793
+ errors.push(`${prefix}.risk must be one of: safe, caution, dangerous`);
85794
+ }
85795
+ for (const field of ["launchArgs", "removeArgs"]) {
85796
+ const value = mode[field];
85797
+ if (value !== void 0 && (!Array.isArray(value) || value.some((arg) => typeof arg !== "string" || !arg.trim()))) {
85798
+ errors.push(`${prefix}.${field} must be an array of non-empty strings when provided`);
85799
+ }
85800
+ }
85801
+ if (strategy === "launch-args" && (!Array.isArray(mode.launchArgs) || mode.launchArgs.length === 0)) {
85802
+ errors.push(`${prefix}.launchArgs must be a non-empty array for launch-args strategy`);
85803
+ }
85804
+ if (["safe", "caution", "dangerous"].includes(String(risk)) && deriveAutoApproveModeRisk(mode) === "dangerous") {
85805
+ mode.risk = "dangerous";
85806
+ }
85807
+ if (mode.risk === "dangerous" && (typeof mode.warning !== "string" || !mode.warning.trim())) {
85808
+ errors.push(`${prefix}.warning is required for dangerous modes`);
85809
+ } else if (mode.warning !== void 0 && (typeof mode.warning !== "string" || !mode.warning.trim())) {
85810
+ errors.push(`${prefix}.warning must be a non-empty string when provided`);
85811
+ }
85812
+ }
85813
+ if (defaultModeId && !ids.has(defaultModeId)) {
85814
+ errors.push(`autoApproveModes.default must reference an existing mode id: ${defaultModeId}`);
85815
+ }
85816
+ }
85483
85817
  function validateCapabilities(provider, controls, errors) {
85484
85818
  const capabilities = provider.capabilities;
85485
85819
  if (provider.contractVersion === 2) {