新增: 路径授权三档化 once/session/always

Phase B 弹窗 once/always → once/session/always 三档(本次单次执行后清/当前会话切会话清/始终落KV)。修 once 原写 session 致本次实为本会话名实不符。AllowedDirs 加 once 层 + ai_authorize_dir decision 改 match 四分支 + 执行后 clear_once。
This commit is contained in:
lxy
2026-06-25 00:23:07 +08:00
parent 56a08fb5c1
commit 24c3fa08f1
10 changed files with 116 additions and 46 deletions
+15 -3
View File
@@ -3,8 +3,9 @@
后端挂起 loop 等用户决定)。阶段1 改遍历 pendingDirAuths(数组)——同轮多个文件工具落不同
未授权目录时后端连发多条 AiDirAuthRequired,数组并存不互覆盖。
条件:pendingDirAuths 非空(AiDirAuthRequired 事件置)+ 当前视图正在生成(防切走后误显)。
每项独立三按钮:点"仅本次" → ai_authorize_dir(decision=once, 写会话临时授权)→ 后端执行工具 + try_continue。
点"未来都允许" → ai_authorize_dir(decision=always, 写持久化 Settings KV)→ 执行 + 续 loop。
每项独立四按钮:点"本次" → ai_authorize_dir(decision=once, 写 once 层单次授权,执行后清)→ 后端执行工具 + try_continue。
点"当前会话" → ai_authorize_dir(decision=session, 写 session 层会话授权,切会话清)→ 执行 + 续 loop。
点"始终放行" → ai_authorize_dir(decision=always, 写持久化 Settings KV)→ 执行 + 续 loop。
点"拒绝" → ai_authorize_dir(decision=deny, 工具返 Err)→ 续 loop。
store 单例共享(state/aiApi),pendingDirAuths 模块级 ref(useAiEvents)直接导入。
toast 经 emit 转父(保持单一 toast 源)。 -->
@@ -19,6 +20,11 @@
:disabled="actingIds.has(item.id)"
@click="handleAuthorize(item.id, 'once')"
>{{ $t('aiChat.dirAuthOnce') }}</button>
<button
class="ai-dir-auth-btn ai-dir-auth-btn--session"
:disabled="actingIds.has(item.id)"
@click="handleAuthorize(item.id, 'session')"
>{{ $t('aiChat.dirAuthSession') }}</button>
<button
class="ai-dir-auth-btn ai-dir-auth-btn--always"
:disabled="actingIds.has(item.id)"
@@ -74,7 +80,7 @@ const actingIds = reactive(new Set<string>())
/** 点三选项之一:按 id 定位挂起项,调 ai_authorize_dir。后端 remove pending → 写授权/拒 →
* execute → try_continue。不主动清 pendingDirAuths——由后端 AiApprovalResult/AiCompleted/AiError
* 在 useAiEvents 内按 id filter / 清空。IPC 失败回滚 actingIds 让用户可重试。 */
async function handleAuthorize(id: string, decision: 'once' | 'always' | 'deny'): Promise<void> {
async function handleAuthorize(id: string, decision: 'once' | 'session' | 'always' | 'deny'): Promise<void> {
if (actingIds.has(id)) return
actingIds.add(id)
try {
@@ -148,6 +154,12 @@ watch(() => pendingDirAuths.value, (items) => {
color: #fff;
}
.ai-dir-auth-btn--once:hover:not(:disabled) { filter: brightness(1.1); }
.ai-dir-auth-btn--session {
background: color-mix(in srgb, var(--df-accent) 15%, transparent);
color: var(--df-accent);
border: 0.5px solid color-mix(in srgb, var(--df-accent) 40%, transparent);
}
.ai-dir-auth-btn--session:hover:not(:disabled) { filter: brightness(1.1); }
.ai-dir-auth-btn--always {
background: var(--df-warning);
color: #000;