(input: {
readonly parse: NonNullable<DiscoverSkillsOptions['parse']>;
readonly byName: Map<string, SkillDefinition>;
readonly skillMdPath: string;
readonly skillDirName: string;
readonly root: SkillRoot;
readonly onDiscoveredSkill?: (skill: SkillDefinition) => void;
readonly warn: (message: string, cause?: unknown) => void;
readonly skip: (skill: SkippedSkill) => void;
readonly subSkillParentName?: string;
})
| 360 | } |
| 361 | |
| 362 | async function parseAndRegister(input: { |
| 363 | readonly parse: NonNullable<DiscoverSkillsOptions['parse']>; |
| 364 | readonly byName: Map<string, SkillDefinition>; |
| 365 | readonly skillMdPath: string; |
| 366 | readonly skillDirName: string; |
| 367 | readonly root: SkillRoot; |
| 368 | readonly onDiscoveredSkill?: (skill: SkillDefinition) => void; |
| 369 | readonly warn: (message: string, cause?: unknown) => void; |
| 370 | readonly skip: (skill: SkippedSkill) => void; |
| 371 | readonly subSkillParentName?: string; |
| 372 | }): Promise<SkillDefinition | undefined> { |
| 373 | try { |
| 374 | const parsed = await input.parse({ |
| 375 | skillMdPath: input.skillMdPath, |
| 376 | skillDirName: input.skillDirName, |
| 377 | source: input.root.source, |
| 378 | }); |
| 379 | const subSkillParentName = input.subSkillParentName; |
| 380 | const skill = |
| 381 | subSkillParentName !== undefined |
| 382 | ? { |
| 383 | ...parsed, |
| 384 | name: qualifySubSkillName(subSkillParentName, parsed.name), |
| 385 | metadata: { |
| 386 | ...parsed.metadata, |
| 387 | isSubSkill: true, |
| 388 | }, |
| 389 | } |
| 390 | : parsed; |
| 391 | const discovered = input.root.plugin === undefined ? skill : { |
| 392 | ...skill, |
| 393 | plugin: input.root.plugin, |
| 394 | }; |
| 395 | input.onDiscoveredSkill?.(discovered); |
| 396 | const key = normalizeSkillName(discovered.name); |
| 397 | if (!input.byName.has(key)) { |
| 398 | input.byName.set(key, discovered); |
| 399 | } |
| 400 | return discovered; |
| 401 | } catch (error) { |
| 402 | if (error instanceof UnsupportedSkillTypeError) { |
| 403 | input.skip({ |
| 404 | path: input.skillMdPath, |
| 405 | type: error.skillType, |
| 406 | reason: `unsupported skill type "${error.skillType}"`, |
| 407 | }); |
| 408 | } else if (error instanceof SkillParseError) { |
| 409 | input.warn(`Skipping invalid skill at ${input.skillMdPath}: ${error.message}`, error); |
| 410 | } else { |
| 411 | input.warn(`Skipping skill at ${input.skillMdPath} due to unexpected error`, error); |
| 412 | } |
| 413 | return undefined; |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | function qualifySubSkillName(parentName: string, skillName: string): string { |
| 418 | if (skillName === parentName || skillName.startsWith(`${parentName}.`)) return skillName; |
no test coverage detected