@michengai/dsh-codex-pet 0.1.5 → 0.1.7
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 +9 -0
- package/CHANGELOG.zh-CN.md +9 -0
- package/README.md +12 -10
- package/README.zh-CN.md +12 -10
- package/lib/client.js +166 -26
- package/package.json +11 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.7] - 2026-09-18
|
|
4
|
+
|
|
5
|
+
- Add compatibility with DSH `0.1.6-alpha.2` without dropping the existing supported hosts. Keep `sessions.open`, `pendingInteractions`, and legacy session snapshots on older hosts; use `uiWorkspace.openSession` and `uiSession.sessionStatus` only when those APIs are gone. Pin development types and the default e2e host to this release.
|
|
6
|
+
- Use a bilingual package description matching the GitHub repository.
|
|
7
|
+
|
|
8
|
+
## [0.1.6] - 2026-09-16
|
|
9
|
+
|
|
10
|
+
- Add compatibility with DSH `0.1.6-alpha.1` without dropping the existing supported hosts. Pin development types and the default e2e host to this release.
|
|
11
|
+
|
|
3
12
|
## [0.1.5] - 2026-09-12
|
|
4
13
|
|
|
5
14
|
- Keep the pet in a global Web overlay across pages while preserving interaction and letting clicks pass through empty areas.
|
package/CHANGELOG.zh-CN.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## [0.1.7] - 2026-09-18
|
|
4
|
+
|
|
5
|
+
- 新增 DSH `0.1.6-alpha.2` 兼容,不移除已支持的旧宿主。旧宿主继续使用 `sessions.open`、`pendingInteractions` 和会话快照里的旧请求;仅在这些接口消失后改走 `uiWorkspace.openSession` 和 `uiSession.sessionStatus`。开发类型检查和默认端到端宿主固定到该版本。
|
|
6
|
+
- 软件包描述改为与 GitHub 仓库一致的中英文双语。
|
|
7
|
+
|
|
8
|
+
## [0.1.6] - 2026-09-16
|
|
9
|
+
|
|
10
|
+
- 新增 DSH `0.1.6-alpha.1` 兼容,不移除已支持的旧宿主。开发类型检查和默认端到端宿主固定到该版本。
|
|
11
|
+
|
|
3
12
|
## [0.1.5] - 2026-09-12
|
|
4
13
|
|
|
5
14
|
- 宠物改为在整个 Web 页面内悬浮,切换页面时保留显示和交互,空白区域不阻挡页面操作。
|
package/README.md
CHANGED
|
@@ -56,23 +56,25 @@ Keep working in DSH while the pet and task notifications remain in the corner of
|
|
|
56
56
|
|
|
57
57
|
## DSH product ecosystem
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
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.
|
|
60
60
|
|
|
61
61
|
| Plugin | What you can do |
|
|
62
62
|
| --- | --- |
|
|
63
|
-
| [Codex UI](https://github.com/MichengAI/dsh-codex-ui) | Organize projects and conversations and navigate
|
|
64
|
-
| [
|
|
65
|
-
| [Automation](https://github.com/MichengAI/dsh-automation) | Schedule tasks and review their runs |
|
|
63
|
+
| [Codex UI](https://github.com/MichengAI/dsh-codex-ui) | Organize projects and conversations, search tasks, and navigate chat turns |
|
|
64
|
+
| [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | Choose and summon specialists for your task |
|
|
66
65
|
| [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) | Find, enable, create, and import local skills |
|
|
67
|
-
| [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) | Search, restore,
|
|
68
|
-
| [
|
|
69
|
-
| [
|
|
70
|
-
| [
|
|
71
|
-
| [
|
|
66
|
+
| [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) | Search, restore, or clean up archived conversations |
|
|
67
|
+
| [IM Connect](https://github.com/MichengAI/dsh-im-connect) | Send tasks and receive replies through messaging platforms |
|
|
68
|
+
| [Automation](https://github.com/MichengAI/dsh-automation) | Schedule tasks and review each run |
|
|
69
|
+
| [BTW](https://github.com/MichengAI/dsh-btw) | Ask side questions without interrupting the main task |
|
|
70
|
+
| [Simplify](https://github.com/MichengAI/dsh-simplify) | Use `/simplify` to improve code within your Git changes |
|
|
71
|
+
| [PUA](https://github.com/MichengAI/dsh-pua) | Guide the Agent to try new approaches after failures, investigate causes, and verify results before completion |
|
|
72
|
+
| [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 |
|
|
73
|
+
| [Codex Pet](https://github.com/MichengAI/dsh-codex-pet) | View conversation notifications and respond to tool approvals and questions through a desktop pet |
|
|
72
74
|
|
|
73
75
|
## Installation
|
|
74
76
|
|
|
75
|
-
Supported DeepSeek Harness versions: **`0.1.0-rc.8`, `0.1.1-rc.2`, `0.1.2-rc.1`, `0.1.5-rc.1`,
|
|
77
|
+
Supported DeepSeek Harness versions: **`0.1.0-rc.8`, `0.1.1-rc.2`, `0.1.2-rc.1`, `0.1.5-rc.1`, `0.1.5-rc.2`, `0.1.6-alpha.1`, and `0.1.6-alpha.2`**. New compatibility is added without dropping these older releases. Make sure the `dsh` command is available. The example uses the `web` profile; replace it with your target profile.
|
|
76
78
|
|
|
77
79
|
```powershell
|
|
78
80
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
package/README.zh-CN.md
CHANGED
|
@@ -56,23 +56,25 @@
|
|
|
56
56
|
|
|
57
57
|
## DSH 产品生态
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
想使用桌面工作台,可下载 [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop/releases);已有 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 环境,可按各项目 README 按需安装。以下列出 11 个自研插件;桌面端实际随附范围以对应版本的发行说明和内置清单为准。
|
|
60
60
|
|
|
61
61
|
| 插件 | 你可以用它做什么 |
|
|
62
62
|
| --- | --- |
|
|
63
|
-
| [Codex UI](https://github.com/MichengAI/dsh-codex-ui) |
|
|
63
|
+
| [Codex UI](https://github.com/MichengAI/dsh-codex-ui) | 整理项目与会话、搜索任务、跳转对话轮次 |
|
|
64
|
+
| [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | 按任务选择并召唤专业角色 |
|
|
65
|
+
| [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) | 统一查找、启停、创建和导入本机技能 |
|
|
66
|
+
| [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) | 搜索、恢复或清理已归档会话 |
|
|
64
67
|
| [IM Connect](https://github.com/MichengAI/dsh-im-connect) | 从消息平台下任务、收回复 |
|
|
65
|
-
| [Automation](https://github.com/MichengAI/dsh-automation) |
|
|
66
|
-
| [
|
|
67
|
-
| [
|
|
68
|
-
| [
|
|
69
|
-
| [
|
|
70
|
-
| [
|
|
71
|
-
| [Codex Pet](https://github.com/MichengAI/dsh-codex-pet) | 宠物陪伴,查看和处理任务通知 |
|
|
68
|
+
| [Automation](https://github.com/MichengAI/dsh-automation) | 按计划执行任务,查看每次运行的结果 |
|
|
69
|
+
| [BTW](https://github.com/MichengAI/dsh-btw) | 在当前上下文中临时旁问,不打断主任务 |
|
|
70
|
+
| [Simplify](https://github.com/MichengAI/dsh-simplify) | 用 `/simplify` 整理 Git 改动范围内的代码 |
|
|
71
|
+
| [PUA](https://github.com/MichengAI/dsh-pua) | 引导 Agent 在失败时换方法、查原因,并在完成前验证结果 |
|
|
72
|
+
| [Code Review](https://github.com/MichengAI/dsh-code-review) | 用 `/review` 发起独立 Agent 代码审查,在当前会话接收报告 |
|
|
73
|
+
| [Codex Pet](https://github.com/MichengAI/dsh-codex-pet) | 通过桌面宠物查看会话提醒、处理工具审批和问题回答 |
|
|
72
74
|
|
|
73
75
|
## 安装
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
支持的 DeepSeek Harness 版本:**`0.1.0-rc.8`、`0.1.1-rc.2`、`0.1.2-rc.1`、`0.1.5-rc.1`、`0.1.5-rc.2`、`0.1.6-alpha.1`、`0.1.6-alpha.2`**。新增兼容不移除这些旧版。需要可用的 `dsh` 命令。以下示例使用 `web` profile,请按实际环境替换。
|
|
76
78
|
|
|
77
79
|
```powershell
|
|
78
80
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
package/lib/client.js
CHANGED
|
@@ -38,14 +38,44 @@ __export(client_exports, {
|
|
|
38
38
|
module.exports = __toCommonJS(client_exports);
|
|
39
39
|
|
|
40
40
|
// src/session-compat.ts
|
|
41
|
-
function compatibleSessions(sessions) {
|
|
41
|
+
function compatibleSessions(sessions, navigate, status) {
|
|
42
42
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
43
|
+
const refs = /* @__PURE__ */ new Map();
|
|
44
|
+
const sweep = () => {
|
|
45
|
+
const ids = new Set(sessions.list?.getSnapshot?.()?.ids ?? []);
|
|
46
|
+
for (const [id, ref] of refs) if (!ids.has(id)) {
|
|
47
|
+
try {
|
|
48
|
+
ref.release();
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
refs.delete(id);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
sessions.list?.subscribe?.(sweep);
|
|
43
55
|
return {
|
|
44
56
|
list: sessions.list,
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
status: status ?? sessions.status,
|
|
58
|
+
using: sessions.using?.bind(sessions),
|
|
59
|
+
open: (id) => navigate ? navigate(id) : sessions.open?.(id),
|
|
60
|
+
create: (options) => {
|
|
61
|
+
if (!sessions.create) throw new Error("\u521B\u5EFA\u4F1A\u8BDD\u5C1A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u8BD5");
|
|
62
|
+
return sessions.create(options);
|
|
63
|
+
},
|
|
47
64
|
binding(id) {
|
|
48
|
-
|
|
65
|
+
sweep();
|
|
66
|
+
let binding = sessions.binding(id);
|
|
67
|
+
if (!binding && sessions.retain) {
|
|
68
|
+
let ref = refs.get(id);
|
|
69
|
+
if (!ref) {
|
|
70
|
+
try {
|
|
71
|
+
ref = sessions.retain(id, { source: "controllerOperation" });
|
|
72
|
+
refs.set(id, ref);
|
|
73
|
+
} catch {
|
|
74
|
+
return void 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
binding = ref.binding;
|
|
78
|
+
}
|
|
49
79
|
if (!binding || binding.eventSource) return binding;
|
|
50
80
|
const cached = cache.get(binding);
|
|
51
81
|
if (cached) return cached;
|
|
@@ -73,6 +103,31 @@ function compatibleSessions(sessions) {
|
|
|
73
103
|
};
|
|
74
104
|
}
|
|
75
105
|
|
|
106
|
+
// src/pending-status.ts
|
|
107
|
+
function pendingFromSessionStatus(status) {
|
|
108
|
+
return {
|
|
109
|
+
getSnapshot() {
|
|
110
|
+
const next = /* @__PURE__ */ new Map();
|
|
111
|
+
for (const [id, row] of status.getSnapshot()) {
|
|
112
|
+
const wait = row.pendingInteraction;
|
|
113
|
+
if (!wait || typeof wait !== "object") continue;
|
|
114
|
+
const item = wait;
|
|
115
|
+
next.set(String(id), {
|
|
116
|
+
kind: item.kind,
|
|
117
|
+
key: item.key,
|
|
118
|
+
sessionId: item.sessionId ?? String(id),
|
|
119
|
+
toolName: item.toolName,
|
|
120
|
+
reason: item.reason,
|
|
121
|
+
questions: item.questions,
|
|
122
|
+
answer: typeof item.answer === "function" ? item.answer.bind(item) : void 0
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return next;
|
|
126
|
+
},
|
|
127
|
+
subscribe: (listener) => status.subscribe(listener)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
76
131
|
// src/legacy-pending.ts
|
|
77
132
|
function compatiblePending(sessions, resolveModern) {
|
|
78
133
|
const legacy = legacyPending(sessions);
|
|
@@ -893,7 +948,7 @@ function PluginUpdateHeader({ locale }) {
|
|
|
893
948
|
zh2 ? "\u5BA0\u7269" : "Pets",
|
|
894
949
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dcp-version", children: [
|
|
895
950
|
"v",
|
|
896
|
-
"0.1.
|
|
951
|
+
"0.1.7"
|
|
897
952
|
] })
|
|
898
953
|
] }),
|
|
899
954
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("nav", { className: "dcp-project-links", children: [
|
|
@@ -1880,6 +1935,12 @@ function Companion({
|
|
|
1880
1935
|
);
|
|
1881
1936
|
}
|
|
1882
1937
|
|
|
1938
|
+
// src/activity.ts
|
|
1939
|
+
function selectedSessionId(list) {
|
|
1940
|
+
for (const id of list.ids) if ((list.byId[id]?.retainedBy?.mainView ?? 0) > 0) return id;
|
|
1941
|
+
return list.current;
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1883
1944
|
// src/notifications.ts
|
|
1884
1945
|
var priority = { waiting: 0, failed: 1, review: 2, running: 3 };
|
|
1885
1946
|
var lifetime = { failed: 36e5, waiting: 864e5, review: 6048e5 };
|
|
@@ -1910,7 +1971,8 @@ function createNotifications(sessions, pending, notify, now = Date.now) {
|
|
|
1910
1971
|
if (publishing) return;
|
|
1911
1972
|
publishing = true;
|
|
1912
1973
|
try {
|
|
1913
|
-
const list = sessions.list.getSnapshot(), requests = pending.getSnapshot();
|
|
1974
|
+
const list = sessions.list.getSnapshot(), requests = pending.getSnapshot(), statuses = sessions.status?.getSnapshot();
|
|
1975
|
+
const current = selectedSessionId(list);
|
|
1914
1976
|
const ids = new Set(list.ids.filter((id) => list.byId[id] && list.byId[id].origin !== "subagent"));
|
|
1915
1977
|
for (const id of records.keys()) if (!ids.has(id)) {
|
|
1916
1978
|
records.delete(id);
|
|
@@ -1927,33 +1989,35 @@ function createNotifications(sessions, pending, notify, now = Date.now) {
|
|
|
1927
1989
|
for (const id of ids) {
|
|
1928
1990
|
const row = list.byId[id];
|
|
1929
1991
|
if (!row) continue;
|
|
1992
|
+
const status = statuses?.get(id);
|
|
1930
1993
|
const binding = sessions.binding(id);
|
|
1931
1994
|
let record = records.get(id);
|
|
1932
1995
|
if (!record) {
|
|
1933
|
-
record = { round: 0, running: row.running, completion: !!row.completed, error: null, revision: binding?.eventSource
|
|
1996
|
+
record = { round: 0, running: row.running, completion: !!status?.completionUnread || !!row.completed, error: null, revision: binding?.eventSource?.getSnapshot().revision ?? -1, updatedAt: row.updatedAt ?? now(), lastPose: "" };
|
|
1934
1997
|
records.set(id, record);
|
|
1935
1998
|
}
|
|
1936
1999
|
const previous = bindings.get(id);
|
|
1937
2000
|
if (binding && (previous?.binding.session !== binding.session || previous.binding.eventSource !== binding.eventSource)) {
|
|
1938
2001
|
previous?.off();
|
|
1939
|
-
record.revision = binding.eventSource
|
|
1940
|
-
const offSession = binding.session.subscribe(publish), offEvents = binding.eventSource
|
|
2002
|
+
record.revision = binding.eventSource?.getSnapshot().revision ?? record.revision;
|
|
2003
|
+
const offSession = binding.session.subscribe(publish), offEvents = binding.eventSource?.subscribe(publish);
|
|
1941
2004
|
bindings.set(id, { binding, off: () => {
|
|
1942
2005
|
offSession();
|
|
1943
|
-
offEvents();
|
|
2006
|
+
offEvents?.();
|
|
1944
2007
|
} });
|
|
1945
2008
|
}
|
|
1946
2009
|
const snapshot = binding?.session.getSnapshot();
|
|
1947
|
-
const running = id ===
|
|
2010
|
+
const running = status?.running ?? (id === current ? snapshot?.running ?? row.running : row.running);
|
|
1948
2011
|
if (running && !record.running) {
|
|
1949
2012
|
record.round++;
|
|
1950
2013
|
record.awaitingStart = true;
|
|
1951
2014
|
record.finished = void 0;
|
|
1952
2015
|
record.completion = false;
|
|
1953
2016
|
record.error = null;
|
|
2017
|
+
record.suppressStopCompletion = false;
|
|
1954
2018
|
record.updatedAt = now();
|
|
1955
2019
|
}
|
|
1956
|
-
const events = binding?.eventSource
|
|
2020
|
+
const events = binding?.eventSource?.getSnapshot();
|
|
1957
2021
|
if (events && record.revision !== events.revision) {
|
|
1958
2022
|
record.revision = events.revision;
|
|
1959
2023
|
if (events.change.kind === "append") for (const entry of events.change.entries) {
|
|
@@ -1971,11 +2035,18 @@ function createNotifications(sessions, pending, notify, now = Date.now) {
|
|
|
1971
2035
|
record.updatedAt = now();
|
|
1972
2036
|
}
|
|
1973
2037
|
}
|
|
2038
|
+
else if (events.change.kind === "replace") record.suppressStopCompletion = true;
|
|
1974
2039
|
}
|
|
2040
|
+
const stopped = !running && record.running;
|
|
1975
2041
|
record.running = running;
|
|
1976
|
-
|
|
1977
|
-
record.snapshotError =
|
|
1978
|
-
|
|
2042
|
+
const agentError = snapshot?.lastAgentError ?? snapshot?.promptError?.error?.message ?? null;
|
|
2043
|
+
if (agentError && agentError !== record.snapshotError) record.error = agentError;
|
|
2044
|
+
record.snapshotError = agentError;
|
|
2045
|
+
if (stopped && !record.suppressStopCompletion && !record.finished && !record.error) {
|
|
2046
|
+
record.completion = true;
|
|
2047
|
+
record.updatedAt = now();
|
|
2048
|
+
}
|
|
2049
|
+
if ((status?.completionUnread || row.completed) && !running && (!record.finished || record.finished === "completed")) record.completion = true;
|
|
1979
2050
|
const request2 = requests.get(id);
|
|
1980
2051
|
const activity = selectActivity([{ id, title: row.title ?? row.displayTitle, running, waiting: !!request2, error: running ? null : record.error, completed: !running && record.completion }]);
|
|
1981
2052
|
if (activity.pose === "idle") continue;
|
|
@@ -2002,7 +2073,7 @@ function createNotifications(sessions, pending, notify, now = Date.now) {
|
|
|
2002
2073
|
publishing = false;
|
|
2003
2074
|
}
|
|
2004
2075
|
};
|
|
2005
|
-
const offList = sessions.list.subscribe(publish), offPending = pending.subscribe(publish);
|
|
2076
|
+
const offList = sessions.list.subscribe(publish), offPending = pending.subscribe(publish), offStatus = sessions.status?.subscribe(publish);
|
|
2006
2077
|
publish();
|
|
2007
2078
|
const timer = setInterval(publish, 1e3);
|
|
2008
2079
|
return {
|
|
@@ -2025,6 +2096,7 @@ function createNotifications(sessions, pending, notify, now = Date.now) {
|
|
|
2025
2096
|
return;
|
|
2026
2097
|
}
|
|
2027
2098
|
if (command.type === "open") {
|
|
2099
|
+
if (!sessions.open) throw new Error("\u5BBF\u4E3B\u672A\u63D0\u4F9B\u6253\u5F00\u4F1A\u8BDD\u80FD\u529B");
|
|
2028
2100
|
sessions.open(item.id);
|
|
2029
2101
|
if (item.pose === "review") dismissed.set(item.id, item.token);
|
|
2030
2102
|
publish();
|
|
@@ -2064,6 +2136,7 @@ function createNotifications(sessions, pending, notify, now = Date.now) {
|
|
|
2064
2136
|
dispose() {
|
|
2065
2137
|
offList();
|
|
2066
2138
|
offPending();
|
|
2139
|
+
offStatus?.();
|
|
2067
2140
|
clearInterval(timer);
|
|
2068
2141
|
for (const value of bindings.values()) value.off();
|
|
2069
2142
|
bindings.clear();
|
|
@@ -2072,17 +2145,38 @@ function createNotifications(sessions, pending, notify, now = Date.now) {
|
|
|
2072
2145
|
}
|
|
2073
2146
|
|
|
2074
2147
|
// src/creation.ts
|
|
2148
|
+
function tryOpen(sessions, id) {
|
|
2149
|
+
try {
|
|
2150
|
+
sessions.open?.(id);
|
|
2151
|
+
} catch {
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2075
2154
|
async function createPetSession(sessions, description, directory, skill) {
|
|
2076
2155
|
if (!description.trim() || description.length > 2e3) throw new Error("\u8BF7\u8F93\u5165 1\u20132000 \u5B57\u7684\u5BA0\u7269\u63CF\u8FF0");
|
|
2077
2156
|
const id = await sessions.create({ cwd: directory });
|
|
2078
|
-
sessions.open(id);
|
|
2079
|
-
const binding = sessions.binding(id);
|
|
2080
|
-
if (!binding) throw new Error("\u521B\u5EFA\u4F1A\u8BDD\u5C1A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u8BD5");
|
|
2081
2157
|
const text = `\u8BF7\u5148\u8BFB\u53D6\u5E76\u9075\u5FAA\u5BA0\u7269\u521B\u5EFA Skill\uFF1A${skill}
|
|
2082
2158
|
\u5BA0\u7269\u8981\u6C42\uFF1A${description.trim()}
|
|
2083
2159
|
\u6210\u54C1\u4FDD\u5B58\u5230 ${directory} \u4E0B\u7684\u65B0\u76EE\u5F55\uFF0C\u4FDD\u7559\u6240\u6709\u5DF2\u6709\u5BA0\u7269\u3002\u4F7F\u7528 DSH \u5F53\u524D\u914D\u7F6E\u7684\u56FE\u50CF\u5DE5\u5177\u3002\u7F3A\u5C11\u751F\u56FE\u5DE5\u5177\u65F6\u660E\u786E\u8BF4\u660E\uFF0C\u4E0D\u751F\u6210\u5360\u4F4D\u56FE\uFF0C\u4E0D\u865A\u62A5\u5B8C\u6210\u3002`;
|
|
2084
|
-
const
|
|
2085
|
-
|
|
2160
|
+
const send = async (session) => {
|
|
2161
|
+
const result = await session.prompt([{ type: "text", text }], "queue");
|
|
2162
|
+
if (!result.ok) throw new Error(result.error?.message ?? "DSH \u672A\u63A5\u53D7\u5BA0\u7269\u521B\u5EFA\u8BF7\u6C42");
|
|
2163
|
+
};
|
|
2164
|
+
tryOpen(sessions, id);
|
|
2165
|
+
const binding = sessions.binding(id);
|
|
2166
|
+
if (binding?.session.prompt) {
|
|
2167
|
+
await send(binding.session);
|
|
2168
|
+
tryOpen(sessions, id);
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
if (sessions.using) {
|
|
2172
|
+
await sessions.using(id, { source: "controllerOperation" }, async (reference) => {
|
|
2173
|
+
await reference.ready;
|
|
2174
|
+
await send(reference.binding.session);
|
|
2175
|
+
});
|
|
2176
|
+
tryOpen(sessions, id);
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
throw new Error("\u521B\u5EFA\u4F1A\u8BDD\u5C1A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u8BD5");
|
|
2086
2180
|
}
|
|
2087
2181
|
|
|
2088
2182
|
// src/settings-icon.ts
|
|
@@ -2227,8 +2321,7 @@ function Overlay({
|
|
|
2227
2321
|
activity: state.activity,
|
|
2228
2322
|
tray: { state, command },
|
|
2229
2323
|
open: () => {
|
|
2230
|
-
if (state.activity.sessionId)
|
|
2231
|
-
sessions.open(state.activity.sessionId);
|
|
2324
|
+
if (state.activity.sessionId) sessions.open?.(state.activity.sessionId);
|
|
2232
2325
|
},
|
|
2233
2326
|
settings: openSettings
|
|
2234
2327
|
}
|
|
@@ -2300,11 +2393,58 @@ function Page({
|
|
|
2300
2393
|
}
|
|
2301
2394
|
);
|
|
2302
2395
|
}
|
|
2396
|
+
function probe(ctx, name2) {
|
|
2397
|
+
if (ctx.reflect) {
|
|
2398
|
+
try {
|
|
2399
|
+
return ctx.reflect.get(name2);
|
|
2400
|
+
} catch {
|
|
2401
|
+
return void 0;
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
return ctx[name2];
|
|
2405
|
+
}
|
|
2406
|
+
function liveSessionStatus(ctx) {
|
|
2407
|
+
const resolve = () => {
|
|
2408
|
+
const live = probe(ctx, "uiSession");
|
|
2409
|
+
return live && "sessionStatus" in live ? live.sessionStatus : void 0;
|
|
2410
|
+
};
|
|
2411
|
+
return {
|
|
2412
|
+
getSnapshot() {
|
|
2413
|
+
return resolve()?.getSnapshot() ?? /* @__PURE__ */ new Map();
|
|
2414
|
+
},
|
|
2415
|
+
subscribe(listener) {
|
|
2416
|
+
let source = resolve();
|
|
2417
|
+
let off = source?.subscribe(listener);
|
|
2418
|
+
const timer = setInterval(() => {
|
|
2419
|
+
const next = resolve();
|
|
2420
|
+
if (next === source) return;
|
|
2421
|
+
off?.();
|
|
2422
|
+
source = next;
|
|
2423
|
+
off = next?.subscribe(listener);
|
|
2424
|
+
listener();
|
|
2425
|
+
}, 250);
|
|
2426
|
+
return () => {
|
|
2427
|
+
clearInterval(timer);
|
|
2428
|
+
off?.();
|
|
2429
|
+
};
|
|
2430
|
+
}
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2303
2433
|
function apply(ctx) {
|
|
2304
|
-
const sessions = compatibleSessions(
|
|
2434
|
+
const sessions = compatibleSessions(
|
|
2435
|
+
ctx.sessions,
|
|
2436
|
+
(id) => {
|
|
2437
|
+
const open = ctx.sessions.open;
|
|
2438
|
+
if (open) return open.call(ctx.sessions, id);
|
|
2439
|
+
const uiWorkspace = probe(ctx, "uiWorkspace");
|
|
2440
|
+
if (uiWorkspace) return uiWorkspace.openSession(id);
|
|
2441
|
+
},
|
|
2442
|
+
liveSessionStatus(ctx)
|
|
2443
|
+
);
|
|
2305
2444
|
const pending = compatiblePending(sessions, () => {
|
|
2306
|
-
const
|
|
2307
|
-
return
|
|
2445
|
+
const live = probe(ctx, "uiSession");
|
|
2446
|
+
if (live && "sessionStatus" in live && live.sessionStatus) return pendingFromSessionStatus(live.sessionStatus);
|
|
2447
|
+
return live && "pendingInteractions" in live ? live.pendingInteractions : void 0;
|
|
2308
2448
|
});
|
|
2309
2449
|
ctx.slots.inject(
|
|
2310
2450
|
"settings.section",
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-codex-pet",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "DSH Codex Pet — 为 DeepSeek Harness 提供宠物陪伴、多任务提醒与交互,以及 Skill 自定义宠物 · A pet companion with multi-task notifications, interactions, and Skill-based custom pets for DeepSeek Harness",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"assets:import": "tsx scripts/import-codex.ts"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.0-rc.8 || 0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
|
|
63
63
|
"react": "^18.2.0",
|
|
64
64
|
"react-dom": "^18.2.0"
|
|
65
65
|
},
|
|
@@ -70,13 +70,14 @@
|
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@deepseek-ai/cordis": "4.0.2",
|
|
73
|
-
"@deepseek-ai/dsh": "0.1.
|
|
74
|
-
"@deepseek-ai/dsh-api-session-controller": "0.1.
|
|
75
|
-
"@deepseek-ai/dsh-client-locale": "0.1.
|
|
76
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.1.
|
|
77
|
-
"@deepseek-ai/dsh-client-ui-session": "0.1.
|
|
78
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.
|
|
79
|
-
"@deepseek-ai/dsh-
|
|
73
|
+
"@deepseek-ai/dsh": "0.1.6-alpha.2",
|
|
74
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.6-alpha.2",
|
|
75
|
+
"@deepseek-ai/dsh-client-locale": "0.1.6-alpha.2",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.6-alpha.2",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.6-alpha.2",
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.6-alpha.2",
|
|
79
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.1.6-alpha.2",
|
|
80
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.6-alpha.2",
|
|
80
81
|
"@electron/asar": "^3.4.1",
|
|
81
82
|
"@radix-ui/react-icons": "^1.3.2",
|
|
82
83
|
"@types/node": "^24.0.0",
|