fix: address Copilot review on the _meta widening
- Widen the three `_meta` annotations the bulk pass missed, all of them
return types rather than identifier declarations: `mergeMeta`,
`aggregateListParams`, and the `tools/call` params object. The second was
unsound in a way callers could see — it advertised
`{ _meta: Record<string, string> }` while the runtime carried nested JSON.
- `normalizeStoredMetadata`: keep an explicit `null` from a legacy pair
instead of folding it into `""` (only a missing `value` defaults now), and
store through `Object.defineProperty` so a legacy `__proto__` key becomes an
own property rather than hitting the prototype setter.
- Drop the unjustified `as unknown as` from the migration test; the legacy
fixture is untyped and cast once where it crosses into the typed parser.
- The TUI settings test asserted only that the app mounted, so it could not
have caught a pair array being forwarded as numeric `_meta` keys. The fake
client now captures its constructor options and the test asserts the nested
object arrives intact.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177mPHAdECD18nLLCTwR5rh
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
04b5e70a53
commit
0f628a8174
2 changed files with 67 additions and 16 deletions
|
|
@ -1037,7 +1037,7 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
*/
|
||||
private mergeMeta(
|
||||
callMetadata?: RequestMetadata,
|
||||
): Record<string, string> | undefined {
|
||||
): RequestMetadata | undefined {
|
||||
const defaults = this.defaultMetadata;
|
||||
// Modern-era per-request log level (#1629): stamp the opt-in `_meta` key on
|
||||
// every request so the server emits `notifications/message` on this
|
||||
|
|
@ -1132,7 +1132,7 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
*/
|
||||
private aggregateListParams(
|
||||
metadata?: RequestMetadata,
|
||||
): { _meta: Record<string, string> } | undefined {
|
||||
): { _meta: RequestMetadata } | undefined {
|
||||
const effectiveMeta = this.mergeMeta(metadata);
|
||||
return effectiveMeta ? { _meta: effectiveMeta } : undefined;
|
||||
}
|
||||
|
|
@ -4279,7 +4279,7 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
const callParams: {
|
||||
name: string;
|
||||
arguments: Record<string, JsonValue>;
|
||||
_meta?: Record<string, string>;
|
||||
_meta?: RequestMetadata;
|
||||
task?: { ttl: number };
|
||||
} = {
|
||||
name: tool.name,
|
||||
|
|
|
|||
|
|
@ -234,7 +234,19 @@ export function normalizeStoredMetadata(
|
|||
}
|
||||
const { key, value } = entry as { key: string; value?: JsonValue };
|
||||
if (key.trim() === "") continue;
|
||||
out[key] = value ?? "";
|
||||
// `??`, not `||`: `null` is a legal `_meta` value and must survive the
|
||||
// migration as `null`. Only a genuinely absent `value` becomes `""`.
|
||||
//
|
||||
// `defineProperty` rather than `out[key] = …` because a legacy key of
|
||||
// `__proto__` would otherwise hit the prototype setter — silently
|
||||
// dropping the entry (or, for an object value, mutating the prototype)
|
||||
// instead of storing an own property under that name.
|
||||
Object.defineProperty(out, key, {
|
||||
value: value === undefined ? "" : value,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue