dsh-email 0.4.0 → 0.4.1
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/README.md +1 -1
- package/lib/index.js +24 -20
- package/package.json +1 -1
package/README.md
CHANGED
package/lib/index.js
CHANGED
|
@@ -164,20 +164,6 @@ function renderFolders(value) {
|
|
|
164
164
|
function renderAttachment(value) {
|
|
165
165
|
return oneText('账号 ' + value.account + ' 已下载附件 "' + value.filename + '"(' + value.contentType + ',' + value.size + ' 字节)到:\n' + value.path + '\n可用 read 工具读取该文件。');
|
|
166
166
|
}
|
|
167
|
-
/**
|
|
168
|
-
* Best-effort read of the session's effective approval policy. Duck-typed on
|
|
169
|
-
* the permission-presets seam; any drift or absence yields undefined and the
|
|
170
|
-
* gate falls back to the plain ask flow.
|
|
171
|
-
*/
|
|
172
|
-
function effectiveApprovalPolicy(ctx, exec) {
|
|
173
|
-
try {
|
|
174
|
-
const preset = ctx.get?.('permissionPresets')?.current?.(exec?.agent?.session?.events);
|
|
175
|
-
return typeof preset?.approval === 'string' ? preset.approval : undefined;
|
|
176
|
-
}
|
|
177
|
-
catch {
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
167
|
function fingerprintSettings(settings) {
|
|
182
168
|
return JSON.stringify({
|
|
183
169
|
accounts: [...settings.accounts.entries()].map(([name, account]) => [name, account]),
|
|
@@ -372,16 +358,34 @@ export function apply(ctx, config = {}) {
|
|
|
372
358
|
const args = (exec.args ?? {});
|
|
373
359
|
const attachCount = Array.isArray(args.attachments) ? args.attachments.length : 0;
|
|
374
360
|
const reason = '发送邮件给 ' + args.to + ',主题「' + args.subject + '」' + (attachCount > 0 ? ',附件 ' + attachCount + ' 个' : '');
|
|
375
|
-
//
|
|
376
|
-
//
|
|
377
|
-
//
|
|
378
|
-
|
|
361
|
+
// Gate-owned approval: we run the approval round-trip ourselves so the
|
|
362
|
+
// denial reason is always honest and actionable — including the Full
|
|
363
|
+
// Access case where the harness policy answers 'rejected' without ever
|
|
364
|
+
// showing a dialog.
|
|
365
|
+
const approval = ctx.get('approval');
|
|
366
|
+
if (approval === undefined) {
|
|
379
367
|
return {
|
|
380
368
|
kind: 'deny',
|
|
381
|
-
reason: 'email_send
|
|
369
|
+
reason: 'email_send 需要确认,但当前环境没有审批通道(如 headless)。如确定安全,可在配置中设置 sendApproval: false 后直接发送。',
|
|
382
370
|
};
|
|
383
371
|
}
|
|
384
|
-
|
|
372
|
+
const outcome = await approval.request({
|
|
373
|
+
agent: exec.agent,
|
|
374
|
+
toolName: exec.name,
|
|
375
|
+
callId: exec.callId,
|
|
376
|
+
reason,
|
|
377
|
+
signal: exec.signal,
|
|
378
|
+
});
|
|
379
|
+
if (outcome === 'allowed-once')
|
|
380
|
+
return next();
|
|
381
|
+
if (outcome === 'cancelled')
|
|
382
|
+
return { kind: 'deny', reason: '发信确认被取消,邮件未发送。' };
|
|
383
|
+
if (outcome === 'unavailable')
|
|
384
|
+
return { kind: 'deny', reason: '发信确认不可用(没有可用的审批界面),邮件未发送。' };
|
|
385
|
+
return {
|
|
386
|
+
kind: 'deny',
|
|
387
|
+
reason: '发信未获批准:要么你拒绝了,要么当前会话处于 Full Access(审批策略 never,不会弹框)。若在 Full Access:切到 Read Only / Write 再发,或关闭 sendApproval(自行承担风险)。',
|
|
388
|
+
};
|
|
385
389
|
}, { prepend: true });
|
|
386
390
|
}
|
|
387
391
|
export { PROVIDER_NAMES, EMAIL_PASSWORD_ENV } from './config.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-email",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "IMAP/SMTP email tools for DeepSeek Harness: list, read, search and send mail, with QQ/163/126/Sina/Aliyun/Gmail/Outlook/iCloud presets.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|