diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e36555..6096ef2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,15 +65,6 @@ jobs: - name: Lint mtmharness package metadata run: pnpm dlx publint run "${{ steps.pack.outputs.tarball }}" --strict - - name: Install DSH CLI for Web smoke - if: ${{ matrix.node == '22.19.0' }} - run: npm install --global @deepseek-ai/dsh@0.1.1-rc.2 - - - name: Verify isolated DSH Web profile and tool catalog - if: ${{ matrix.node == '22.19.0' }} - env: - DSH_SMOKE_TOOL_CATALOG: "1" - run: pnpm run smoke:mtmharness -- "${{ steps.pack.outputs.tarball }}" - name: Verify mtmharness profile migration if: ${{ matrix.node == '22.19.0' }} diff --git a/.github/workflows/release-mtmharness.yml b/.github/workflows/release-mtmharness.yml index df4fcfb..6c991ea 100644 --- a/.github/workflows/release-mtmharness.yml +++ b/.github/workflows/release-mtmharness.yml @@ -85,13 +85,6 @@ jobs: - name: Lint package metadata run: pnpm dlx publint run "${{ steps.pack.outputs.tarball }}" --strict - - name: Install DSH CLI for Web smoke - run: npm install --global @deepseek-ai/dsh@0.1.1-rc.2 - - - name: Verify isolated DSH Web profile and tool catalog - env: - DSH_SMOKE_TOOL_CATALOG: "1" - run: pnpm run smoke:mtmharness -- "${{ steps.pack.outputs.tarball }}" - name: Verify mtmharness profile migration run: pnpm --filter mtmharness run profile:check -- "${{ steps.pack.outputs.tarball }}" diff --git a/packages/mtmharness/package.json b/packages/mtmharness/package.json index db00691..f841f10 100644 --- a/packages/mtmharness/package.json +++ b/packages/mtmharness/package.json @@ -1,6 +1,6 @@ { "name": "mtmharness", - "version": "0.5.3", + "version": "0.5.4", "description": "Unified DeepSeek Harness Web plugin with Connect, Canvas, Codebase Memory, Ponytail, and independent static/embed clients.", "type": "module", "engines": { "node": ">=22.19.0", "pnpm": ">=11.7.0" }, diff --git a/packages/mtmharness/standalone/src/components/conversation-surface.test.tsx b/packages/mtmharness/standalone/src/components/conversation-surface.test.tsx new file mode 100644 index 0000000..35b2a5d --- /dev/null +++ b/packages/mtmharness/standalone/src/components/conversation-surface.test.tsx @@ -0,0 +1,60 @@ +// @vitest-environment jsdom + +import { act } from "react"; +import { createRoot } from "react-dom/client"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import type { MtmHarnessRuntime, RuntimeSnapshot } from "@/runtime"; +import { ConversationSurface } from "./conversation-surface"; + +(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true; + +const snapshot: RuntimeSnapshot = { + status: "auth-required", + messages: [], + registryStatus: "idle", + sandboxCatalogStatus: "idle", + sandboxes: [], + workspaces: [], + archivedSessionIds: [], + sessions: [], +}; + +function createRuntime(): MtmHarnessRuntime { + return { + getSnapshot: () => snapshot, + subscribe: vi.fn(() => () => undefined), + connect: vi.fn(async () => undefined), + prompt: vi.fn(async () => undefined), + } as unknown as MtmHarnessRuntime; +} + +let container: HTMLDivElement | undefined; +let root: ReturnType | undefined; + +afterEach(() => { + act(() => root?.unmount()); + container?.remove(); + container = undefined; + root = undefined; +}); + +describe("ConversationSurface authentication gate", () => { + it("explains the anonymous path without presenting auth as transport failure", async () => { + container = document.createElement("div"); + document.body.append(container); + root = createRoot(container); + + await act(async () => { + root?.render( + , + ); + }); + + expect(container.querySelector('[role="status"]')?.textContent).toContain("Sign in above or continue anonymously on the sign-in page"); + expect((container.querySelector("#mtmharness-prompt") as HTMLTextAreaElement).disabled).toBe(true); + expect((container.querySelector('button[aria-label="Send message"]') as HTMLButtonElement).disabled).toBe(true); + }); +}); diff --git a/packages/mtmharness/standalone/src/components/conversation-surface.tsx b/packages/mtmharness/standalone/src/components/conversation-surface.tsx index bb8c0d0..317011b 100644 --- a/packages/mtmharness/standalone/src/components/conversation-surface.tsx +++ b/packages/mtmharness/standalone/src/components/conversation-surface.tsx @@ -17,8 +17,8 @@ function statusLabel(snapshot: RuntimeSnapshot): string { } function statusVariant(snapshot: RuntimeSnapshot): "default" | "secondary" | "destructive" | "outline" { - if (snapshot.status === "error" || snapshot.status === "auth-required") return "destructive"; - if (snapshot.status === "loading" || snapshot.status === "streaming") return "secondary"; + if (snapshot.status === "error") return "destructive"; + if (snapshot.status === "loading" || snapshot.status === "streaming" || snapshot.status === "auth-required") return "secondary"; return "outline"; } @@ -94,8 +94,8 @@ export function ConversationSurface({ config, runtime, compact = false, connectO ) : null} {snapshot.status === "auth-required" ? ( -
- An OAuth access token is required. Configure the token-aware API and WebSocket transport before connecting. +
+ Sign in above or continue anonymously on the sign-in page to start a conversation.
) : null} {snapshot.status === "error" ? (