@michengai/dsh-automation 0.1.40 → 0.1.42

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/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@
4
4
 
5
5
  Upcoming changes and recent published versions are listed below. Git tags and GitHub Releases now mirror these entries; historical sections retain links to their original release commits.
6
6
 
7
+ ## 0.1.42 - 2026-09-14
8
+
9
+ - Preserve a replacement sidebar tab when an older registration with the same ID is unloaded.
10
+
11
+ ## 0.1.41 - 2026-09-14
12
+
13
+ - Fix Scheduled and execution-history navigation disappearing when used with the archive and IM plugins.
14
+
7
15
  ## 0.1.40 - 2026-09-12
8
16
 
9
17
  - Configure concurrency per automation to allow overlapping executions of the same task. The default is `1`, preserving existing task behavior. When full, scheduled triggers are skipped and manual starts are rejected; lowering the limit does not cancel existing runs.
@@ -4,6 +4,14 @@
4
4
 
5
5
  以下记录待发布变更及近期已发布版本。Git 标签与 GitHub Release 现已和这些条目同步;历史条目继续保留原始发布提交链接。
6
6
 
7
+ ## 0.1.42 - 2026-09-14
8
+
9
+ - 修复旧侧栏页签卸载时,可能误删同 ID 替代页签的问题。
10
+
11
+ ## 0.1.41 - 2026-09-14
12
+
13
+ - 修复与归档、IM 插件组合使用时,侧栏定时入口及执行记录入口可能消失的问题。
14
+
7
15
  ## 0.1.40 - 2026-09-12
8
16
 
9
17
  - 支持为单个自动化设置并发数量,让同一任务的多次执行可以同时进行。默认 `1`,旧任务保持原有行为;满额时跳过定时触发并拒绝手动启动,调低上限不取消已有运行。
package/README.md CHANGED
@@ -55,18 +55,21 @@ Run history stays in Settings and can be filtered by day, week, month, task, or
55
55
 
56
56
  ## DSH product ecosystem
57
57
 
58
- For a ready-to-use workbench, download [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop/releases). If you already use [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), install any of these eight plugins individually. The desktop app includes all eight.
58
+ For a desktop workbench, download [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop/releases). Existing [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) installations can add plugins as needed by following each project's README. Below are 11 first-party plugins; consult the corresponding desktop release notes and bundled catalog for what that version includes.
59
59
 
60
60
  | Plugin | What you can do |
61
61
  | --- | --- |
62
62
  | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) | Organize projects and conversations, search tasks, and navigate chat turns |
