Files
goodbuddy/src/shared/goodbuddy-config-contracts.test.ts
T
mesalogo 5cdffee9ee
GoodBuddy Agents / Validate Agent source (push) Canceled after 0s
GoodBuddy Agents / Build darwin arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux x64 Agent (push) Canceled after 0s
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s
release: validate the complete 0.15.0 branch snapshot
Account for concurrent composer, conversation-order, desktop-notification,
and Supervisor discussion changes in bilingual notes and feature matrices.
Correct the removed entity-writeback description in the companion article.

Align the configuration fixture with the default-on notification setting,
scope note-source UI queries and wait for completed actions, and preserve
all real Obsidian child-process checks with a 15-second scenario allowance.

Validation: frozen complete tree passed 5371 Linux tests with 51 skipped;
19 focused Windows tests, typecheck, lint, and release-note validation passed.
The older 5345-test Host result did not cover all concurrent branch changes
and is not treated as validation of this complete candidate.
2026-09-28 03:06:41 +08:00

257 lines
7.6 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
goodbuddyConfigApplyInputSchema,
goodbuddyConfigCapabilities,
goodbuddyConfigCapabilitiesOutputSchema,
goodbuddyConfigCommonExamples,
goodbuddyConfigGetOutputSchema,
goodbuddyConfigOperationNameSchema,
goodbuddyConfigOperationSchema,
goodbuddyConfigPlanInputSchema,
goodbuddyConfigPlanOutputSchema
} from './goodbuddy-config-contracts'
import {
goodbuddyConfigToolByName,
goodbuddyConfigTools
} from './goodbuddy-config-tools'
import { defaultLocalToolEnvironmentSettings } from './local-tool-environment-contracts'
import { defaultApplicationNavigation } from './application-settings-contracts'
describe('GoodBuddy configuration contracts', () => {
it('uses the authoritative full application order for configuration-tool writes', () => {
const operation = {
operation: 'application.update',
updates: { applicationNavigation: {
...defaultApplicationNavigation,
order: ['local-inference', 'heartbeat', 'magic-notes', 'knowledge'],
} },
}
expect(goodbuddyConfigOperationSchema.parse(operation)).toEqual(operation)
for (const order of [['magic-notes', 'local-inference'], ['knowledge', 'heartbeat', 'magic-notes', 'magic-notes'], ['knowledge', 'heartbeat', 'magic-notes', 'invalid']]) {
expect(goodbuddyConfigOperationSchema.safeParse({ ...operation, updates: {
applicationNavigation: { ...defaultApplicationNavigation, order },
} }).success).toBe(false)
}
})
it('publishes one valid generated example for every operation', () => {
const operationNames = goodbuddyConfigOperationNameSchema.options
expect(goodbuddyConfigCommonExamples).toHaveLength(
operationNames.length
)
expect(
goodbuddyConfigCommonExamples.map(({ operation }) => operation)
).toEqual(operationNames)
for (const example of goodbuddyConfigCommonExamples) {
expect(goodbuddyConfigOperationSchema.parse(example)).toEqual(
example
)
}
expect(
goodbuddyConfigCapabilitiesOutputSchema.parse(
goodbuddyConfigCapabilities
)
).toEqual(goodbuddyConfigCapabilities)
})
it('accepts a bounded sequence of strongly typed operations', () => {
const input = {
operations: [
{
operation: 'application.update',
updates: {
magicNotesEnabled: true,
magicNoteCommentMode: 'after-save-manual',
magicNoteCanvasPageCount: 8
}
},
{
operation: 'skill.setAssignments',
skillId: 'document-writing',
assignments: ['model', 'continue']
},
{
operation: 'mcp.add',
connection: {
name: 'Project MCP',
description: '',
allowDynamicTools: false,
transport: 'http',
url: 'https://mcp.example.com/tools'
},
enabled: false,
assignments: ['model']
}
]
}
expect(goodbuddyConfigPlanInputSchema.parse(input)).toEqual(input)
})
it('keeps custom MCP assignments limited to the direct model', () => {
expect(() =>
goodbuddyConfigOperationSchema.parse({
operation: 'mcp.add',
connection: {
name: 'Project MCP',
description: '',
allowDynamicTools: false,
transport: 'http',
url: 'https://mcp.example.com/tools'
},
enabled: true,
assignments: ['continue']
})
).toThrow()
})
it('never accepts MCP secrets or credential-bearing remote URLs', () => {
const baseConnection = {
name: 'Project MCP',
description: '',
allowDynamicTools: false,
transport: 'http',
url: 'https://mcp.example.com/tools'
}
expect(() =>
goodbuddyConfigOperationSchema.parse({
operation: 'mcp.add',
connection: {
...baseConnection,
secret: { action: 'replace', value: 'do-not-accept' }
},
enabled: true,
assignments: ['model']
})
).toThrow()
expect(() =>
goodbuddyConfigOperationSchema.parse({
operation: 'mcp.update',
serverId: '00000000-0000-4000-8000-000000000001',
connection: {
...baseConnection,
url: 'https://user:password@mcp.example.com/tools'
}
})
).toThrow()
expect(() =>
goodbuddyConfigOperationSchema.parse({
operation: 'mcp.update',
serverId: '00000000-0000-4000-8000-000000000001',
connection: {
...baseConnection,
url: 'https://mcp.example.com/tools?token=secret'
}
})
).toThrow()
})
it('only exposes redacted MCP summaries from get', () => {
const snapshot = {
application: {
checkUpdatesOnStartup: true,
desktopNotificationsEnabled: true,
updateSource: 'github',
modelDownloadSource: 'modelscope',
localToolEnvironment: defaultLocalToolEnvironmentSettings,
applicationNavigation: defaultApplicationNavigation,
localInferenceEnabled: true,
conversationHtmlRenderingEnabled: true,
remoteProjectsEnabled: false,
magicNotesEnabled: true,
magicNotesShowIncompleteTodoCount: true,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined',
magicNoteCanvasPageCount: 1
},
skills: [],
mcpServers: [
{
id: '00000000-0000-4000-8000-000000000001',
name: 'Project MCP',
description: '',
enabled: true,
allowDynamicTools: false,
assignments: ['model'],
secretConfigured: true,
transport: 'http'
}
]
}
expect(goodbuddyConfigGetOutputSchema.parse(snapshot)).toEqual(
snapshot
)
expect(() =>
goodbuddyConfigGetOutputSchema.parse({
...snapshot,
mcpServers: [
{
...snapshot.mcpServers[0],
url: 'https://mcp.example.com?token=secret',
secret: 'secret'
}
]
})
).toThrow()
})
it('requires an expiring, approved plan and applies only its ID', () => {
const operation = goodbuddyConfigCommonExamples[0]!
expect(
goodbuddyConfigPlanOutputSchema.parse({
planId: '00000000-0000-4000-8000-000000000002',
expiresAt: '2030-01-01T00:00:00.000Z',
operations: [operation],
steps: [
{
index: 0,
operation: operation.operation,
summary: 'Update startup checks.',
risk: 'low',
reload: 'none',
destructive: false
}
],
overallRisk: 'low',
reload: 'none',
requiresApproval: true
}).requiresApproval
).toBe(true)
expect(
goodbuddyConfigApplyInputSchema.parse({
planId: '00000000-0000-4000-8000-000000000002'
})
).toEqual({
planId: '00000000-0000-4000-8000-000000000002'
})
expect(() =>
goodbuddyConfigApplyInputSchema.parse({
planId: '00000000-0000-4000-8000-000000000002',
operations: [operation]
})
).toThrow()
})
it('catalogs the four request-scoped MCP tools', () => {
expect(goodbuddyConfigTools.map(({ name }) => name)).toEqual([
'goodbuddy_config_capabilities',
'goodbuddy_config_get',
'goodbuddy_config_plan',
'goodbuddy_config_apply'
])
expect(
goodbuddyConfigToolByName.get('goodbuddy_config_apply')?.access
).toBe(
'write'
)
expect(
goodbuddyConfigTools
.filter(({ name }) => name !== 'goodbuddy_config_apply')
.every(({ access }) => access === 'read')
).toBe(true)
})
})