Files
brysonerandall-a11y f83bd316da feat(cli): add x-path-template-env-vars spec extension (#1401)
* feat(cli): add x-path-template-env-vars spec extension

Generic, map-shaped successor to x-tenant-env-var. Each entry binds a
path placeholder to an env-var override (env field, parallel to the
tenant flow) or a build-time literal substitution (default field, which
bakes the value into operation paths at generation time and drops the
matching path parameter). When both are set, default wins.

Adds APISpec.EndpointPathParamDefaults to carry the generation-time
substitutions, populated from the extension or set directly in internal
YAML. Legacy x-tenant-env-var path is preserved and coexists with the
new extension.

Documents the new extension in docs/SPEC-EXTENSIONS.md and covers it
with TestParsePathTemplateEnvVarsExtension (env-only, default-only,
both-set-default-wins, coexists-with-tenant, absent, whitespace-only).
Specs without the extension keep byte-identical output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(cli): tighten x-path-template-env-vars edge cases

Address Greptile review feedback on PR #1401:

- applyPathParamDefaults now consults isPathSubstitutionParam before
  dropping an endpoint param. A query or body param that shares its
  name with a substituted path placeholder is no longer silently
  removed from generated commands.
- parseEndpointTemplateExtensions now scrubs EndpointTemplateVars and
  EndpointTemplateEnvOverrides of any key that x-path-template-env-vars
  declares a default for. When x-tenant-env-var and the new extension
  both target the same placeholder (e.g. tenant), default wins fully
  instead of leaving dead runtime config / URL-substitution code
  behind for a placeholder that no longer appears in any path.
- docs/SPEC-EXTENSIONS.md splits the contradictory single example
  (Gmail title + Atlassian entry) into two coherent examples: a
  runtime-override example and a build-time default example.

Tests cover both new behaviors. go test ./..., go vet ./..., and
scripts/golden.sh verify (18/18) all pass locally.

* feat(cli): emit tools-manifest.json on every generate run

Before, only mcp-sync and publish wrote tools-manifest.json. A
fresh printing-press generate produced cmd/, internal/mcp/, and
the rest of the Go runtime surface but left tools-manifest.json
untouched. Any pre-existing manifest carried over from a prior
generation under a different spec / parser silently misrepresented
the current MCP tool set until the user remembered to run mcp-sync.

This bit the x-path-template-env-vars adoption flow on Gmail:
generate baked /users/me/... into every path in cmd/ and tools.go,
but the stale tools-manifest still advertised /users/{userId}/...
with a userId path parameter. Agents reading the manifest got a
different surface than the runtime served.

Move WriteToolsManifest into runGenerateProject right after
gen.Generate() so a single generate run produces a consistent CLI
end to end. Non-blocking on error: warn-and-continue matches the
posture publish.go already takes for the same call.

Side effect on the golden suite: generate-golden-api's scorecard
can now evaluate the mcp_description_quality dimension (3/10)
because the manifest exists. Dimension moves from
unscored_dimensions into scored, total drops from 82 to 80 — a
real signal that was previously hidden, not a regression.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Trevin Chow <trevin@trevinchow.com>
2026-05-22 07:33:27 +00:00
..