refactor(skill): scope provider invalidation
This commit is contained in:
@@ -123,12 +123,8 @@ describe('skill-local watcher failures', () => {
|
||||
watchStabilityThresholdMs: 20,
|
||||
})
|
||||
expect((await ctx.skills.list()).map(skill => skill.name)).toEqual(['watched-skill'])
|
||||
const invalidateProvider = ctx.skills.invalidateProvider.bind(ctx.skills)
|
||||
let invalidations = 0
|
||||
ctx.skills.invalidateProvider = (provider) => {
|
||||
invalidations += 1
|
||||
invalidateProvider(provider)
|
||||
}
|
||||
ctx.on('skills/change', () => { invalidations += 1 })
|
||||
const first = watcherHarness.watchers[0]
|
||||
if (first === undefined) throw new Error('expected a root watcher')
|
||||
|
||||
@@ -169,14 +165,17 @@ describe('skill-local watcher failures', () => {
|
||||
watcherHarness.deferredReady = 1
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SkillService)
|
||||
const provider = new SkillLocal.LocalSkillProvider(ctx, {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(home, '.agents'),
|
||||
watch: true,
|
||||
watchPollIntervalMs: 10,
|
||||
watchStabilityThresholdMs: 20,
|
||||
let provider!: InstanceType<typeof SkillLocal.LocalSkillProvider>
|
||||
const disposeProvider = ctx.skills.registerProvider((control) => {
|
||||
provider = new SkillLocal.LocalSkillProvider(ctx, control, {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(home, '.agents'),
|
||||
watch: true,
|
||||
watchPollIntervalMs: 10,
|
||||
watchStabilityThresholdMs: 20,
|
||||
})
|
||||
return provider
|
||||
})
|
||||
ctx.skills.registerProvider(provider)
|
||||
|
||||
const discovery = provider.list({})
|
||||
await settle()
|
||||
@@ -187,6 +186,7 @@ describe('skill-local watcher failures', () => {
|
||||
first.emitter.emit('ready')
|
||||
|
||||
await Promise.all([discovery, disposal])
|
||||
disposeProvider()
|
||||
await settle()
|
||||
expect(first.closeCalls).toBeGreaterThan(0)
|
||||
})
|
||||
@@ -198,14 +198,17 @@ describe('skill-local watcher failures', () => {
|
||||
watcherHarness.deferredReady = 1
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SkillService)
|
||||
const provider = new SkillLocal.LocalSkillProvider(ctx, {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(home, '.agents'),
|
||||
watch: true,
|
||||
watchPollIntervalMs: 10,
|
||||
watchStabilityThresholdMs: 20,
|
||||
let provider!: InstanceType<typeof SkillLocal.LocalSkillProvider>
|
||||
const disposeProvider = ctx.skills.registerProvider((control) => {
|
||||
provider = new SkillLocal.LocalSkillProvider(ctx, control, {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(home, '.agents'),
|
||||
watch: true,
|
||||
watchPollIntervalMs: 10,
|
||||
watchStabilityThresholdMs: 20,
|
||||
})
|
||||
return provider
|
||||
})
|
||||
ctx.skills.registerProvider(provider)
|
||||
|
||||
const discovery = provider.list({})
|
||||
await settle()
|
||||
@@ -216,5 +219,6 @@ describe('skill-local watcher failures', () => {
|
||||
|
||||
await expect(discovery).rejects.toThrow('opening failed during disposal')
|
||||
await disposal
|
||||
disposeProvider()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -572,12 +572,8 @@ describe('LocalSkillProvider', () => {
|
||||
const root = join(home, '.agents/skills')
|
||||
const ctx = await setupLocal(home)
|
||||
expect(await ctx.skills.list()).toEqual([])
|
||||
const invalidateProvider = ctx.skills.invalidateProvider.bind(ctx.skills)
|
||||
let invalidations = 0
|
||||
ctx.skills.invalidateProvider = (provider) => {
|
||||
invalidations += 1
|
||||
invalidateProvider(provider)
|
||||
}
|
||||
ctx.on('skills/change', () => { invalidations += 1 })
|
||||
|
||||
await writeSkill(root, 'observed-skill', 'Observed skill')
|
||||
const path = join(root, 'observed-skill/SKILL.md')
|
||||
@@ -657,15 +653,18 @@ describe('LocalSkillProvider', () => {
|
||||
await writeSkill(join(home, '.agents/skills'), 'disposed-skill', 'Disposed skill')
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SkillService)
|
||||
const provider = new SkillLocal.LocalSkillProvider(ctx, {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(home, '.agents'),
|
||||
customSkillDirs: [nonDirectoryRoot],
|
||||
watch: true,
|
||||
watchStabilityThresholdMs: 20,
|
||||
watchPollIntervalMs: 10,
|
||||
let provider!: SkillLocal.LocalSkillProvider
|
||||
const disposeProvider = ctx.skills.registerProvider((control) => {
|
||||
provider = new SkillLocal.LocalSkillProvider(ctx, control, {
|
||||
dshHome: join(home, '.dsh'),
|
||||
agentsHome: join(home, '.agents'),
|
||||
customSkillDirs: [nonDirectoryRoot],
|
||||
watch: true,
|
||||
watchStabilityThresholdMs: 20,
|
||||
watchPollIntervalMs: 10,
|
||||
})
|
||||
return provider
|
||||
})
|
||||
ctx.skills.registerProvider(provider)
|
||||
expect((await provider.list({})).map(skill => skill.name)).toEqual(['disposed-skill'])
|
||||
|
||||
await provider.dispose()
|
||||
@@ -673,6 +672,7 @@ describe('LocalSkillProvider', () => {
|
||||
provider.observeHostMutation(join(home, '.agents/skills/disposed-skill/SKILL.md'))
|
||||
|
||||
expect((await provider.list({})).map(skill => skill.name)).toEqual(['disposed-skill'])
|
||||
disposeProvider()
|
||||
})
|
||||
|
||||
it('refreshes frontmatter through a followed skill symlink', { timeout: 10000 }, async () => {
|
||||
@@ -740,7 +740,10 @@ describe('LocalSkillProvider', () => {
|
||||
expect(await empty.skills.list()).toEqual([])
|
||||
|
||||
delete process.env.DSH_AGENTS_HOME
|
||||
expect(new SkillLocal.LocalSkillProvider(empty, { dshHome: join(envHome, 'empty-dsh') }).name).toBe('local')
|
||||
expect(new SkillLocal.LocalSkillProvider(empty, {
|
||||
signal: new AbortController().signal,
|
||||
invalidate() {},
|
||||
}, { dshHome: join(envHome, 'empty-dsh') }).name).toBe('local')
|
||||
} finally {
|
||||
if (previousDshHome === undefined) {
|
||||
delete process.env.DSH_HOME
|
||||
|
||||
Reference in New Issue
Block a user