@michengai/dsh-automation 0.1.11 → 0.1.13

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/lib/index.js CHANGED
@@ -21547,21 +21547,6 @@ function automationSessionTitle(taskName, iso) {
21547
21547
  return `${formatRunStamp(iso)} - ${taskName}`;
21548
21548
  }
21549
21549
 
21550
- // src/permission-presets.ts
21551
- function normalizePermissionPreset(input, names) {
21552
- if (typeof input !== "string") return void 0;
21553
- const raw = input.trim();
21554
- if (raw === "") return void 0;
21555
- const value = raw === "full-access" ? "danger-full-access" : raw;
21556
- return names.includes(value) ? value : void 0;
21557
- }
21558
- function isUnattendedPermissionSafe(name2, presets) {
21559
- const normalized = normalizePermissionPreset(name2, presets.names);
21560
- if (normalized === void 0) return false;
21561
- const sandbox = presets.resolve?.(normalized).sandbox;
21562
- return (sandbox ?? normalized) !== "danger-full-access";
21563
- }
21564
-
21565
21550
  // src/executor.ts
21566
21551
  var UNATTENDED_TOOL_ALLOWLIST = /* @__PURE__ */ new Set([
21567
21552
  "run_code",
@@ -21605,9 +21590,6 @@ function unattendedToolGuardReason(name2, args) {
21605
21590
  return UNATTENDED_TOOL_ALLOWLIST.has(name2) ? void 0 : `\u5DE5\u5177 '${name2}' \u4E0D\u5728\u65E0\u4EBA\u503C\u5B88\u81EA\u52A8\u5316\u5141\u8BB8\u5217\u8868\u4E2D\u3002`;
21606
21591
  }
21607
21592
  function applyUnattendedPermission(presets, session, permission) {
21608
- if (!isUnattendedPermissionSafe(permission, presets)) {
21609
- throw new Error("\u65E0\u4EBA\u503C\u5B88\u81EA\u52A8\u5316\u62D2\u7EDD\u5B8C\u5168\u6587\u4EF6\u7CFB\u7EDF\u8BBF\u95EE\u6743\u9650\u3002");
21610
- }
21611
21593
  presets.set(session, permission);
21612
21594
  setApprovalPolicy(session, "never");
21613
21595
  }
@@ -21791,6 +21773,15 @@ function pinAutomationSessionTitle(ctx, session, title) {
21791
21773
  }
21792
21774
  }
21793
21775
 
21776
+ // src/permission-presets.ts
21777
+ function normalizePermissionPreset(input, names) {
21778
+ if (typeof input !== "string") return void 0;
21779
+ const raw = input.trim();
21780
+ if (raw === "") return void 0;
21781
+ const value = raw === "full-access" ? "danger-full-access" : raw;
21782
+ return names.includes(value) ? value : void 0;
21783
+ }
21784
+
21794
21785
  // src/service.ts
21795
21786
  var MAX_TIMER_DELAY_MS = 2147483647;
21796
21787
  var OPTION_CACHE_TTL_MS = 3e4;
@@ -21858,20 +21849,17 @@ var AutomationService = class _AutomationService {
21858
21849
  });
21859
21850
  }
21860
21851
  permissionNames() {
21861
- const presets = this.permissionPresets();
21862
- return presets.names.filter((name2) => isUnattendedPermissionSafe(name2, presets));
21852
+ return this.permissionPresets().names;
21863
21853
  }
21864
21854
  permissionOptions() {
21865
21855
  const presets = this.permissionPresets();
21866
- return this.permissionNames().map((name2) => presets.optionOf(name2));
21856
+ return presets.names.map((name2) => presets.optionOf(name2));
21867
21857
  }
