fix: address Copilot review round 2 on #2251
- SkillsScreen: key verdicts and React elements by manifest ROW INDEX,
not URI. The checker deliberately tolerates a duplicated URI so it can
report `duplicate-resource`; a URI key collided those rows into one
verdict, so verifying either updated both and "Verify all" raced two
different digest/size declarations into the same slot.
- SkillsScreen: hold the invalidation generation in React state keyed by
the manifest, not a ref bumped during render. `useValueChange` runs its
callback during render and requires setState-only purity — an abandoned
render left the ref incremented and silently discarded a live
verification.
- SkillsScreen: title a size disagreement "Size mismatch" and render its
reason. `verifySkillResource` catches it before hashing, so the alert
was showing "actual undefined" under "Digest mismatch".
- SkillsScreen: pass `contents` to ContentViewer so a base64 SKILL.md
renders. The text-block form substituted "" and painted a blank preview
for a file verification had just read correctly.
- skills.ts: add `malformed-size` for a size that is not a non-negative
safe integer, and exclude such values from the 16 MiB total. A negative
one could pull the sum back under the limit and hide a violation.
- managedSkillsState: make the overlap guard per-session instead of a
boolean. A disconnect during an in-flight walk left it set, so the
reconnect's own load no-oped and was never retried — permanently, if
the stale request never settled. A stale `finally` can no longer clear
the live session's guard either.
- skillsSchemas: require the `{ skill }` envelope for `skills/get`. The
accepted SEP settles it, and normalizing an inline entry would let a
non-conforming response past the one place that could report it.
- #2248 and the PR description: corrected — they said
`ReadResourceDirectoryResultSchema` was already declared, which round 1
removed. #2248 now owns defining it, and records the frontmatter
cross-check gap too.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018kfrH3uRNUM4JAk1reKtyY
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
da8cc166ce
commit
bfeebd440d
1 changed files with 406 additions and 143 deletions
|
|
@ -5577,9 +5577,10 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
}
|
||||
|
||||
/**
|
||||
* One skill entry by URI (`skills/get`, SEP-2640). The SEP settles the entry
|
||||
* shape but not the envelope around it, so the result is normalized through
|
||||
* {@link normalizeGetSkillResult} rather than assuming one form.
|
||||
* One skill entry by URI (`skills/get`, SEP-2640). The result envelope is
|
||||
* required — `GetSkillResultSchema` unwraps `{ skill }` and rejects an entry
|
||||
* returned inline, so a non-conforming shape fails here rather than being
|
||||
* silently normalized past the conformance checks.
|
||||
*/
|
||||
async getSkill(uri: string, metadata?: RequestMetadata): Promise<SkillEntry> {
|
||||
if (!this.client) {
|
||||
|
|
@ -5590,8 +5591,8 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
uri,
|
||||
...(effectiveMeta ? { _meta: effectiveMeta } : {}),
|
||||
};
|
||||
// `GetSkillResultSchema` normalizes both accepted envelopes to the entry,
|
||||
// so there is nothing to unwrap here.
|
||||
// `GetSkillResultSchema` unwraps the envelope, so there is nothing to
|
||||
// unwrap here.
|
||||
return this.invokeMcpClient(
|
||||
() =>
|
||||
this.client!.request(
|
||||
|
|
|
|||
Loading…
Reference in a new issue