@michengai/dsh-btw 0.1.8 → 0.1.9
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 +5 -0
- package/CHANGELOG.zh-CN.md +5 -0
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/lib/client.js +5 -10
- package/lib/index.js +28 -7
- package/lib/types/client/SelectionAsk.d.ts +1 -1
- package/lib/types/client/composer.d.ts +3 -2
- package/lib/types/server/tool-guard.d.ts +10 -2
- package/package.json +35 -35
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.9] - 2026-09-18
|
|
4
|
+
|
|
5
|
+
- Support DSH `0.1.6-alpha.2` while retaining compatibility with the six previously supported host versions.
|
|
6
|
+
- Use the official composer focus action when adding a quote to the conversation.
|
|
7
|
+
|
|
3
8
|
## [0.1.8] - 2026-09-16
|
|
4
9
|
|
|
5
10
|
- Support DSH `0.1.6-alpha.1` while retaining compatibility with the five previously supported host versions.
|
package/CHANGELOG.zh-CN.md
CHANGED
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ For a desktop workbench, download [DSH Codex Desktop](https://github.com/Micheng
|
|
|
68
68
|
## Prerequisites
|
|
69
69
|
|
|
70
70
|
- An installed copy of DeepSeek Harness.
|
|
71
|
-
- Host peers accept exactly `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`.
|
|
71
|
+
- Host peers accept exactly `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`.
|
|
72
72
|
- Node.js 22+ and `dsh` available in your terminal.
|
|
73
73
|
|
|
74
74
|
## Installation
|
|
@@ -160,7 +160,7 @@ npm run check
|
|
|
160
160
|
|
|
161
161
|
`npm run check` runs type checking, tests, and a build.
|
|
162
162
|
|
|
163
|
-
Development and builds target `0.1.6-alpha.
|
|
163
|
+
Development and builds target `0.1.6-alpha.2`. `npm run test:compat` builds with that baseline and runs the test suite on each of the seven isolated host versions, using a test model adapter. DOM component tests do not replace live-browser acceptance.
|
|
164
164
|
|
|
165
165
|
Previous manual end-to-end acceptance with Edge and a live DeepSeek model passed on `0.1.5-rc.1`: side questions, attachment rejection, copying, collapse/expand, cancellation, and continued parent-session operation. This is not part of `npm run test:compat`. The selection toolbar, draft insertion, sidebar coexistence, and real-model side answers were subsequently checked on `0.1.5-rc.2`; the full end-to-end suite remains pending on that version and the older three versions.
|
|
166
166
|
|
package/README.zh-CN.md
CHANGED
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
## 前置条件
|
|
69
69
|
|
|
70
70
|
- 已安装 DeepSeek Harness。
|
|
71
|
-
- 宿主 peer 依赖精确声明为 `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`。
|
|
71
|
+
- 宿主 peer 依赖精确声明为 `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`。
|
|
72
72
|
- Node.js 22+,可在终端执行 `dsh`。
|
|
73
73
|
|
|
74
74
|
## 安装
|
|
@@ -159,7 +159,7 @@ npm run check
|
|
|
159
159
|
|
|
160
160
|
`npm run check` 执行类型检查、测试和构建。
|
|
161
161
|
|
|
162
|
-
开发与构建基线为 `0.1.6-alpha.
|
|
162
|
+
开发与构建基线为 `0.1.6-alpha.2`。`npm run test:compat` 用该基线编译,再在七个隔离宿主版本中分别运行测试集,模型使用测试适配器。DOM 组件测试不替代真实浏览器验收。
|
|
163
163
|
|
|
164
164
|
此前在 `0.1.5-rc.1` 上完成真实 Edge 与 DeepSeek 模型的手工端到端验收,旁问、附件拒绝、复制、折叠/展开、取消和父会话继续均通过。这不属于 `npm run test:compat`;随后在 `0.1.5-rc.2` 验证了划词横条、添加引用、侧边栏共存及真实模型旁问回答;该版本与旧三版的完整端到端用例仍未全部验收。
|
|
165
165
|
|
package/lib/client.js
CHANGED
|
@@ -13404,11 +13404,11 @@ function appendQuote(draft, reference) {
|
|
|
13404
13404
|
|
|
13405
13405
|
`;
|
|
13406
13406
|
}
|
|
13407
|
-
function addQuoteToComposer(input, reference, t
|
|
13407
|
+
function addQuoteToComposer(input, reference, t) {
|
|
13408
13408
|
const snapshot = input.state.getSnapshot();
|
|
13409
13409
|
if (snapshot.phase === "adjudicating" || snapshot.phase === "submitting") throw new Error(t("error.composerBusy"));
|
|
13410
13410
|
input.setDraft(appendQuote(snapshot.draft, reference));
|
|
13411
|
-
focus();
|
|
13411
|
+
input.focus?.();
|
|
13412
13412
|
}
|
|
13413
13413
|
|
|
13414
13414
|
// src/client/SelectionAsk.tsx
|
|
@@ -13569,9 +13569,7 @@ function SelectionAsk({ store, sessionId, t, addToConversation }) {
|
|
|
13569
13569
|
const add = () => {
|
|
13570
13570
|
if (!draft) return;
|
|
13571
13571
|
try {
|
|
13572
|
-
addToConversation(draft.reference
|
|
13573
|
-
anchor.current?.closest("[data-composer-seat]")?.querySelector('[contenteditable="true"]:not([aria-disabled="true"]), textarea:not(:disabled):not([readonly])')?.focus({ preventScroll: true });
|
|
13574
|
-
});
|
|
13572
|
+
addToConversation(draft.reference);
|
|
13575
13573
|
setDraft(void 0);
|
|
13576
13574
|
} catch (issue) {
|
|
13577
13575
|
setError(issue instanceof Error ? issue.message : String(issue));
|
|
@@ -13733,13 +13731,10 @@ function apply(ctx) {
|
|
|
13733
13731
|
});
|
|
13734
13732
|
ctx.effect(() => () => store.dispose());
|
|
13735
13733
|
function Dock(props) {
|
|
13736
|
-
return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(SelectionAsk, { key: props.session.sessionId, store, sessionId: props.session.sessionId, t: props.t, addToConversation: (reference
|
|
13734
|
+
return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(SelectionAsk, { key: props.session.sessionId, store, sessionId: props.session.sessionId, t: props.t, addToConversation: (reference) => {
|
|
13737
13735
|
const session = ctx.get("sessions").scope(props.session.sessionId);
|
|
13738
13736
|
if (!session) throw new Error(props.t("error.backend"));
|
|
13739
|
-
|
|
13740
|
-
addQuoteToComposer(input, reference, props.t, () => {
|
|
13741
|
-
focusComposer?.();
|
|
13742
|
-
});
|
|
13737
|
+
addQuoteToComposer(ctx.conversation.input.for(session), reference, props.t);
|
|
13743
13738
|
} }), /* @__PURE__ */ import_react6.default.createElement(BubbleDock, { store, sessionId: props.session.sessionId, t: props.t }));
|
|
13744
13739
|
}
|
|
13745
13740
|
slots.inject("conversation.input.dock", () => slots.register({ name: "conversation.input.dock", id: "michengai-btw", order: -50, locale: NS }, Dock));
|
package/lib/index.js
CHANGED
|
@@ -336,12 +336,33 @@ function descriptorLabel(data) {
|
|
|
336
336
|
if (typeof data !== "object" || data === null || !("label" in data) || typeof data.label !== "string") return void 0;
|
|
337
337
|
return data.label;
|
|
338
338
|
}
|
|
339
|
-
function lastDescriptorLabel(session) {
|
|
340
|
-
if (
|
|
341
|
-
|
|
342
|
-
|
|
339
|
+
function lastDescriptorLabel(session, identityOf) {
|
|
340
|
+
if (!session) return void 0;
|
|
341
|
+
if (identityOf) {
|
|
342
|
+
const identity = identityOf(session);
|
|
343
|
+
return typeof identity?.label === "string" ? identity.label : void 0;
|
|
344
|
+
}
|
|
345
|
+
const events = session.snapshotEvents;
|
|
346
|
+
if (typeof events !== "function") return void 0;
|
|
347
|
+
return descriptorLabel(events().findLast((item) => item.type === "subagent/descriptor")?.data);
|
|
348
|
+
}
|
|
349
|
+
function identityOfFromContext(ctx) {
|
|
350
|
+
try {
|
|
351
|
+
const projections = ctx.get("sessionProjections");
|
|
352
|
+
const snapshot = projections?.snapshot;
|
|
353
|
+
if (typeof snapshot !== "function") return void 0;
|
|
354
|
+
return (session) => {
|
|
355
|
+
try {
|
|
356
|
+
return snapshot(session, ["subagent"]).values?.subagent ?? null;
|
|
357
|
+
} catch {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
} catch {
|
|
362
|
+
return void 0;
|
|
363
|
+
}
|
|
343
364
|
}
|
|
344
|
-
function createAnswerOnlyGuard(labels) {
|
|
365
|
+
function createAnswerOnlyGuard(labels, identityOf) {
|
|
345
366
|
const owned = /* @__PURE__ */ new WeakSet();
|
|
346
367
|
const claim = (value) => {
|
|
347
368
|
if (value) owned.add(value);
|
|
@@ -349,7 +370,7 @@ function createAnswerOnlyGuard(labels) {
|
|
|
349
370
|
const guard = ({ agent }) => {
|
|
350
371
|
if (!agent) return void 0;
|
|
351
372
|
if (owned.has(agent) || agent.session !== void 0 && owned.has(agent.session)) return DENY;
|
|
352
|
-
const label = lastDescriptorLabel(agent.session);
|
|
373
|
+
const label = lastDescriptorLabel(agent.session, identityOf);
|
|
353
374
|
if (!label || !labels.has(label)) return void 0;
|
|
354
375
|
claim(agent);
|
|
355
376
|
claim(agent.session);
|
|
@@ -394,8 +415,8 @@ var PERSONA = `\u4F60\u662F\u5F53\u524D\u4E3B\u4EFB\u52A1\u4E4B\u5916\u7684\u4E0
|
|
|
394
415
|
function apply(ctx) {
|
|
395
416
|
ctx.effect(() => hideInternalCommands(ctx.commands));
|
|
396
417
|
const labels = /* @__PURE__ */ new Set();
|
|
397
|
-
const protection = createAnswerOnlyGuard(labels);
|
|
398
418
|
const host = ctx.extend({ fiber: ctx.root.fiber });
|
|
419
|
+
const protection = createAnswerOnlyGuard(labels, identityOfFromContext(host));
|
|
399
420
|
const releaseGuard = host.tools.guard(protection);
|
|
400
421
|
const stopWatch = host.on("session/event", (session, event) => protection.recognize(session, event));
|
|
401
422
|
const jobs = new SideJobs(async (request) => {
|
|
@@ -6,5 +6,5 @@ export declare function SelectionAsk({ store, sessionId, t, addToConversation }:
|
|
|
6
6
|
store: BubbleStore;
|
|
7
7
|
sessionId: string;
|
|
8
8
|
t: BtwTranslate;
|
|
9
|
-
addToConversation: (reference: string
|
|
9
|
+
addToConversation: (reference: string) => void;
|
|
10
10
|
}): React.JSX.Element;
|
|
@@ -7,9 +7,10 @@ interface DraftInput {
|
|
|
7
7
|
};
|
|
8
8
|
};
|
|
9
9
|
setDraft(text: string): void;
|
|
10
|
+
focus?(): void;
|
|
10
11
|
}
|
|
11
12
|
/** 固定追加引用,保留原草稿;统一引用内部换行,正文空白不裁剪。 */
|
|
12
13
|
export declare function appendQuote(draft: string, reference: string): string;
|
|
13
|
-
/**
|
|
14
|
-
export declare function addQuoteToComposer(input: DraftInput, reference: string, t: BtwTranslate
|
|
14
|
+
/** 提交事务期间不改写草稿;成功写入后把键盘交回宿主输入框。 */
|
|
15
|
+
export declare function addQuoteToComposer(input: DraftInput, reference: string, t: BtwTranslate): void;
|
|
15
16
|
export {};
|
|
@@ -6,8 +6,12 @@ export interface SessionIdentityHint {
|
|
|
6
6
|
snapshotEvents?(): readonly SessionEventLike[];
|
|
7
7
|
}
|
|
8
8
|
export interface AgentIdentity {
|
|
9
|
-
session?:
|
|
9
|
+
session?: object;
|
|
10
10
|
}
|
|
11
|
+
export interface SubagentIdentityHint {
|
|
12
|
+
readonly label?: string;
|
|
13
|
+
}
|
|
14
|
+
export type IdentityOf = (session: object) => SubagentIdentityHint | null | undefined;
|
|
11
15
|
export interface AnswerOnlyGuard {
|
|
12
16
|
(execution: {
|
|
13
17
|
agent?: AgentIdentity;
|
|
@@ -15,5 +19,9 @@ export interface AnswerOnlyGuard {
|
|
|
15
19
|
own(agent: object): void;
|
|
16
20
|
recognize(session: object, event: SessionEventLike): void;
|
|
17
21
|
}
|
|
22
|
+
/** 官方替换同步事件扫描:ctx.sessionProjections.snapshot(session, ['subagent']).values.subagent */
|
|
23
|
+
export declare function identityOfFromContext(ctx: {
|
|
24
|
+
get(name: string): unknown;
|
|
25
|
+
}): IdentityOf | undefined;
|
|
18
26
|
/** 空白名单过滤继承工具;本保护额外拒绝 PTC 及子作用域自注册工具。 */
|
|
19
|
-
export declare function createAnswerOnlyGuard(labels: ReadonlySet<string
|
|
27
|
+
export declare function createAnswerOnlyGuard(labels: ReadonlySet<string>, identityOf?: IdentityOf): AnswerOnlyGuard;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-btw",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "DSH 一次性只读旁问气泡",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -63,44 +63,44 @@
|
|
|
63
63
|
"license": "Apache-2.0",
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
66
|
-
"@deepseek-ai/dsh-commands": "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",
|
|
67
|
-
"@deepseek-ai/dsh-subagent": "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",
|
|
68
|
-
"@deepseek-ai/dsh-tools": "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",
|
|
66
|
+
"@deepseek-ai/dsh-commands": "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",
|
|
67
|
+
"@deepseek-ai/dsh-subagent": "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",
|
|
68
|
+
"@deepseek-ai/dsh-tools": "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",
|
|
69
69
|
"react": "^18.3.1"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@deepseek-ai/cordis": "4.0.2",
|
|
73
|
-
"@deepseek-ai/dsh-agent": "0.1.6-alpha.
|
|
74
|
-
"@deepseek-ai/dsh-agent-loop": "0.1.6-alpha.
|
|
75
|
-
"@deepseek-ai/dsh-api-gateway": "0.1.6-alpha.
|
|
76
|
-
"@deepseek-ai/dsh-api-session-controller": "0.1.6-alpha.
|
|
77
|
-
"@deepseek-ai/dsh-attachment": "0.1.6-alpha.
|
|
78
|
-
"@deepseek-ai/dsh-client-locale": "0.1.6-alpha.
|
|
79
|
-
"@deepseek-ai/dsh-client-ui-chat": "0.1.6-alpha.
|
|
80
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.1.6-alpha.
|
|
81
|
-
"@deepseek-ai/dsh-client-ui-input-trigger": "0.1.6-alpha.
|
|
82
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.1.6-alpha.
|
|
83
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.6-alpha.
|
|
84
|
-
"@deepseek-ai/dsh-client-ui-theme": "0.1.6-alpha.
|
|
85
|
-
"@deepseek-ai/dsh-commands": "0.1.6-alpha.
|
|
86
|
-
"@deepseek-ai/dsh-invariants": "0.1.6-alpha.
|
|
87
|
-
"@deepseek-ai/dsh-llm": "0.1.6-alpha.
|
|
88
|
-
"@deepseek-ai/dsh-ptc-runtime": "0.1.6-alpha.
|
|
89
|
-
"@deepseek-ai/dsh-sandbox": "0.1.6-alpha.
|
|
90
|
-
"@deepseek-ai/dsh-sandbox-policy": "0.1.6-alpha.
|
|
91
|
-
"@deepseek-ai/dsh-scope": "0.1.6-alpha.
|
|
92
|
-
"@deepseek-ai/dsh-session": "0.1.6-alpha.
|
|
93
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.6-alpha.
|
|
94
|
-
"@deepseek-ai/dsh-session-projection": "0.1.6-alpha.
|
|
95
|
-
"@deepseek-ai/dsh-subagent": "0.1.6-alpha.
|
|
96
|
-
"@deepseek-ai/dsh-subagent-fork-in-process": "0.1.6-alpha.
|
|
97
|
-
"@deepseek-ai/dsh-subagent-in-process-driver": "0.1.6-alpha.
|
|
98
|
-
"@deepseek-ai/dsh-system-prompt": "0.1.6-alpha.
|
|
99
|
-
"@deepseek-ai/dsh-tools": "0.1.6-alpha.
|
|
100
|
-
"@deepseek-ai/dsh-user-approval": "0.1.6-alpha.
|
|
101
|
-
"@deepseek-ai/dsh-typert-protocol": "0.1.6-alpha.
|
|
102
|
-
"@deepseek-ai/dsh-typert-registry": "0.1.6-alpha.
|
|
103
|
-
"@deepseek-ai/dsh-util-time": "0.1.6-alpha.
|
|
73
|
+
"@deepseek-ai/dsh-agent": "0.1.6-alpha.2",
|
|
74
|
+
"@deepseek-ai/dsh-agent-loop": "0.1.6-alpha.2",
|
|
75
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.6-alpha.2",
|
|
76
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.6-alpha.2",
|
|
77
|
+
"@deepseek-ai/dsh-attachment": "0.1.6-alpha.2",
|
|
78
|
+
"@deepseek-ai/dsh-client-locale": "0.1.6-alpha.2",
|
|
79
|
+
"@deepseek-ai/dsh-client-ui-chat": "0.1.6-alpha.2",
|
|
80
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.6-alpha.2",
|
|
81
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.1.6-alpha.2",
|
|
82
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.6-alpha.2",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.6-alpha.2",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-theme": "0.1.6-alpha.2",
|
|
85
|
+
"@deepseek-ai/dsh-commands": "0.1.6-alpha.2",
|
|
86
|
+
"@deepseek-ai/dsh-invariants": "0.1.6-alpha.2",
|
|
87
|
+
"@deepseek-ai/dsh-llm": "0.1.6-alpha.2",
|
|
88
|
+
"@deepseek-ai/dsh-ptc-runtime": "0.1.6-alpha.2",
|
|
89
|
+
"@deepseek-ai/dsh-sandbox": "0.1.6-alpha.2",
|
|
90
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.6-alpha.2",
|
|
91
|
+
"@deepseek-ai/dsh-scope": "0.1.6-alpha.2",
|
|
92
|
+
"@deepseek-ai/dsh-session": "0.1.6-alpha.2",
|
|
93
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.6-alpha.2",
|
|
94
|
+
"@deepseek-ai/dsh-session-projection": "0.1.6-alpha.2",
|
|
95
|
+
"@deepseek-ai/dsh-subagent": "0.1.6-alpha.2",
|
|
96
|
+
"@deepseek-ai/dsh-subagent-fork-in-process": "0.1.6-alpha.2",
|
|
97
|
+
"@deepseek-ai/dsh-subagent-in-process-driver": "0.1.6-alpha.2",
|
|
98
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.6-alpha.2",
|
|
99
|
+
"@deepseek-ai/dsh-tools": "0.1.6-alpha.2",
|
|
100
|
+
"@deepseek-ai/dsh-user-approval": "0.1.6-alpha.2",
|
|
101
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.6-alpha.2",
|
|
102
|
+
"@deepseek-ai/dsh-typert-registry": "0.1.6-alpha.2",
|
|
103
|
+
"@deepseek-ai/dsh-util-time": "0.1.6-alpha.2",
|
|
104
104
|
"@types/node": "^22.0.0",
|
|
105
105
|
"@types/react": "^18.3.1",
|
|
106
106
|
"@types/react-dom": "^18.3.7",
|