Files
reverse-engineering-anything/scripts/lib/catalog-builders.mjs
T
morluto e53212655b refactor(contracts): derive the public tool catalog from one contract-group list (#10564)
* refactor(contracts): derive the public tool catalog from one contract-group list

toolContracts.ts and toolFamilies.ts each imported and listed the same
contract groups. toolContracts.ts now owns one ordered group object;
TOOL_CONTRACTS is its flattened values in the same catalog order, and
toolFamilies.ts reads TOOL_CONTRACT_GROUPS from it instead of re-importing
every group. The static catalog-source lint rule learns the
Object.values(groups).flat() composition so positional-contract enforcement
still discovers every group without executing modules.

* fix(lint): reject computed tool catalog groups
2026-11-15 04:07:17 +08:00

78 lines
2.6 KiB
JavaScript

import { names } from "./catalog-core.mjs";
/** Build tool-family counts and sorted tool-name lists. */
export const toolFamilyCatalog = (sources) => {
const families = sources.toolFamilies.TOOL_FAMILY_DEFINITIONS.map(
({ id, surface, contracts }) => ({
id,
surface,
count: contracts.length,
tools: names(contracts),
}),
);
const familyTotal = families.reduce(
(total, family) => total + family.count,
0,
);
if (
familyTotal !== sources.toolContracts.TOOL_CONTRACTS.length ||
familyTotal !==
sources.catalogIdentity.FULL_CATALOG_IDENTITY.counts.mcp_tools
)
throw new Error("Tool family inventory does not match TOOL_CONTRACTS");
return { total: familyTotal, families };
};
/** Derive provider capabilities from the same static declarations used by composition. */
export const providerCatalog = (sources) => {
const contractNames = new Set(
sources.toolContracts.TOOL_CONTRACTS.map(({ name }) => name),
);
const providers = new Map();
for (const declaration of Object.values(
sources.capabilityDeclarations.CAPABILITY_DECLARATIONS,
)) {
for (const { identity, operations } of declaration.providers) {
let provider = providers.get(identity.id);
if (provider === undefined) {
provider = { ...identity, capabilities: new Set() };
providers.set(identity.id, provider);
} else if (
provider.name !== identity.name ||
provider.version !== identity.version
) {
throw new TypeError(
`Provider ${identity.id} has conflicting source identities`,
);
}
let selectedOperations = operations;
if (!Array.isArray(operations)) {
const contracts =
sources.toolContracts.TOOL_CONTRACT_GROUPS[operations.group];
if (contracts === undefined)
throw new TypeError(
`Provider ${identity.id} declares an unknown contract group: ${operations.group}`,
);
selectedOperations = contracts.map(({ name }) => name);
}
for (const operation of selectedOperations) {
if (!contractNames.has(operation))
throw new TypeError(
`Provider ${identity.id} declares an unknown analyst operation: ${operation}`,
);
provider.capabilities.add(operation);
}
}
}
return [...providers.values()]
.map(({ id, name, version, capabilities }) => ({
id,
name,
version,
capabilities: [...capabilities].sort((left, right) =>
left.localeCompare(right),
),
}))
.sort((left, right) => left.id.localeCompare(right.id));
};