opencode: session.create 传入 permission 规则 + 心跳报 native

按 PLAN 7.11 P4 + 六条实测结论:
- 导入 opencodePermissions/normalizeMode 从 lib/permission-mode.js
- session.create 时根据 data.permission_mode 生成规则数组传入 permission 字段
  plan: edit/bash/task 全 deny(工具从清单消失)
  workspace: edit deny→allow(目录内) + bash ask + task deny
  full: 空数组(用平台默认配置)
- 心跳上报 mode_enforcement: 'native'(opencode 有原生 permission.ask 钩子)
- 290 测试全过
This commit is contained in:
2026-09-06 19:14:19 +08:00
parent af61a37d9a
commit 3bb419f2f2

View File

@ -41,6 +41,7 @@ import { appendRenameProposal, renameProposalNote } from "./lib/rename-proposal.
// opencode 原生支持三态权限免批由它自己记response:"always"
// 所以这里只借用决策文本的判定,不需要 createGrantStore。
import { isAlwaysDecision, isApproval } from "./lib/permission-grants.js";
import { opencodePermissions, normalizeMode, modeBriefing } from "./lib/permission-mode.js";
const GATEWAY_URL = process.env.AGENTMAIL_GATEWAY_URL || "http://127.0.0.1:8180";
const AGENT_NAME = process.env.AGENTMAIL_AGENT_NAME || "opencode";
@ -681,8 +682,10 @@ async function resolveSessionForMail(client, directory, data, kind) {
// 故意不传 titleopencode 只在标题缺省时才让模型按首轮对话生成摘要标题,
// 传了占位标题就等于掐掉平台自己的命名机制。标题稍后由 session.updated 事件回写。
const permMode = normalizeMode(data.permission_mode);
const created = await client.session.create({
query: wantDir ? { directory: wantDir } : undefined,
permission: opencodePermissions(permMode),
});
const session = created?.data ?? created;
const sessionID = session?.id;
@ -1151,6 +1154,7 @@ export default async function mailBridge(input) {
reportModels(),
]);
const body = {};
body.mode_enforcement = 'native';
if (platform_sessions) body.platform_sessions = platform_sessions;
if (models) body.models = models;
try {