feat: file_permission interaction + DOM Observer RPC passthrough

This commit is contained in:
2026-03-10 10:54:28 +09:00
parent 563fbadd5a
commit df592723b7
3 changed files with 35 additions and 5 deletions

View File

@@ -1983,6 +1983,13 @@ async function processResponseFile(filePath) {
|| pending.source === 'dom_observer';
pendingStepType = pending.step_type || '';
pendingStepIndex = pending.step_index ?? lastPendingStepIndex;
// Infer step_type from cmd if not explicitly set
if (!pendingStepType && pending.command) {
const cmd = (pending.command || '').toLowerCase();
if (cmd.includes('allow once') || cmd.includes('allow this conversation')) {
pendingStepType = 'file_permission';
}
}
}
catch { }
}
@@ -1992,8 +1999,10 @@ async function processResponseFile(filePath) {
// Step probe/stall: try RPC → VS Code commands → log results
const approved = resp.approved;
if (isDomObserver) {
// DOM observer path: renderer polls /response/:rid and clicks directly
logToFile(`[RESPONSE] renderer-handled approval (rid=${resp.request_id})`);
// DOM observer path: ALSO try RPC strategies (renderer click is unreliable)
logToFile(`[RESPONSE] dom_observer → tryApprovalStrategies(${approved}, ${activeSessionId.substring(0, 8)}, type=${pendingStepType}, step=${pendingStepIndex})`);
const strategyResult = await tryApprovalStrategies(approved, activeSessionId, pendingStepType, pendingStepIndex);
logToFile(`[RESPONSE] dom strategy result: ${strategyResult}`);
}
else {
// Step probe path: run ALL approval strategies
@@ -2286,6 +2295,13 @@ async function tryApprovalStrategies(approved, sessionId, stepType = '', stepInd
else if (typeLower.includes('invoke_subagent') || typeLower.includes('extension_code')) {
interactionPayload = { runExtensionCode: { confirm: true } };
}
else if (typeLower.includes('file_permission')) {
// FilePermissionInteraction: allow=true, scope=ONCE(1) or CONVERSATION(2)
interactionPayload = { filePermission: { allow: true, scope: 1 } }; // PERMISSION_SCOPE_ONCE
}
else if (typeLower.includes('elicitation')) {
interactionPayload = { elicitation: {} }; // ElicitationInteraction (TBD)
}
else {
// Default: try run_command (most common)
interactionPayload = { runCommand: { confirm: true } };

File diff suppressed because one or more lines are too long

View File

@@ -1939,6 +1939,13 @@ async function processResponseFile(filePath: string) {
|| pending.source === 'dom_observer';
pendingStepType = pending.step_type || '';
pendingStepIndex = pending.step_index ?? lastPendingStepIndex;
// Infer step_type from cmd if not explicitly set
if (!pendingStepType && pending.command) {
const cmd = (pending.command || '').toLowerCase();
if (cmd.includes('allow once') || cmd.includes('allow this conversation')) {
pendingStepType = 'file_permission';
}
}
} catch { }
}
@@ -1950,8 +1957,10 @@ async function processResponseFile(filePath: string) {
const approved = resp.approved;
if (isDomObserver) {
// DOM observer path: renderer polls /response/:rid and clicks directly
logToFile(`[RESPONSE] renderer-handled approval (rid=${resp.request_id})`);
// DOM observer path: ALSO try RPC strategies (renderer click is unreliable)
logToFile(`[RESPONSE] dom_observer → tryApprovalStrategies(${approved}, ${activeSessionId.substring(0, 8)}, type=${pendingStepType}, step=${pendingStepIndex})`);
const strategyResult = await tryApprovalStrategies(approved, activeSessionId, pendingStepType, pendingStepIndex);
logToFile(`[RESPONSE] dom strategy result: ${strategyResult}`);
} else {
// Step probe path: run ALL approval strategies
logToFile(`[RESPONSE] step_probe → tryApprovalStrategies(${approved}, ${activeSessionId.substring(0, 8)}, type=${pendingStepType}, step=${pendingStepIndex})`);
@@ -2226,6 +2235,11 @@ async function tryApprovalStrategies(approved: boolean, sessionId: string, stepT
interactionPayload = { mcpTool: { confirm: true } }; // guess
} else if (typeLower.includes('invoke_subagent') || typeLower.includes('extension_code')) {
interactionPayload = { runExtensionCode: { confirm: true } };
} else if (typeLower.includes('file_permission')) {
// FilePermissionInteraction: allow=true, scope=ONCE(1) or CONVERSATION(2)
interactionPayload = { filePermission: { allow: true, scope: 1 } }; // PERMISSION_SCOPE_ONCE
} else if (typeLower.includes('elicitation')) {
interactionPayload = { elicitation: {} }; // ElicitationInteraction (TBD)
} else {
// Default: try run_command (most common)
interactionPayload = { runCommand: { confirm: true } };