@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/commands/cli-manager.d.ts +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +372 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +370 -34
- package/dist/index.mjs.map +1 -1
- package/dist/providers/auto-approve-modes.d.ts +14 -0
- package/dist/providers/chat-message-normalization.d.ts +22 -0
- package/dist/providers/cli-provider-instance.d.ts +4 -0
- package/dist/providers/contracts.d.ts +17 -0
- package/dist/providers/provider-schema.d.ts +1 -0
- package/dist/repo-mesh-types.d.ts +16 -6
- package/dist/shared-types.d.ts +3 -1
- package/package.json +3 -3
- package/src/commands/cli-manager.ts +54 -8
- package/src/index.ts +3 -1
- package/src/mesh/mesh-completion-synthesis.ts +12 -1
- package/src/mesh/mesh-event-forwarding.ts +6 -2
- package/src/mesh/mesh-queue-assignment.ts +13 -6
- package/src/mesh/mesh-reconcile-loop.ts +124 -4
- package/src/providers/auto-approve-modes.ts +97 -0
- package/src/providers/chat-message-normalization.ts +53 -0
- package/src/providers/cli-provider-instance.ts +45 -13
- package/src/providers/contracts.ts +25 -1
- package/src/providers/provider-schema.ts +83 -0
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +44 -0
- package/src/repo-mesh-types.ts +65 -12
- package/src/shared-types.ts +3 -1
- package/src/status/snapshot.ts +2 -0
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
|
-
|
|
190
|
+
enabled = nodePolicy.delegatedWorkerAutoApprove;
|
|
191
|
+
} else if (typeof meshPolicy?.delegatedWorkerAutoApprove === "boolean") {
|
|
192
|
+
enabled = meshPolicy.delegatedWorkerAutoApprove;
|
|
129
193
|
}
|
|
130
|
-
if (
|
|
131
|
-
|
|
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
|
|
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 ? "
|
|
446
|
-
const commitShort = readInjected(true ? "
|
|
447
|
-
const version = readInjected(true ? "1.0.18-rc.
|
|
448
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
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
|
-
|
|
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
|
|
17609
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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 (
|
|
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.
|
|
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
|
-
|
|
52463
|
-
|
|
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
|
-
|
|
52466
|
-
|
|
52467
|
-
|
|
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.
|
|
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
|
|
54716
|
-
|
|
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(
|
|
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(
|
|
54990
|
+
const sessionBinding = resolveCliSessionBinding(launchProvider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
|
|
54727
54991
|
const resolvedCliArgs = sessionBinding.cliArgs;
|
|
54728
54992
|
const instanceManager = this.deps.getInstanceManager();
|
|
54729
|
-
if (
|
|
54730
|
-
const resolvedProvider =
|
|
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
|
-
|
|
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,
|