mirror of
https://gh-proxy.org/https://github.com/klinsmaya/dsh-oil-creator.git
synced 2026-11-08 01:06:46 +08:00
fix(sidebar): 兼容新版 Harness 新建会话接口
This commit is contained in:
@@ -155,3 +155,10 @@ ego-browser nodejs < scripts/collect-publish.mjs
|
||||
- 重媒体继续调用已有脚本,参数与对应 SKILL.md 保持一致。
|
||||
- 人导出、人点平台发布、Agent 做校对和标题,这三件事不要改成全自动。
|
||||
- Host remote 或工具改完后要重新 `pnpm build` 并重启 `dsh web`。
|
||||
|
||||
|
||||
### 新建会话接口兼容
|
||||
|
||||
侧栏新建会话的版本回归基线(2026-09-10):本地编译依赖为 `0.1.1-rc.2`,实际使用的是 DSH Desktop `2.0.5`、`web` profile,桌面安装包内置 Harness `0.1.2-rc.1`。本地 Harness 仓库 HEAD 为 `47f943859bef60e4160492346772ded9b24f765a`,接口判断以桌面安装产物为准。旧版调用 `workspaces.startSession`,新版官方侧栏调用 `uiWorkspace.startSession`;插件通过 `sidebar/startSession.ts` 在点击时解析服务,优先新版并保留旧版入口,不复制宿主的工作区选择、空会话复用和导航策略。
|
||||
|
||||
升级验收必须对照实际宿主的官方侧栏和服务实现,不能只依赖项目锁定版本的类型检查。`sidebarStartSession.test.ts` 覆盖新版控制器不含旧方法、旧版透传工作区、服务方法接收者、失败不重复创建及服务重新解析;入口契约测试同时防止绕过适配器。未进行人工点击或授权的界面验收时,不能把代码测试表述为按钮已在实际窗口验证。
|
||||
|
||||
@@ -40,6 +40,7 @@ import { CreatorSettingsCard } from "./CreatorSettingsCard.tsx";
|
||||
import type { CreatorViewFace } from "./face.ts";
|
||||
import { en, NS, type CreatorKey, zh } from "./locales.ts";
|
||||
import { OilSidebarRoot } from "./sidebar/OilSidebarRoot.tsx";
|
||||
import { startSidebarSession } from "./sidebar/startSession.ts";
|
||||
import type { OilSidebarInjected, OilSidebarSlotProps } from "./sidebar/slots.ts";
|
||||
import {
|
||||
registerCreatorSettingsCard,
|
||||
@@ -297,7 +298,7 @@ export function apply(ctx: ClientContext): void {
|
||||
|
||||
const injectSidebar = (): OilSidebarInjected => ({
|
||||
startSession: (workspaceId?: WorkspaceId) => {
|
||||
ctx.workspaces.startSession(workspaceId);
|
||||
startSidebarSession(ctx, workspaceId);
|
||||
},
|
||||
toggleSidebar: () => {
|
||||
ctx.layout.toggleSidebar();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { WorkspaceId } from "@deepseek-ai/dsh-client-runtime/client";
|
||||
|
||||
interface SessionNavigation {
|
||||
startSession: (workspaceId?: WorkspaceId) => void;
|
||||
}
|
||||
|
||||
/** 0.1.2-rc.1 将导航迁入 uiWorkspace;0.1.1-rc.2 仍由 workspaces 提供。 */
|
||||
export function startSidebarSession(
|
||||
ctx: { get: (name: string) => unknown },
|
||||
workspaceId?: WorkspaceId,
|
||||
): void {
|
||||
// 点击时解析,避免保存尚未就绪或热更新前的服务实例。
|
||||
for (const name of ["uiWorkspace", "workspaces"]) {
|
||||
const navigation = ctx.get(name) as Partial<SessionNavigation> | undefined;
|
||||
if (typeof navigation?.startSession === "function") {
|
||||
navigation.startSession(workspaceId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new Error("新建会话服务尚未就绪,请刷新页面后重试。");
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import type { WorkspaceId } from "@deepseek-ai/dsh-client-runtime/client";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { startSidebarSession } from "../src/client/sidebar/startSession.ts";
|
||||
|
||||
describe("侧栏新建会话版本兼容", () => {
|
||||
it("侧栏入口统一经过兼容适配器", () => {
|
||||
const source = readFileSync(new URL("../src/client/index.tsx", import.meta.url), "utf8");
|
||||
expect(source).toContain("startSidebarSession(ctx, workspaceId)");
|
||||
expect(source).not.toContain("ctx.workspaces.startSession(");
|
||||
});
|
||||
|
||||
it("新版 workspaces 不再提供导航时,使用 uiWorkspace 并保留方法接收者", () => {
|
||||
const navigation = {
|
||||
current: "old-session",
|
||||
startSession() { this.current = "blank-session"; },
|
||||
};
|
||||
const services = new Map<string, unknown>([
|
||||
["uiWorkspace", navigation],
|
||||
["workspaces", { list: {} }],
|
||||
]);
|
||||
|
||||
startSidebarSession({ get: (name) => services.get(name) });
|
||||
|
||||
expect(navigation.current).toBe("blank-session");
|
||||
});
|
||||
|
||||
it("旧版仍可新建会话,并透传指定工作区", () => {
|
||||
const startSession = vi.fn();
|
||||
const ctx = { get: (name: string) => name === "workspaces" ? { startSession } : undefined };
|
||||
const workspaceId = "workspace-a" as WorkspaceId;
|
||||
|
||||
startSidebarSession(ctx, workspaceId);
|
||||
startSidebarSession(ctx);
|
||||
|
||||
expect(startSession.mock.calls).toEqual([[workspaceId], [undefined]]);
|
||||
});
|
||||
|
||||
it("优先新版服务,且不在调用失败后重复创建", () => {
|
||||
const legacy = vi.fn();
|
||||
const failure = new Error("navigation failed");
|
||||
const modern = vi.fn(() => { throw failure; });
|
||||
const ctx = { get: (name: string) => ({ startSession: name === "uiWorkspace" ? modern : legacy }) };
|
||||
|
||||
expect(() => startSidebarSession(ctx)).toThrow(failure);
|
||||
expect(modern).toHaveBeenCalledOnce();
|
||||
expect(legacy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("服务未就绪时明确失败,后续点击重新解析服务", () => {
|
||||
const services = new Map<string, unknown>([["workspaces", {}]]);
|
||||
const ctx = { get: (name: string) => services.get(name) };
|
||||
expect(() => startSidebarSession(ctx)).toThrow("新建会话服务尚未就绪");
|
||||
|
||||
const startSession = vi.fn();
|
||||
services.set("uiWorkspace", { startSession });
|
||||
startSidebarSession(ctx);
|
||||
expect(startSession).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user