63
- | [IM Connect](https://github.com/MichengAI/dsh-im-connect) | Send tasks and receive replies through your usual messenger |
64
- | [Automation](https://github.com/MichengAI/dsh-automation) | Schedule tasks and review each run |
63
+ | [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | Choose and summon specialists for your task |
65
64
  | [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) | Find, enable, create, and import local skills |
66
65
  | [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) | Search, restore, or clean up archived conversations |
67
- | [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | Choose and summon specialists for your task |
66
+ | [IM Connect](https://github.com/MichengAI/dsh-im-connect) | Send tasks and receive replies through messaging platforms |
67
+ | [Automation](https://github.com/MichengAI/dsh-automation) | Schedule tasks and review each run |
68
68
  | [BTW](https://github.com/MichengAI/dsh-btw) | Ask side questions without interrupting the main task |
69
- | [Simplify](https://github.com/MichengAI/dsh-simplify) | Use /simplify to improve code within your Git changes |
69
+ | [Simplify](https://github.com/MichengAI/dsh-simplify) | Use `/simplify` to improve code within your Git changes |
70
+ | [PUA](https://github.com/MichengAI/dsh-pua) | Guide the Agent to try new approaches after failures, investigate causes, and verify results before completion |
71
+ | [Code Review](https://github.com/MichengAI/dsh-code-review) | Use `/review` to request an independent Agent code review and receive the report in the current conversation |
72
+ | [Codex Pet](https://github.com/MichengAI/dsh-codex-pet) | View conversation notifications and respond to tool approvals and questions through a desktop pet |
70
73
 
71
74
  ## Prerequisites
72
75
 
@@ -186,6 +189,8 @@ pnpm build
186
189
 
187
190
  `pnpm check` runs typecheck, unit tests, real Host compatibility tests, and build. `pnpm test:host` bypasses runtime stubs and uses the official AgentLoop, Session V3, and permission service with a fixed local model adapter; it makes no external model calls. Browser interactions and real model calls require separate acceptance testing.
188
191
 
192
+ Cross-plugin sidebar regressions run with `pnpm test:composition <dsh-im-connect checkout>`. Build the IM checkout first; the script reads its `lib/client.js`. It executes the composition logic and tab registries of both repositories, covering registration order, delayed notifications, and uninstall handover across the archive, IM, scheduled, and Codex UI plugins; slots and timers use a simulated environment, so it does not install any plugin or replace Desktop rendering acceptance testing. This separate check requires an external checkout and is not included in `pnpm check`; use a fixed IM revision for reproducible results.
193
+
189
194
  `pnpm test:matrix` builds the package, then creates separate temporary npm environments for all four versions using network access. It checks strict peer installation, every official dependency version, the packaged entry point, real AgentLoop execution, and service regressions. All four versions pass. Persistence enumeration in service regressions uses in-memory fixtures for both cold-session formats; it does not validate on-disk migration of a real Profile. The printed evidence directory retains installation lockfiles, test logs, and `results.json`. The matrix does not modify development dependencies or connect to the user's Profile.
190
195
 
191
196
  ## License
package/README.zh-CN.md CHANGED
@@ -55,18 +55,21 @@
55
55
 
56
56
  ## DSH 产品生态
57
57
 
58
- 想直接使用完整工作台,可下载 [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop/releases);已有 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 环境,可按需独立安装以下 8 个自研插件。桌面端已随附这些插件。
58
+ 想使用桌面工作台,可下载 [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop/releases);已有 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 环境,可按各项目 README 按需安装。以下列出 11 个自研插件;桌面端实际随附范围以对应版本的发行说明和内置清单为准。
59
59
 
60
60
  | 插件 | 你可以用它做什么 |
61
61
  | --- | --- |
62
62
  | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) | 整理项目与会话、搜索任务、跳转对话轮次 |
63
- | [IM Connect](https://github.com/MichengAI/dsh-im-connect) | 从微信、飞书、钉钉等消息平台下任务、收回复 |
64
- | [Automation](https://github.com/MichengAI/dsh-automation) | 按计划执行任务,查看每次运行的结果 |
63
+ | [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | 按任务选择并召唤专业角色 |
65
64
  | [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) | 统一查找、启停、创建和导入本机技能 |
66
65
  | [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) | 搜索、恢复或清理已归档会话 |
67
- | [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | 按任务选择并召唤专业角色 |
66
+ | [IM Connect](https://github.com/MichengAI/dsh-im-connect) | 从消息平台下任务、收回复 |
67
+ | [Automation](https://github.com/MichengAI/dsh-automation) | 按计划执行任务,查看每次运行的结果 |
68
68
  | [BTW](https://github.com/MichengAI/dsh-btw) | 在当前上下文中临时旁问,不打断主任务 |
69
- | [Simplify](https://github.com/MichengAI/dsh-simplify) | 用 /simplify 整理 Git 改动范围内的代码 |
69
+ | [Simplify](https://github.com/MichengAI/dsh-simplify) | 用 `/simplify` 整理 Git 改动范围内的代码 |
70
+ | [PUA](https://github.com/MichengAI/dsh-pua) | 引导 Agent 在失败时换方法、查原因,并在完成前验证结果 |
71
+ | [Code Review](https://github.com/MichengAI/dsh-code-review) | 用 `/review` 发起独立 Agent 代码审查,在当前会话接收报告 |
72
+ | [Codex Pet](https://github.com/MichengAI/dsh-codex-pet) | 通过桌面宠物查看会话提醒、处理工具审批和问题回答 |
70
73
 
71
74
  ## 前置条件
72
75
 
@@ -186,6 +189,8 @@ pnpm build
186
189
 
187
190
  `pnpm check` 会连续执行类型检查、单元测试、真实宿主兼容测试和构建。`pnpm test:host` 不加载宿主运行时桩,使用官方 AgentLoop、Session V3 和权限服务,模型响应由本地固定适配器提供,不调用外部模型。浏览器交互和真实模型调用需另行验收。
188
191
 
192
+ 跨插件侧栏回归可运行 `pnpm test:composition <dsh-im-connect 检出目录>`。请先构建 IM 检出目录,脚本读取其中的 `lib/client.js`。它执行两仓库的接入逻辑和页签注册表,覆盖归档、IM、定时及 Codex UI 的注册顺序、延迟通知与卸载接管;插槽和计时器使用模拟环境,不替代 Desktop 渲染验收,也不安装插件。该检查需要外部检出目录,独立于 `pnpm check`;请固定 IM revision,以便复现结果。
193
+
189
194
  `pnpm test:matrix` 先构建发布包,再联网为上述四个版本分别建立临时 npm 环境,执行严格 peer 安装、整棵官方依赖树版本检查、发布入口加载、真实 AgentLoop 执行和服务回归。四版均通过;服务回归中的持久化枚举使用内存夹具,覆盖新旧冷会话格式,不等同于真实 Profile 的磁盘迁移验收。脚本输出证据目录,保留各版安装锁文件、测试日志和 `results.json`。矩阵不修改开发依赖,也不连接用户 Profile。
190
195
 
191
196
  ## 许可证
package/lib/client.js CHANGED
@@ -2963,6 +2963,7 @@ function createNativeTabRegistry(officialTree) {
2963
2963
  emit();
2964
2964
  }
2965
2965
  return () => {
2966
+ if (tabs.get(tab.id) !== tab) return;
2966
2967
  tabs.delete(tab.id);
2967
2968
  rebuild();
2968
2969
  emit();
@@ -4648,10 +4649,15 @@ function apply(ctx) {
4648
4649
  ctx.slots.inject("sidebar.workspaces", () => {
4649
4650
  let wrappedEntry;
4650
4651
  let originalComp;
4652
+ let ownedWrapper;
4653
+ let ownedRegistry;
4654
+ let insertedRegistry;
4651
4655
  let removeInsertedTab = () => void 0;
4652
- let wrapped = false;
4653
4656
  let syncing = false;
4654
4657
  let retryTimer;
4658
+ const notifyPeers = () => {
4659
+ queueMicrotask(() => window.dispatchEvent(new Event("dsh-native-sidebar-change")));
4660
+ };
4655
4661
  const listenChannels = (listener) => ctx.slots.subscribe?.("sidebar.channels", listener) ?? (() => void 0);
4656
4662
  const stopRetry = () => {
4657
4663
  if (retryTimer !== void 0) {
@@ -4663,19 +4669,26 @@ function apply(ctx) {
4663
4669
  stopRetry();
4664
4670
  removeInsertedTab();
4665
4671
  removeInsertedTab = () => void 0;
4666
- if (wrappedEntry !== void 0 && originalComp !== void 0) {
4667
- try {
4668
- wrappedEntry.component = originalComp;
4669
- } catch {
4670
- }
4672
+ insertedRegistry = void 0;
4673
+ if (wrappedEntry !== void 0) {
4674
+ if (originalComp !== void 0 && wrappedEntry.component === ownedWrapper) wrappedEntry.component = originalComp;
4675
+ const record = wrappedEntry;
4676
+ if (record.__dshNativeTabs === ownedRegistry) delete record.__dshNativeTabs;
4677
+ notifyPeers();
4671
4678
  }
4672
4679
  wrappedEntry = void 0;
4673
4680
  originalComp = void 0;
4674
- wrapped = false;
4681
+ ownedWrapper = void 0;
4682
+ ownedRegistry = void 0;
4675
4683
  };
4676
4684
  const insertScheduleTab = (entry, openSession) => {
4677
4685
  const registry = findNativeTabRegistry(entry);
4678
4686
  if (registry === void 0) return false;
4687
+ if (insertedRegistry !== registry) {
4688
+ removeInsertedTab();
4689
+ removeInsertedTab = () => void 0;
4690
+ insertedRegistry = registry;
4691
+ }
4679
4692
  if (registry.getTabs().some((item) => item.id === "schedule")) return true;
4680
4693
  removeInsertedTab = registry.insert({
4681
4694
  id: "schedule",
@@ -4707,7 +4720,7 @@ function apply(ctx) {
4707
4720
  const record = entry;
4708
4721
  if (insertScheduleTab(entry) || insertScheduleTab(record.component)) return true;
4709
4722
  }
4710
- return wrappedEntry !== void 0 && insertScheduleTab(wrappedEntry);
4723
+ return false;
4711
4724
  };
4712
4725
  const ensureScheduleTab = () => {
4713
4726
  if (insertIntoKnownHosts()) {
@@ -4740,7 +4753,7 @@ function apply(ctx) {
4740
4753
  ...innerProps.useSessions === void 0 ? {} : { useSessions: innerProps.useSessions },
4741
4754
  ...innerProps.useWorkspaces === void 0 ? {} : { useWorkspaces: innerProps.useWorkspaces },
4742
4755
  ...innerProps.renderSlot === void 0 ? {} : { renderSlot: innerProps.renderSlot },
4743
- ...originalComp === void 0 ? {} : { officialTree: originalComp }
4756
+ officialTree: tree
4744
4757
  });
4745
4758
  };
4746
4759
  var AutomationNativeWorkspaceShell = AutomationNativeWorkspaceShell2;
@@ -4749,32 +4762,41 @@ function apply(ctx) {
4749
4762
  return;
4750
4763
  }
4751
4764
  const entries = readSlotEntries(ctx, "sidebar.workspaces");
4752
- const occupant = pickWrappableWorkspacesEntry(entries);
4753
- const current = occupant?.component;
4754
- if (current !== void 0 && isForeignSidebarHost(current)) {
4765
+ const active = entries.find((entry) => entry?.component !== void 0);
4766
+ if (wrappedEntry !== void 0 && (active !== wrappedEntry || active.component !== ownedWrapper)) unwrap();
4767
+ if (active === wrappedEntry && active?.component === ownedWrapper && ownedWrapper !== void 0) {
4755
4768
  ensureScheduleTab();
4756
4769
  return;
4757
4770
  }
4758
- if (wrappedEntry?.component !== void 0 && wrappedEntry.component.__dshAutomationWrapped === true) {
4771
+ if (active === void 0) {
4772
+ unwrap();
4773
+ return;
4774
+ }
4775
+ const occupant = pickWrappableWorkspacesEntry(entries);
4776
+ const current = occupant?.component;
4777
+ if (current !== void 0 && isForeignSidebarHost(current)) {
4759
4778
  ensureScheduleTab();
4760
4779
  return;
4761
4780
  }
4762
- if (occupant?.component === void 0 || wrapped) return;
4781
+ if (occupant?.component === void 0) return;
4763
4782
  const resolved = resolveOfficialTreeComponent(occupant.component);
4764
4783
  if (resolved === void 0) return;
4765
4784
  originalComp = resolved;
4766
4785
  const registry = createNativeTabRegistry(originalComp);
4786
+ ownedRegistry = registry;
4767
4787
  attachNativeTabRegistry(occupant, registry);
4768
4788
  const marked = AutomationNativeWorkspaceShell2;
4769
4789
  marked.displayName = "AutomationNativeWorkspaceShell";
4770
4790
  marked.__dshNativeTabHost = true;
4771
4791
  marked.__dshAutomationWrapped = true;
4772
4792
  marked.__dshAutomationOriginal = originalComp;
4793
+ const tree = originalComp;
4773
4794
  attachNativeTabRegistry(marked, registry);
4774
4795
  occupant.component = marked;
4796
+ ownedWrapper = marked;
4775
4797
  wrappedEntry = occupant;
4776
- wrapped = true;
4777
4798
  ensureScheduleTab();
4799
+ notifyPeers();
4778
4800
  } catch (error) {
4779
4801
  console.warn("[dsh-automation] \u5305\u88F9\u5B98\u65B9\u4EFB\u52A1\u6811\u5931\u8D25", error);
4780
4802
  } finally {
@@ -4783,9 +4805,13 @@ function apply(ctx) {
4783
4805
  };
4784
4806
  sync();
4785
4807
  const unsub = typeof ctx.slots.subscribe === "function" ? ctx.slots.subscribe("sidebar.workspaces", sync) : () => void 0;
4808
+ const unsubSidebar = ctx.slots.subscribe?.("sidebar", sync) ?? (() => void 0);
4809
+ window.addEventListener("dsh-native-sidebar-change", sync);
4786
4810
  ensureScheduleTab();
4787
4811
  return () => {
4788
4812
  unsub();
4813
+ unsubSidebar();
4814
+ window.removeEventListener("dsh-native-sidebar-change", sync);
4789
4815
  unwrap();
4790
4816
  };
4791
4817
  });