21868
21858
  defaultPermission() {
21869
21859
  const presets = this.permissionPresets();
21870
21860
  const value = normalizePermissionPreset(presets.defaultPreset, presets.names);
21871
- if (value !== void 0 && isUnattendedPermissionSafe(value, presets)) return value;
21872
- const fallback = this.permissionNames()[0];
21873
- if (fallback === void 0) throw new Error("Host \u6CA1\u6709\u53EF\u7528\u4E8E\u65E0\u4EBA\u503C\u5B88\u4EFB\u52A1\u7684\u5B89\u5168\u6743\u9650\u9884\u8BBE\u3002");
21874
- return fallback;
21861
+ if (value === void 0) throw new Error("Host \u7684\u9ED8\u8BA4\u6743\u9650\u9884\u8BBE\u4E0D\u5728\u5B98\u65B9\u6743\u9650\u5217\u8868\u4E2D\u3002");
21862
+ return value;
21875
21863
  }
21876
21864
  async dispose() {
21877
21865
  this.stopping = true;
@@ -22353,9 +22341,6 @@ var AutomationService = class _AutomationService {
22353
22341
  if (input === void 0) return this.defaultPermission();
22354
22342
  const value = normalizePermissionPreset(input, presets.names);
22355
22343
  if (value === void 0) throw new AutomationRequestError(`unknown permission preset '${input}'`);
22356
- if (!isUnattendedPermissionSafe(value, presets)) {
22357
- throw new AutomationRequestError("\u65E0\u4EBA\u503C\u5B88\u81EA\u52A8\u5316\u4E0D\u5141\u8BB8\u4F7F\u7528\u5B8C\u5168\u6587\u4EF6\u7CFB\u7EDF\u8BBF\u95EE\u6743\u9650\u3002");
22358
- }
22359
22344
  return value;
22360
22345
  }
22361
22346
  /** 把旧版 full-access 及已移除的预设收敛到 Host 当前可用列表。 */
@@ -22363,23 +22348,12 @@ var AutomationService = class _AutomationService {
22363
22348
  const presets = this.permissionPresets();
22364
22349
  const fallback = this.defaultPermission();
22365
22350
  for (const [id, definition] of this.definitions.entries()) {
22366
- const normalized = normalizePermissionPreset(definition.permissionPreset, presets.names);
22367
- const unsafe = normalized !== void 0 && !isUnattendedPermissionSafe(normalized, presets);
22368
- const permissionPreset2 = normalized !== void 0 && !unsafe ? normalized : fallback;
22369
- if (permissionPreset2 === definition.permissionPreset && !unsafe) continue;
22370
- await this.definitions.put(id, {
22371
- ...definition,
22372
- permissionPreset: permissionPreset2,
22373
- ...unsafe ? {
22374
- status: "paused",
22375
- revision: definition.revision + 1,
22376
- updatedAt: toIso()
22377
- } : {}
22378
- });
22351
+ const permissionPreset2 = normalizePermissionPreset(definition.permissionPreset, presets.names) ?? fallback;
22352
+ if (permissionPreset2 === definition.permissionPreset) continue;
22353
+ await this.definitions.put(id, { ...definition, permissionPreset: permissionPreset2 });
22379
22354
  }
22380
22355
  for (const [id, run] of this.runs.entries()) {
22381
- const normalized = normalizePermissionPreset(run.targetSnapshot.permissionPreset, presets.names);
22382
- const permissionPreset2 = normalized !== void 0 && isUnattendedPermissionSafe(normalized, presets) ? normalized : fallback;
22356
+ const permissionPreset2 = normalizePermissionPreset(run.targetSnapshot.permissionPreset, presets.names) ?? fallback;
22383
22357
  if (permissionPreset2 === run.targetSnapshot.permissionPreset) continue;
22384
22358
  await this.runs.put(id, {
22385
22359
  ...run,
@@ -22537,6 +22511,9 @@ var WEEKDAYS = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"];
22537
22511
  var RpcRequestError = class extends Error {
22538
22512
  name = "RpcRequestError";
22539
22513
  };
22514
+ function isBadRequest(error51) {
22515
+ return error51 instanceof RpcRequestError || error51 instanceof AutomationRequestError;
22516
+ }
22540
22517
  function record2(value, label) {
22541
22518
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
22542
22519
  throw new RpcRequestError(`${label} must be an object`);
@@ -22607,7 +22584,7 @@ function errorResult(error51, aborted2 = false) {
22607
22584
  };
22608
22585
  }
22609
22586
  const message = error51 instanceof Error ? error51.message : String(error51);
22610
- const badRequest = error51 instanceof RpcRequestError || error51 instanceof AutomationRequestError;
22587
+ const badRequest = isBadRequest(error51);
22611
22588
  return {
22612
22589
  ok: false,
22613
22590
  error: {
@@ -22755,6 +22732,10 @@ function registerAutomationRpc(ctx, service) {
22755
22732
  throw new RpcRequestError(`unknown automation endpoint '${endpoint}'`);
22756
22733
  }
22757
22734
  } catch (error51) {
22735
+ if (!signal.aborted && !isBadRequest(error51)) {
22736
+ const detail = error51 instanceof Error ? error51.stack ?? error51.message : String(error51);
22737
+ ctx.logger.warn(`dsh-automation: RPC '${endpoint}' failed: ${detail}`);
22738
+ }
22758
22739
  return errorResult(error51, signal.aborted);
22759
22740
  }
22760
22741
  }, { authority: "loopback" });
@@ -1,2 +1,5 @@
1
+ import type { AutomationPermission } from './protocol.js';
1
2
  /** 新建/编辑弹窗只允许取消或 ESC 关闭,点旁边不能关。 */
2
3
  export declare function shouldCloseCreateModal(reason: 'backdrop' | 'escape' | 'cancel'): boolean;
4
+ /** 与 Chat 一致:从其他权限切换到完全访问时显示风险确认。 */
5
+ export declare function shouldConfirmFullAccess(current: AutomationPermission, next: AutomationPermission): boolean;
@@ -1,6 +1,6 @@
1
1
  /** 已认领 run 的独立 Agent 执行边界。 */
2
2
  import type { Context } from '@deepseek-ai/cordis';
3
- import { type PermissionPresetService } from './permission-presets.ts';
3
+ import type { PermissionPresetService } from './permission-presets.ts';
4
4
  import type { AutomationDefinition, AutomationRun } from './types.ts';
5
5
  interface SessionEventLike {
6
6
  readonly seq: number;
@@ -8,13 +8,7 @@ export interface PermissionPresetService {
8
8
  readonly names: readonly string[];
9
9
  readonly defaultPreset: string;
10
10
  optionOf(name: string): PermissionOption;
11
- resolve?(name: string): {
12
- readonly sandbox: 'read-only' | 'workspace-write' | 'danger-full-access';
13
- readonly approval: 'ask' | 'never';
14
- };
15
11
  set(session: unknown, name: string): void;
16
12
  }
17
13
  /** 兼容旧版插件曾保存的 full-access 名称,其余值必须来自 Host 当前列表。 */
18
14
  export declare function normalizePermissionPreset(input: unknown, names: readonly string[]): string | undefined;
19
- /** 无人值守任务禁止完全文件系统访问;自定义预设也按其真实 sandbox 语义判断。 */
20
- export declare function isUnattendedPermissionSafe(name: string, presets: PermissionPresetService): boolean;
@@ -1,6 +1,9 @@
1
1
  /** 仅 loopback 的 Web 客户端 RPC 适配器。 */
2
2
  import { type AutomationService } from './service.ts';
3
3
  interface RpcContext {
4
+ readonly logger: {
5
+ warn(message: string): void;
6
+ };
4
7
  readonly connection: {
5
8
  readonly rpc: {
6
9
  handle(channel: string, handler: (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<unknown>, options: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michengai/dsh-automation",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "在独立 DSH Session 中按计划执行编码任务,支持 Web 设置页与 Agent 双入口管理。",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",