(params: {
targets: ToolTarget[];
global: boolean;
})
| 485 | // roots (paths are output-root-relative). Multi-output-root `--check` would |
| 486 | // need per-output-root keying; that is out of scope here. |
| 487 | function computeRootFileOwnership(params: { |
| 488 | targets: ToolTarget[]; |
| 489 | global: boolean; |
| 490 | }): Map<string, ToolTarget> { |
| 491 | const ownerByPath = new Map<string, ToolTarget>(); |
| 492 | const register = ( |
| 493 | relativeDirPath: string, |
| 494 | relativeFilePath: string, |
| 495 | target: ToolTarget, |
| 496 | ): void => { |
| 497 | ownerByPath.set(toPosixPath(join(relativeDirPath, relativeFilePath)), target); |
| 498 | }; |
| 499 | for (const target of params.targets) { |
| 500 | const factory = RulesProcessor.getFactory(target); |
| 501 | if (!factory) continue; |
| 502 | const paths = factory.class.getSettablePaths({ global: params.global }); |
| 503 | if ("root" in paths && paths.root) { |
| 504 | register(paths.root.relativeDirPath, paths.root.relativeFilePath, target); |
| 505 | } |
| 506 | // Secondary/fallback root locations a target recognizes are attributed to |
| 507 | // it as well, so a shared collision at one of those paths is skipped for |
| 508 | // non-owning targets. |
| 509 | if ("alternativeRoots" in paths && paths.alternativeRoots) { |
| 510 | for (const alt of paths.alternativeRoots) { |
| 511 | register(alt.relativeDirPath, alt.relativeFilePath, target); |
| 512 | } |
| 513 | } |
| 514 | // Some targets (e.g. rovodev) mirror their primary root — which lives in a |
| 515 | // subdirectory — to a project-root `./AGENTS.md` at generation time (project |
| 516 | // scope only). That mirror is exactly the shared-collision path, so it must |
| 517 | // be attributed to the target too, otherwise ownership/skip decisions invert. |
| 518 | // (For rovodev this overlaps its `alternativeRoots` today; the explicit |
| 519 | // block keeps ownership correct even if that alt root is ever removed.) |
| 520 | if (!params.global && factory.meta.mirrorsRootToAgentsMd) { |
| 521 | register(".", AGENTSMD_RULE_FILE_NAME, target); |
| 522 | } |
| 523 | } |
| 524 | return ownerByPath; |
| 525 | } |
| 526 | |
| 527 | async function generateRulesCore(params: { |
| 528 | config: Config; |
no test coverage detected
searching dependent graphs…