feat(#1173): wire the 8 agent converters into the descriptor-driven install path
The descriptor-driven install path (resolveRuntimeArtifactLayout) installed no agents for copilot/antigravity/cursor/windsurf/augment/trae/codebuddy/cline — their per-runtime agent conversion ran only via the legacy bin/install.js loop. This wires each runtime's agent converter into the descriptor so the new path applies per-runtime conversion (follow-up to #1099; ADR-1235 cutover). - capabilities/<rt>/capability.json: declare an `agents` kind with the runtime's converter (global+local; cline global-only). Regenerated capability-registry.cjs. - convertedAgentsKind threads install scope -> isGlobal so the scope-aware copilot/antigravity converters choose global vs workspace-relative paths; the six single-arg converters ignore the extra arg. stageAgentsForRuntimeWithConverter passes isGlobal to the converter. - Tests: feat-1173 gains a real-registry block asserting each runtime's descriptor applies the correct converter (== conv(src, isGlobal), != raw copy) with scope threading (fails-first on pristine next). The ADR-857 equivalence golden + per-runtime kind-count assertions now include the agents kind, each annotated as an intentional #1173 change. Scope: this wires the per-runtime CONVERTER. The remaining byte-parity behaviors of the legacy loop (copilot `.agent.md` rename, cross-cutting path/attribution rewrites, config-reading) stay with the legacy loop -- which runs after installRuntimeArtifacts and is authoritative for the real install -- and are tracked by ADR-1235's later cutover steps. No user-facing change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -548,12 +548,16 @@ function stageSkillsForRuntimeAsSkills(
|
||||
*
|
||||
* @param srcAgentsDir source agents directory (e.g. agents/)
|
||||
* @param resolvedProfile profile filter from resolveProfile()
|
||||
* @param converter (content: string) → string pure per-file converter
|
||||
* @param converter (content: string, isGlobal?: boolean) → string per-file
|
||||
* converter; scope-aware converters (copilot/antigravity)
|
||||
* read isGlobal, single-arg converters ignore it (#1173)
|
||||
* @param isGlobal install scope passed through to the converter
|
||||
*/
|
||||
function stageAgentsForRuntimeWithConverter(
|
||||
srcAgentsDir: string,
|
||||
resolvedProfile: ResolvedProfile,
|
||||
converter: (content: string) => string,
|
||||
converter: (content: string, isGlobal?: boolean) => string,
|
||||
isGlobal = false,
|
||||
): string {
|
||||
if (!fs.existsSync(srcAgentsDir)) return srcAgentsDir;
|
||||
|
||||
@@ -571,7 +575,7 @@ function stageAgentsForRuntimeWithConverter(
|
||||
}
|
||||
}
|
||||
const content = fs.readFileSync(path.join(srcAgentsDir, entry.name), 'utf8');
|
||||
const converted = converter(content);
|
||||
const converted = converter(content, isGlobal);
|
||||
fs.writeFileSync(path.join(stageDir, entry.name), converted, 'utf8');
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -175,6 +175,16 @@ function agentsKind(destSubpath: string, prefix: string, configDir: string): Art
|
||||
* Agent filenames are preserved verbatim (the prefix is already embedded in the
|
||||
* agent stem — e.g. `gsd-planner.md`).
|
||||
*
|
||||
* #1173 SCOPE: this wires the per-runtime agent CONVERTER (frontmatter/body +
|
||||
* isGlobal scope) into the descriptor path. The remaining byte-for-byte parity
|
||||
* behaviors of the legacy `bin/install.js` agent loop — Copilot's `.agent.md`
|
||||
* filename rename, the cross-cutting path-prefix rewrite + attribution, and the
|
||||
* config-reading steps (claude effort, opencode model override) — are NOT applied
|
||||
* here yet; they are tracked by the ADR-1235 cutover (later steps) and remain
|
||||
* provided by the legacy loop, which runs after `installRuntimeArtifacts` and is
|
||||
* authoritative for the real install. So this kind is correct for converter
|
||||
* coverage but not yet a full standalone replacement for these runtimes.
|
||||
*
|
||||
* Mirrors the `convertedCommandsKind` pattern (#785).
|
||||
*
|
||||
* @param destSubpath destination subpath within configDir (e.g. 'agents')
|
||||
@@ -187,14 +197,24 @@ function convertedAgentsKind(
|
||||
prefix: string,
|
||||
converterName: string,
|
||||
configDir: string,
|
||||
scope: 'local' | 'global' = 'global',
|
||||
): ArtifactKind {
|
||||
return {
|
||||
kind: 'agents',
|
||||
destSubpath,
|
||||
prefix,
|
||||
stage: (resolved) => {
|
||||
const converter = conversionExports[converterName] as (content: string) => string;
|
||||
return stageAgentsForRuntimeWithConverter(findAgentsSourceRoot(configDir), resolved, converter);
|
||||
// isGlobal is threaded so scope-aware agent converters (copilot, antigravity)
|
||||
// choose global-home vs workspace-relative paths; converters that only take
|
||||
// (content) ignore the extra positional arg. Mirrors skillsKind's scope
|
||||
// threading (#1173).
|
||||
const converter = conversionExports[converterName] as (content: string, isGlobal?: boolean) => string;
|
||||
return stageAgentsForRuntimeWithConverter(
|
||||
findAgentsSourceRoot(configDir),
|
||||
resolved,
|
||||
converter,
|
||||
scope === 'global',
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -411,7 +431,7 @@ function dispatchKindEntry(entry: ArtifactKindDescriptor, runtime: string, confi
|
||||
if (converter == null) {
|
||||
return agentsKind(destSubpath, prefix, configDir);
|
||||
}
|
||||
return convertedAgentsKind(destSubpath, prefix, converter, configDir);
|
||||
return convertedAgentsKind(destSubpath, prefix, converter, configDir, scope);
|
||||
|
||||
case 'skills':
|
||||
if (converter == null) {
|
||||
|
||||
Reference in New Issue
Block a user