mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 10:08:13 +00:00
* fix(plugins): reject locale ids Intl cannot parse `pluginLocaleIdSchema` checks the shape of a locale id but not its grammar, and the shape check is looser than BCP 47 in one direction: `en-US-US` (duplicate region) and `en-aaa` (a subtag that is neither region nor script) both match it. A pack declaring one installs, loads, and translates every string — and then `Intl.DateTimeFormat` throws inside `getIntlLocale()`, which swallows the error and falls back to English. Nothing is logged, so the pack author sees a working pack with English dates and no way to tell why. Delegate the grammar to `Intl.getCanonicalLocales` in a `.refine`, so the tag is rejected at install where the author can still act on it. The bundled `pt-BR` pack and every other well-formed tag are unaffected. * Condense this branch's comments to one line AGENTS.md asks for one-line comments that say why, and main's comment cleanup (#33249) applied that across the repository. This brings the comments this branch adds in line with it. No code changes. --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
167 lines
5.2 KiB
TypeScript
167 lines
5.2 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { parsePluginManifest, pluginManifestSchema } from './plugin-manifest'
|
|
|
|
function manifest(contributes: Record<string, unknown>): Record<string, unknown> {
|
|
return {
|
|
manifestVersion: 1,
|
|
id: 'content-pack',
|
|
publisher: 'orca-samples',
|
|
name: 'Content pack',
|
|
version: '1.0.0',
|
|
engines: { orca: '>=1.0.0' },
|
|
pluginApi: 1,
|
|
contributes,
|
|
capabilities: []
|
|
}
|
|
}
|
|
|
|
describe('content-pack manifest contributions', () => {
|
|
it('accepts the documented P1 contribution set without a worker', () => {
|
|
const parsed = pluginManifestSchema.parse(
|
|
manifest({
|
|
languagePacks: [{ locale: 'pt-BR', path: 'locales/pt-BR.json' }],
|
|
commands: [
|
|
{
|
|
id: 'workspace.openTasks',
|
|
title: 'Open tasks',
|
|
context: 'worktree',
|
|
action: 'view.tasks'
|
|
}
|
|
],
|
|
keybindings: [{ command: 'workspace.openTasks', key: 'Mod+Alt+T' }],
|
|
vmRecipes: [{ path: 'recipes/fly.json' }],
|
|
agents: [{ path: 'agents/custom.json' }]
|
|
})
|
|
)
|
|
|
|
expect(parsed.main).toBeUndefined()
|
|
expect(parsed.contributes.languagePacks[0]?.locale).toBe('pt-BR')
|
|
expect(parsed.contributes.keybindings[0]?.key).toBe('Mod+Alt+T')
|
|
})
|
|
|
|
it('defaults every contribution registry to an empty array', () => {
|
|
const parsed = pluginManifestSchema.parse(manifest({}))
|
|
|
|
expect(parsed.contributes).toEqual({
|
|
panels: [],
|
|
commands: [],
|
|
events: [],
|
|
languagePacks: [],
|
|
keybindings: [],
|
|
vmRecipes: [],
|
|
agents: []
|
|
})
|
|
})
|
|
|
|
it('rejects the removed plugin skills contribution', () => {
|
|
expect(parsePluginManifest(manifest({ skills: [{ path: 'skills' }] }))).toMatchObject({
|
|
ok: false,
|
|
error: expect.stringContaining('Unrecognized key')
|
|
})
|
|
})
|
|
|
|
it('still requires a worker entry for non-alias commands', () => {
|
|
expect(
|
|
parsePluginManifest(
|
|
manifest({ commands: [{ id: 'content-pack.run', title: 'Run content pack' }] })
|
|
)
|
|
).toMatchObject({ ok: false, error: expect.stringContaining('worker command') })
|
|
})
|
|
|
|
it.each([
|
|
[
|
|
'unknown alias target',
|
|
{
|
|
commands: [{ id: 'open', title: 'Open', action: 'missing.action' }]
|
|
},
|
|
'unknown built-in action'
|
|
],
|
|
[
|
|
'unknown command reference',
|
|
{ keybindings: [{ command: 'missing', key: 'Mod+K' }] },
|
|
'unknown contributed command'
|
|
],
|
|
[
|
|
'invalid chord',
|
|
{
|
|
commands: [{ id: 'open', title: 'Open', action: 'view.tasks' }],
|
|
keybindings: [{ command: 'open', key: 'Mod+NotAKey' }]
|
|
},
|
|
'key'
|
|
],
|
|
[
|
|
'global binding for a worktree command',
|
|
{
|
|
commands: [{ id: 'open', title: 'Open', context: 'worktree', action: 'view.tasks' }],
|
|
keybindings: [{ command: 'open', key: 'Mod+K', when: 'global' }]
|
|
},
|
|
'command context'
|
|
],
|
|
[
|
|
'platform-equivalent duplicate chords',
|
|
{
|
|
commands: [
|
|
{ id: 'first', title: 'First', action: 'view.tasks' },
|
|
{ id: 'second', title: 'Second', action: 'sidebar.left.toggle' }
|
|
],
|
|
keybindings: [
|
|
{ command: 'first', key: 'Mod+K' },
|
|
{ command: 'second', key: 'Ctrl+K' }
|
|
]
|
|
},
|
|
'duplicate keybinding'
|
|
]
|
|
])('rejects %s', (_label, contributes, error) => {
|
|
expect(parsePluginManifest(manifest(contributes))).toMatchObject({
|
|
ok: false,
|
|
error: expect.stringContaining(error)
|
|
})
|
|
})
|
|
|
|
it.each([
|
|
['language pack', { languagePacks: [{ locale: 'en_US', path: 'locale.json' }] }],
|
|
// Shape-legal but ill-formed: the regex alone let these load with dates falling back to English.
|
|
['duplicate region', { languagePacks: [{ locale: 'en-US-US', path: 'locale.json' }] }],
|
|
['unknown subtag', { languagePacks: [{ locale: 'en-aaa', path: 'locale.json' }] }],
|
|
['language pack path', { languagePacks: [{ locale: 'pt-BR', path: '../outside.json' }] }],
|
|
['VM recipe', { vmRecipes: [{ path: '\\\\server\\recipe.json' }] }],
|
|
['agent profile', { agents: [{ path: 'agents/../profile.json' }] }]
|
|
])('rejects unsafe or malformed %s contributions', (_label, contributes) => {
|
|
expect(parsePluginManifest(manifest(contributes)).ok).toBe(false)
|
|
})
|
|
|
|
it.each(['ru', 'pt-BR', 'zh-Hans-CN', 'en-US'])('accepts the well-formed locale %s', (locale) => {
|
|
expect(
|
|
parsePluginManifest(manifest({ languagePacks: [{ locale, path: 'locale.json' }] }))
|
|
).toMatchObject({
|
|
ok: true
|
|
})
|
|
})
|
|
|
|
it('rejects duplicate ids, locales, paths, and bindings', () => {
|
|
const parsed = pluginManifestSchema.safeParse(
|
|
manifest({
|
|
languagePacks: [
|
|
{ locale: 'pt-BR', path: 'pt-br.json' },
|
|
{ locale: 'pt-br', path: 'other.json' }
|
|
],
|
|
commands: [{ id: 'open', title: 'Open', action: 'view.tasks' }],
|
|
keybindings: [
|
|
{ command: 'open', key: 'Mod+T' },
|
|
{ command: 'open', key: 'mod+t' }
|
|
]
|
|
})
|
|
)
|
|
|
|
expect(parsed.success).toBe(false)
|
|
if (!parsed.success) {
|
|
expect(parsed.error.issues.map((issue) => issue.message)).toEqual(
|
|
expect.arrayContaining([
|
|
'duplicate language pack locale: pt-br',
|
|
'duplicate keybinding: mod+t'
|
|
])
|
|
)
|
|
}
|
|
})
|
|
})
|