fix: address Copilot review round 3 — conjunctive keywords, unflattenable allOf, branch inference

- rootUnion: a branch restating a constraint the root states differently is
  declined (keywords at one level are conjunctive and no intersection is
  computed here), while annotations may disagree freely. An `allOf` with a
  member it cannot fold in — JSON Schema's boolean form, or a $ref whose
  constraints are unknown rather than absent — is left intact instead of
  merged-and-stripped, which would turn an unsatisfiable schema into a
  fillable form.
- rootUnion: `declaresAnyFields` counts the raw composition members, so
  `hasInputFields` reports fields for a union the resolver declines and an
  App tool is never auto-invoked with empty arguments.
- SchemaForm: the picker opens on the branch the supplied values identify
  (an App deep link overlays its args, so they can name another branch), and
  a branch switch no longer carries a value the outgoing branch declared —
  the branches may type the same name differently.
- TUI: a base property some branch redeclares is offered in EVERY branch's
  section under that branch's inherited or specialized declaration, so a
  branch that does not redeclare it can still supply a required root
  argument.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-26 02:01:44 -04:00
commit 1a271e4931

View file

@ -118,6 +118,22 @@ describe("hasInputFields with root composition (#2123)", () => {
).toBe(true);
});
it("sees fields on a union the form declines to flatten", () => {
// Otherwise an App tool with such a schema is treated as input-free and
// invoked immediately with `{}`.
expect(
hasInputFields(
tool({
type: "object",
anyOf: [
{ type: "object", properties: { a: { type: "string" } } },
{ $ref: "#/$defs/Other" },
],
}),
),
).toBe(true);
});
it("still reports no fields for a bare object schema", () => {
expect(hasInputFields(tool({ type: "object" }))).toBe(false);
});