mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`, `verify-translation-pairing --write` for the touched bilingual pairs, `gen-doc-graphs`, and one typert snapshot whose ids embed character offsets. `pnpm run rescope-vendor --check` verifies the result. Renames nine vendored packages (cordis, cosmokit, schemastery and the six @cordisjs plugins) and every reference that resolves them: manifest names and dependency keys, module specifiers including declare-module merges, cordis.yml plugin names, tsconfig paths, every Markdown fence, and `docs/` prose. Directory names, upstream versions, and dependency ranges are unchanged, so vendor/README.md still reads as an upstream snapshot; its manifest table gains an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed at each fork's origin. The tutorial tier follows the rename end to end: its yaml fences named plugins the Loader can no longer resolve, its `ts ignore-check` fences disagreed with the compiled fences beside them, and its prose quoted both. The contracts that told readers to keep upstream names — the root convention and the vendoring cookbook's tree comment and manifest invariant — now say to rescope instead. Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle purity gate now names the vendored libraries a browser bundle inlines, and the files where a bare `cordis` is an agent-preset id keep that product data.
133 lines
4.4 KiB
TypeScript
133 lines
4.4 KiB
TypeScript
/**
|
|
* The third-party memory examples stay config-only. This suite parses every
|
|
* checked-in overlay, verifies its package pin, transport, and secret handling, then replaces
|
|
* only the upstream endpoint with the package-owned keyless MCP fixture and
|
|
* proves the real Cordis Loader discovers a tool through the generic bridge.
|
|
*/
|
|
|
|
import { readFileSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import type { Context } from '@deepseek-ai/cordis'
|
|
import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include'
|
|
import { boot, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot'
|
|
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
|
|
import ToolRegistry from '@deepseek-ai/dsh-tools'
|
|
import * as McpClient from '@deepseek-ai/dsh-mcp-client/src/index.ts'
|
|
|
|
interface ExampleContract {
|
|
file: string
|
|
id: string
|
|
serverName: string
|
|
transport: 'stdio' | 'streamable-http'
|
|
pin: string
|
|
}
|
|
|
|
interface InsertedRow {
|
|
id?: string
|
|
name?: string
|
|
config?: Record<string, unknown>
|
|
}
|
|
|
|
const root = resolve(import.meta.dirname, '../../..')
|
|
const exampleDir = resolve(root, 'examples/mcp-memory')
|
|
const baseConfig = resolve(import.meta.dirname, 'fixtures/memory-mcp-base.cordis.yml')
|
|
const fixtureServer = resolve(root, 'packages/mcp/mcp-client/tests/fixture-server.ts')
|
|
|
|
const examples: ExampleContract[] = [
|
|
{
|
|
file: 'memorix.cordis.yml',
|
|
id: 'memory-memorix',
|
|
serverName: 'memorix',
|
|
transport: 'stdio',
|
|
pin: '1.3.0',
|
|
},
|
|
{
|
|
file: 'mcp-reference-memory.cordis.yml',
|
|
id: 'memory-mcp-reference',
|
|
serverName: 'reference_memory',
|
|
transport: 'stdio',
|
|
pin: '2026.7.4',
|
|
},
|
|
{
|
|
file: 'engram.cordis.yml',
|
|
id: 'memory-engram',
|
|
serverName: 'engram',
|
|
transport: 'stdio',
|
|
pin: '1.20.0',
|
|
},
|
|
]
|
|
|
|
const liveContexts = new Set<Context>()
|
|
|
|
afterEach(async () => {
|
|
await Promise.all([...liveContexts].map(async ctx => ctx.fiber.dispose()))
|
|
liveContexts.clear()
|
|
})
|
|
|
|
function insertedRow(patches: PatchOptions[]): InsertedRow {
|
|
expect(patches).toHaveLength(1)
|
|
const insert = patches[0]?.insert
|
|
expect(insert).toHaveLength(1)
|
|
return insert?.[0] as InsertedRow
|
|
}
|
|
|
|
async function waitForTool(ctx: Context, name: string): Promise<void> {
|
|
const deadline = Date.now() + 10_000
|
|
while (!ctx.tools.schemas().some(schema => schema.name === name)) {
|
|
if (Date.now() >= deadline) throw new Error(`timed out waiting for ${name}`)
|
|
await new Promise(resolveWait => setTimeout(resolveWait, 25))
|
|
}
|
|
}
|
|
|
|
describe('third-party memory MCP example overlays', () => {
|
|
it.each(examples)('parses $file with the documented generic plugin fields', (contract) => {
|
|
const file = resolve(exampleDir, contract.file)
|
|
const source = readFileSync(file, 'utf8')
|
|
const row = insertedRow(loadOverlayPatches('memory-mcp-config-test', file))
|
|
|
|
expect(row.id).toBe(contract.id)
|
|
expect(row.name).toBe('@deepseek-ai/dsh-mcp-client')
|
|
expect(row.config?.serverName).toBe(contract.serverName)
|
|
expect(row.config?.transport).toBe(contract.transport)
|
|
expect(source.split('\n', 1)[0]).toContain(contract.pin)
|
|
expect(source).not.toMatch(/\bsk-[A-Za-z0-9_-]{8,}\b/)
|
|
expect(source).not.toContain('DEEPSEEK_API_KEY')
|
|
})
|
|
|
|
it.each(examples)('loads $file and discovers a keyless fixture tool', async (contract) => {
|
|
const patches = loadOverlayPatches(
|
|
'memory-mcp-config-test',
|
|
resolve(exampleDir, contract.file),
|
|
)
|
|
// The static config gate verifies the checked-in bare package specifier.
|
|
// The unit test maps it to the source module so a clean checkout needs no
|
|
// prebuilt `lib/` artifacts before proving the Loader/MCP behavior.
|
|
insertedRow(patches).name = 'cordis:memory-test-mcp-client'
|
|
const fixturePatch: PatchOptions = {
|
|
id: contract.id,
|
|
config: {
|
|
serverName: contract.serverName,
|
|
transport: 'stdio',
|
|
command: process.execPath,
|
|
args: [fixtureServer],
|
|
env: {},
|
|
cwd: root,
|
|
toolCallTimeoutMs: 5_000,
|
|
},
|
|
}
|
|
const ctx = await boot(
|
|
'memory-mcp-config-test',
|
|
baseConfig,
|
|
[...patches, fixturePatch],
|
|
(ctx) => {
|
|
liveContexts.add(ctx)
|
|
ctx.loader.builtins['memory-test-system-prompt'] = SystemPrompt
|
|
ctx.loader.builtins['memory-test-tools'] = ToolRegistry
|
|
ctx.loader.builtins['memory-test-mcp-client'] = McpClient
|
|
},
|
|
)
|
|
await waitForTool(ctx, `mcp__${contract.serverName}__greet`)
|
|
}, 15_000)
|
|
})
|