Some checks failed
CI / node 22.19 (push) Has been skipped
CI / node 26 (push) Has been skipped
CI / python 3.10 / keyless SDK (push) Has been skipped
CI / python runtime / release-shaped Linux x64 (push) Has been skipped
CI / windows node 24 / wine blocking (push) Has been skipped
CI / wine apt cache (push) Successful in 6s
CI / serial / linux (push) Has been skipped
Release (vendor) / Pack npm tarballs (push) Failing after 1m59s
Release (dsh) / Pack npm tarballs (push) Failing after 1m57s
Sandbox / sandbox e2e (landlock, ubuntu-24.04) (push) Failing after 1m59s
Sandbox / sandbox e2e (bwrap, ubuntu-latest) (push) Failing after 1m23s
Release (vendor) / Publish to npm (push) Has been skipped
Release (dsh) / Publish to npm (push) Has been skipped
CI / node 24 / static (push) Has been cancelled
CI / node 24 / coverage (push) Has been cancelled
CI / larger-runner-benchmark (16, windows, dsh-windows-2025-16core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (32, linux, dsh-ubuntu-24-04-32core, typecheck) (push) Has been cancelled
CI / serial / windows (self-hosted standby) (push) Has been cancelled
CI / larger-runner-benchmark (16, linux, dsh-ubuntu-24-04-16core, typecheck) (push) Has been cancelled
CI / node 24 / snapshots and artifacts (push) Has been cancelled
CI / windows node 24 / native complete (push) Has been cancelled
CI / serial / linux (self-hosted standby) (push) Has been cancelled
CI / serial / macos (push) Has been cancelled
CI / larger-runner-benchmark (32, windows, dsh-windows-2025-32core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (4, linux, dsh-ubuntu-24-04-4core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (4, windows, dsh-windows-2025-4core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (64, linux, dsh-ubuntu-24-04-64core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (64, windows, dsh-windows-2025-64core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (8, linux, dsh-ubuntu-24-04-8core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (8, windows, dsh-windows-2025-8core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (96, linux, dsh-ubuntu-24-04-96core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (96, windows, dsh-windows-2025-96core, production-site) (push) Has been cancelled
CI / consolidated-runner-benchmark (16, linux, dsh-ubuntu-24-04-16core, 16) (push) Has been cancelled
CI / consolidated-runner-benchmark (16, windows, dsh-windows-2025-16core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (32, linux, dsh-ubuntu-24-04-32core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (32, windows, dsh-windows-2025-32core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (4, linux, dsh-ubuntu-24-04-4core, 4) (push) Has been cancelled
CI / consolidated-runner-benchmark (4, windows, dsh-windows-2025-4core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (64, linux, dsh-ubuntu-24-04-64core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (64, windows, dsh-windows-2025-64core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (8, linux, dsh-ubuntu-24-04-8core, 8) (push) Has been cancelled
CI / consolidated-runner-benchmark (8, windows, dsh-windows-2025-8core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (96, linux, dsh-ubuntu-24-04-96core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (96, windows, dsh-windows-2025-96core, 2) (push) Has been cancelled
CI / all checks passed (push) Has been cancelled
Sandbox / sandbox e2e (seatbelt, macos-latest) (push) Has been cancelled
Sandbox / sandbox e2e (landlock, ubuntu-24.04-arm) (push) Has been cancelled
E2E (real DeepSeek API) / e2e (push) Failing after 1m36s
The Host cordisInspect registry threw on any duplicate provider id, but tool-cordis is mounted per-preset (standing scope), so two presets that both include it (e.g. `maximum` and a user copy such as `design`) collide. `register()` now replaces the stored entry when the incoming manifest is structurally identical (same id, description, and methods); a provider with the same id but a different manifest still throws as before. Added `jsonEqual` and `sameManifest` module-private helpers; new spec covers first register, identical re-register, different-manifest reject, empty-id validation, and method-array mismatch.
87 lines
3.3 KiB
TypeScript
87 lines
3.3 KiB
TypeScript
import { Context } from '@deepseek-ai/cordis'
|
|
import { describe, expect, it } from 'vitest'
|
|
import { CordisInspectRegistryService, type HostCordisInspectProviderRegistration } from '../src/inspect-registry.ts'
|
|
|
|
function makeProvider(id: string, desc: string): HostCordisInspectProviderRegistration {
|
|
return {
|
|
manifest: {
|
|
id,
|
|
description: desc,
|
|
methods: [{
|
|
name: 'list',
|
|
description: 'List things.',
|
|
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
outputSchema: { description: 'anything' },
|
|
}],
|
|
},
|
|
async query() { return {} },
|
|
}
|
|
}
|
|
|
|
describe('CordisInspectRegistryService', () => {
|
|
it('accepts the first registration of a provider id', () => {
|
|
const ctx = new Context()
|
|
const svc = new CordisInspectRegistryService(ctx)
|
|
const p = makeProvider('Service', 'desc')
|
|
const dispose = svc.register(p)
|
|
expect(svc.list()).toContainEqual(expect.objectContaining({ id: 'Service', platform: 'host' }))
|
|
dispose()
|
|
expect(svc.list()).not.toContainEqual(expect.objectContaining({ id: 'Service' }))
|
|
})
|
|
|
|
it('replaces on identical re-registration without throwing', () => {
|
|
const ctx = new Context()
|
|
const svc = new CordisInspectRegistryService(ctx)
|
|
const p = makeProvider('Service', 'desc')
|
|
const disposeA = svc.register(p)
|
|
const disposeB = svc.register(p) // same object — identical manifest
|
|
// Still in the directory (replaced, not removed)
|
|
expect(svc.list()).toContainEqual(expect.objectContaining({ id: 'Service', platform: 'host' }))
|
|
// disposeA should be a no-op because the map entry was replaced
|
|
disposeA()
|
|
expect(svc.list()).toContainEqual(expect.objectContaining({ id: 'Service', platform: 'host' }))
|
|
// disposeB removes the current registration
|
|
disposeB()
|
|
expect(svc.list()).not.toContainEqual(expect.objectContaining({ id: 'Service' }))
|
|
})
|
|
|
|
it('rejects a different manifest claiming the same id', () => {
|
|
const ctx = new Context()
|
|
const svc = new CordisInspectRegistryService(ctx)
|
|
svc.register(makeProvider('Service', 'original'))
|
|
expect(() => svc.register(makeProvider('Service', 'different')))
|
|
.toThrow('Host Cordis inspect provider "Service" is already registered')
|
|
})
|
|
|
|
it('rejects empty provider id', () => {
|
|
const ctx = new Context()
|
|
const svc = new CordisInspectRegistryService(ctx)
|
|
expect(() => svc.register(makeProvider('', 'empty')))
|
|
.toThrow('Cordis inspect provider id must not be empty')
|
|
})
|
|
|
|
it('detects method-array length mismatch as unequal', () => {
|
|
const ctx = new Context()
|
|
const svc = new CordisInspectRegistryService(ctx)
|
|
const a: HostCordisInspectProviderRegistration = {
|
|
manifest: {
|
|
id: 'X', description: 'd',
|
|
methods: [{ name: 'a', description: 'a', inputSchema: {}, outputSchema: {} }],
|
|
},
|
|
async query() { return {} },
|
|
}
|
|
const b: HostCordisInspectProviderRegistration = {
|
|
manifest: {
|
|
id: 'X', description: 'd',
|
|
methods: [
|
|
{ name: 'a', description: 'a', inputSchema: {}, outputSchema: {} },
|
|
{ name: 'b', description: 'b', inputSchema: {}, outputSchema: {} },
|
|
],
|
|
},
|
|
async query() { return {} },
|
|
}
|
|
svc.register(a)
|
|
expect(() => svc.register(b)).toThrow('already registered')
|
|
})
|
|
})
|