Make install + surface read the registry's derived profileMembership/ capabilityClusters so a capability's tier drives what installs + surfaces. resolveProfile (when given the registry) unions capability skills for the profiles its tier implies before the requires: closure; resolveSurface merges capabilityClusters into the cluster map. bin/install.js, /gsd:surface, and the capability-state resolver all thread the registry. Shipped as a proven no-op: the UI capability is reconciled to tier:full (its skills were full-only in the hand-authored profiles), so it contributes only to the full profile (already the '*' sentinel) and core/standard are unchanged. Equivalence tests prove resolveProfile/resolveSurface/listSurface/staging/ capability-state are identical with vs without the registry; the core-alias staging path is verified equivalent (empty manifest → raw PROFILES.core). Closes #949 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -330,6 +330,14 @@ function cmdCapabilityState(
|
||||
}
|
||||
}
|
||||
|
||||
// ── Load registry (ADR-857 phase 4c) ────────────────────────────────────────
|
||||
// Load BEFORE resolveProfile and resolveSurface so both calls receive the
|
||||
// registry and capability-contributed skills are reflected in installed/surfaced.
|
||||
// No-op today (UI capability is tier:full → only adds to 'full', which returns
|
||||
// '*' regardless) but cutover-ready for future tier:core/standard capabilities.
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const registry = require('./capability-registry.cjs') as Record<string, unknown>;
|
||||
|
||||
// ── Resolve installed skills (from install profile) ──────────────────────────
|
||||
// Distinguish "no profile marker → default full" (legitimate) from a thrown
|
||||
// error (surface as a warning and degrade gracefully — do NOT silently report
|
||||
@@ -342,6 +350,7 @@ function cmdCapabilityState(
|
||||
const resolvedInstall = resolveProfile({
|
||||
modes: profileName.split(',').map((s: string) => s.trim()),
|
||||
manifest,
|
||||
registry,
|
||||
});
|
||||
installedSkills = resolvedInstall.skills;
|
||||
} catch (err: unknown) {
|
||||
@@ -358,7 +367,7 @@ function cmdCapabilityState(
|
||||
try {
|
||||
const commandsGsdDir = _resolveCommandsGsdDir();
|
||||
const manifest = loadSkillsManifest(commandsGsdDir);
|
||||
const surfaceResult = resolveSurface(resolvedConfigDir, manifest);
|
||||
const surfaceResult = resolveSurface(resolvedConfigDir, manifest, undefined, registry);
|
||||
// resolveSurface returns { name, skills: Set<string>, agents: Set<string> }
|
||||
// (always a concrete Set — full profile is materialized)
|
||||
surfacedSkills = surfaceResult.skills instanceof Set
|
||||
@@ -380,9 +389,7 @@ function cmdCapabilityState(
|
||||
config = {};
|
||||
}
|
||||
|
||||
// ── Load registry and resolve state ─────────────────────────────────────────
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const registry = require('./capability-registry.cjs') as Record<string, unknown>;
|
||||
// ── Resolve state ────────────────────────────────────────────────────────────
|
||||
|
||||
const result = resolveCapabilityState({
|
||||
registry,
|
||||
|
||||
Reference in New Issue
Block a user