新增: 路径授权三档化 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:
2026-06-25 00:23:07 +08:00
parent 56a08fb5c1
commit 24c3fa08f1
10 changed files with 116 additions and 46 deletions

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;