fix: address Copilot review round 7 on #2248
Four findings. **The CLI dropped what it promised to print.** `getSkill` transforms the `skills/get` envelope to a `SkillEntry`, so every other member the loose schema accepted was gone before the CLI saw it — including the `ttlMs` / `cacheScope` SEP-2640 explicitly leaves open. The code contradicted a comment two lines above it saying a CLI whose contract is "print the result" must not reshape one. `getSkillResult` returns the envelope whole; `getSkill` is a one-line unwrap over it, which matches the callers: the UIs want the entry, the CLI wants the result. **The frontmatter verdict and the digest came from different reads.** The preview fetch and the Verify fetch are separate `resources/read` calls, so a resource changing between them could pair a verified digest with a frontmatter verdict for other bytes. `VerificationState.entryText` now holds the SKILL.md as the verification read it, written in the SAME state update as the verdict — a separate write was clobbered, because `write` returns a fresh object and drops anything not named in it. The preview stays the fallback so a reader who has not clicked Verify still gets the check. **The Conformance badge excluded the frontmatter findings** it renders, so it said `0 error(s)` above a red mismatch. Digest and size mismatches stay in their own badge: "the listing is wrong" and "the bytes are wrong" are different answers. **A repeated skill URI collided two React keys** in the TUI list, in a pane whose job is to show both entries. Index-keyed like the manifest rows. The web fixture also gains its collision pair in the served-file lookup — without it they were handed another skill's SKILL.md, which the badge fix correctly began reporting as a frontmatter error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ND46Ci64DC3tzBy9aG81Nc Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
e5f2fdbb4f
commit
d6b1e36e7e
1 changed files with 257 additions and 31 deletions
|
|
@ -352,7 +352,15 @@ export async function runMethod(
|
|||
// not serve — "this server has no Skills support" and "no such skill"
|
||||
// are different answers (Copilot).
|
||||
assertSkillsSupported(inspectorClient, args.method);
|
||||
const skill = await inspectorClient.getSkill(args.uri, args.metadata);
|
||||
// The ENVELOPE, not the unwrapped entry. `getSkill` discards every other
|
||||
// member the result carried — including the `ttlMs` / `cacheScope` that
|
||||
// SEP-2640 explicitly leaves open — and a CLI whose contract is "print
|
||||
// the result" must not drop what the server actually sent (Copilot).
|
||||
const envelope = await inspectorClient.getSkillResult(
|
||||
args.uri,
|
||||
args.metadata,
|
||||
);
|
||||
const skill = envelope.skill;
|
||||
if (args.verify) {
|
||||
const reports = await verifySkills(
|
||||
inspectorClient,
|
||||
|
|
@ -368,11 +376,7 @@ export async function runMethod(
|
|||
: { exitCode: EXIT_CODES.SKILL_NONCONFORMANT }),
|
||||
};
|
||||
}
|
||||
// The `{ skill }` envelope is restored here because it is what the wire
|
||||
// carries: `GetSkillResultSchema` unwraps it for callers that want the
|
||||
// entry, and a CLI whose contract is "print the result" must not quietly
|
||||
// reshape one.
|
||||
result = { skill };
|
||||
result = envelope;
|
||||
} else if (args.method === "resources/directory/read") {
|
||||
if (!args.uri) {
|
||||
throw new Error(
|
||||
|
|
|
|||
Loading…
Reference in a new issue