Skip to content

feat: Add {{fn:}}/{{ft:}}/{{attr:}} YAML language support - #23

Merged
oeisenberg merged 9 commits into
mainfrom
feat/yaml-fn-ft-attr-tags
Oct 29, 2026
Merged

oeisenberg merged 9 commits into
mainfrom
feat/yaml-fn-ft-attr-tags

Conversation

@oeisenberg

@oeisenberg oeisenberg commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds hover + Cmd/Ctrl-click go-to-definition + linting for Agent Studio prompt-template tags in step/topic YAML:
    • {{fn:X}} → global function (functions/X.py)
    • {{ft:X}} → flow-local function (flows/<flow>/functions/X.py)
    • {{attr:X}} → variant attribute (config/variant_attributes.yaml)
  • New lint rules: invalid-function-tag, invalid-attr-tag.
  • Fixes a pre-existing bug where the standalone adk-lint CLI bundle (dist/adk-lint.js) failed to compile — a dead import in pythonRules.ts was pulling the vscode module into its dependency graph, which doesn't exist outside the extension host. Pure filesystem resolution logic is now split into src/functionPathResolver.ts (no vscode dependency), shared by both the extension and the CLI.
  • Bumps @vscode/test-electron to 3.1.0 (2.5.2 can't launch VS Code 1.110+, which renamed its macOS executable from Electron to Code).
  • .vscode/launch.json: opens agent-deployments/agents by default, disables the marketplace-installed copy of this extension in the dev host, and defaults to noDebug (the Node inspector attach handshake was flaky and could leave the host permanently paused on line 1).
  • Adds CONTRIBUTING.md documenting all of the above.
image

Test plan

  • tsc --noEmit clean
  • eslint — 0 errors (only pre-existing warnings)
  • yarn test — 98/98 passing, including new tests for invalid-function-tag/invalid-attr-tag
  • Both webpack configs (extension.js, adk-lint.js) compile with 0 errors
  • node dist/adk-lint.js runs standalone without crashing
  • Verified hover/navigation/lint resolution against real project files (paratha, sourdough/clsliving-us)

🤖 Generated with Claude Code

@oeisenberg
oeisenberg requested a review from a team October 23, 2026 17:42
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

✅ Valid PR Title

Type Release Breaking
feat minor false

This PR will trigger a minor release when merged to main.

The version will be automatically determined by semantic-release based on the commit messages.

@oeisenberg oeisenberg changed the title Add {{fn:}}/{{ft:}}/{{attr:}} YAML language support feat: Add {{fn:}}/{{ft:}}/{{attr:}} YAML language support Oct 23, 2026
@oeisenberg
oeisenberg requested a balanced review from Copilot October 23, 2026 17:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

False lint errors and failures in tag ranges and attribute resolution affect the new YAML support.

5 open issues
What changed in this PR

Adds YAML prompt-tag language support to the Agent Studio extension and shares filesystem resolution with the standalone linter.

Changes:

  • Adds hover, navigation, and lint checks for {{fn:}}, {{ft:}}, and {{attr:}}.
  • Separates filesystem resolution from VS Code dependencies and refreshes the extension bundle.
  • Updates the VS Code test dependency, development launch configurations, and contributor documentation.
File Description
yarn.lock Locks the updated test dependency.
src/​yamlLanguageFeatures.ts Adds YAML tag hover and link providers.
src/​test/​linter.test.ts Tests function and attribute tag validation.
src/​pythonFunctionResolver.ts Delegates filesystem operations to the shared resolver.
src/​linter/​rules/​yamlRules.ts Adds unresolved-tag diagnostics.
src/​linter/​rules/​pythonRules.ts Removes the unused VS Code-dependent import.
src/​functionPathResolver.ts Introduces shared function and attribute resolution.
src/​extension.ts Registers and disposes YAML providers.
package.json Upgrades @vscode/test-electron.
node_modules/​@vscode/​test-electron/​vitest.config.ts Updates dependency test timeouts.
node_modules/​@vscode/​test-electron/​pipeline.yml Updates dependency CI to Node 22.
node_modules/​@vscode/​test-electron/​package.json Records dependency version and runtime requirements.
node_modules/​@vscode/​test-electron/​out/​util.js Updates executable and download metadata resolution.
node_modules/​@vscode/​test-electron/​out/​util.d.ts Updates utility declarations.
node_modules/​@vscode/​test-electron/​out/​runTest.js Updates test launching and output forwarding.
node_modules/​@vscode/​test-electron/​out/​runTest.d.ts Declares configurable output streams.
node_modules/​@vscode/​test-electron/​out/​request.js Refreshes generated import helpers.
node_modules/​@vscode/​test-electron/​out/​progress.js Reports downloaded commit identifiers.
node_modules/​@vscode/​test-electron/​out/​progress.d.ts Adds commit metadata to progress reports.
node_modules/​@vscode/​test-electron/​out/​download.test.mjs Updates dependency download tests.
node_modules/​@vscode/​test-electron/​out/​download.js Updates download error handling and metadata reporting.
node_modules/​@vscode/​test-electron/​.editorconfig Removes the dependency’s bundled editor configuration.
node_modules/​.yarn-integrity Refreshes dependency installation metadata.
dist/​extension.js Refreshes the packaged extension with language features.
CONTRIBUTING.md Documents local execution, debugging, and testing.
.vscode/​launch.json Adds development-host defaults and a debugging alternative.

Review effort: Balanced

Comment thread src/functionPathResolver.ts Resolved
Comment thread src/functionPathResolver.ts Resolved
Comment thread src/linter/rules/yamlRules.ts Resolved
Comment thread src/yamlLanguageFeatures.ts Resolved
Comment thread src/yamlLanguageFeatures.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread package.json Resolved
Comment thread src/functionPathResolver.ts Resolved
Comment thread src/functionPathResolver.ts Resolved
Comment thread src/functionPathResolver.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Valid attribute definitions can lose hover and navigation, and attribute links repeat synchronous configuration parsing for every reference.

2 open issues
4 resolved since last review

Review effort: Balanced

Comment thread src/functionPathResolver.ts Resolved
Comment thread src/yamlLanguageFeatures.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/functionPathResolver.ts Resolved
Comment thread src/functionPathResolver.ts Resolved
Comment thread src/functionPathResolver.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Outstanding comments concern vendored dependencies, binary view encoding, and outdated Node.js development prerequisites.

No open issues 🎉

3 resolved since last review

Review effort: Balanced

@oeisenberg
oeisenberg requested a review from dhandal09 October 23, 2026 20:31

@sophyphile sophyphile left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provided some comments. would fix the # one before merge since it's small, the other two can be follow-ups.

since we want to point customers at this and the repo is public, we should probably stop committing node_modules/ and dist/ too. they've been tracked by accident since the initial commit (the .gitignore already ignores both), and they aren't what ships, since the release job rebuilds from a clean install. but they're ~29k of the 30.5k lines in this pr, which buries the real changes.
not on you, we should remove them in a separate pr after this lands.

Comment thread src/linter/rules/yamlRules.ts Resolved
Comment thread src/linter/rules/yamlRules.ts Resolved
Comment thread src/functionPathResolver.ts Resolved
Comment thread .vscode/launch.json Resolved
oeisenberg and others added 6 commits October 26, 2026 23:36
…tr:}} YAML tags

Adds language support for Agent Studio prompt-template tags in step/topic YAML
files, mirroring the existing conv.functions/flow.functions Python support:
- {{fn:X}} -> global function (functions/X.py)
- {{ft:X}} -> flow-local function (flows/<flow>/functions/X.py)
- {{attr:X}} -> variant attribute (config/variant_attributes.yaml)

Each gets a hover tooltip, Cmd/Ctrl-click navigation, and a lint rule
(invalid-function-tag, invalid-attr-tag) flagging references that don't
resolve.

Also fixes a pre-existing bug where the standalone `adk-lint` CLI bundle
(dist/adk-lint.js) failed to compile, because a dead import in pythonRules.ts
pulled the `vscode` module into its dependency graph, which doesn't exist
outside the extension host. Pure filesystem resolution logic is now split
into src/functionPathResolver.ts (no vscode dependency), shared by both the
extension and the CLI.

Other changes:
- Bump @vscode/test-electron to 3.1.0 (2.5.2 can't launch VS Code 1.110+,
  which renamed its macOS executable from Electron to Code).
- .vscode/launch.json: open agent-deployments/agents by default, disable the
  marketplace-installed copy of this extension in the dev host, and default
  to noDebug (the Node inspector attach was flaky and could leave the host
  permanently paused on line 1 with nothing to resume it).
- Add CONTRIBUTING.md documenting all of the above.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- findVariantAttributesPath no longer requires a global functions/
  directory (was reusing findProjectRoot, which does); it now walks up
  independently looking for config/variant_attributes.yaml, so projects
  with only flow-scoped functions still get {{attr:}} resolution.
- resolveVariantAttributeLocation now locates a `name:` key anywhere
  within an attributes list entry (not just as the first key), and
  tolerates a trailing comment — both previously caused valid attributes
  to resolve for linting but silently return no hover/navigation.
- invalid-function-tag / invalid-attr-tag now skip full-line YAML
  comments, so commented-out references no longer produce diagnostics.
- Fixed name-range calculation in yamlLanguageFeatures.ts for both
  providers: it searched for the name text within the matched tag,
  which could match inside the tag's own prefix when the name shared
  characters with it (e.g. {{fn:n}}, {{attr:attr}}), producing a
  link/hover range over the prefix instead of the name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- build.yml: bump CI Node to 22, matching release.yml and the engines
  requirement of @vscode/test-electron 3.1.0 (>=22) — yarn's engine
  check would otherwise reject the install under Node 20.
- resolveVariantAttributeLocation:
  - allow a trailing comment on the `attributes:` section header
    (e.g. `attributes: # project attributes`)
  - skip full-line comments between entries instead of treating them
    as a dedent that ends the search
  - restrict name: matches to direct keys of the current entry's
    mapping (by tracking each entry's key indent), so literal "name:"
    text inside a sibling entry's block-scalar value can no longer be
    mistaken for a real attribute definition

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Handle two more valid variant_attributes.yaml forms that the block-
  style walker couldn't locate (though they parsed fine for lint
  purposes via js-yaml): a dash-only list entry (`-` alone, with its
  keys indented on following lines) and a flow-style inline sequence
  (`attributes: [{name: x, ...}]`), the latter via a best-effort loose
  fallback scan since it isn't block-style YAML.
- Replaced the per-reference resolveVariantAttributeLocation calls in
  YamlAttrLinkProvider with a single buildVariantAttributeIndex call
  per document: previously every {{attr:X}} occurrence independently
  re-walked the project directory, re-read, and re-parsed
  config/variant_attributes.yaml, repeating O(file size) work per tag.
  Now the index (name -> location) is built once and reused for every
  tag in the document. resolveVariantAttributeLocation is now a thin
  wrapper around the same index for the single-lookup hover case.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The hand-rolled line/indentation-based scanner for config/variant_attributes.yaml
kept accumulating edge cases across review rounds (comments, reordered keys,
dash-only entries, flow-style mappings, block-scalar content that happens to
contain "name:"-shaped text) because it was reimplementing YAML parsing by
hand. Replaced it with the `yaml` package (source-position aware), which
handles every valid form correctly by construction — block scalars are
opaque strings to a real parser, so literal text inside them can never be
mistaken for structure, and flow-style/dash-only entries parse the same as
any other valid YAML.

findVariantAttributeNames now just reads the keys of the same index, so
there's a single parse path (previously js-yaml for existence-checking and a
separate regex walk for position-finding, which could in principle diverge).

Adds the `yaml` dependency (zero transitive deps). Added 3 regression tests
for the specific forms called out in review: an inline flow-style mapping
inside a block sequence, a block-scalar value containing literal
dash-prefixed "name:" text, and a flow-style list where an earlier scalar
value contains the text of a later attribute's name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
prompt: |- blocks commonly use markdown headings (## ...), which the
linter's isFullLineComment check mistook for commented-out config,
silently skipping {{fn:}}/{{ft:}}/{{attr:}} validation on those lines.
Use the yaml package's parsed ranges to detect real block scalars and
only suppress the comment skip within them.

Also note in CONTRIBUTING.md that .vscode/launch.json assumes
agent-deployments is checked out as a sibling directory.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@oeisenberg
oeisenberg force-pushed the feat/yaml-fn-ft-attr-tags branch from 7bc4cb9 to 3327398 Compare October 26, 2026 14:41
@oeisenberg
oeisenberg requested review from Ruari-Phipps and sophyphile and a balanced review from Copilot October 26, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved linting and navigation defects affect comment handling, supported attribute names, and definition targeting.

3 open issues

Review effort: Balanced

Comment thread src/linter/rules/yamlRules.ts Resolved
Comment thread src/linter/rules/yamlRules.ts Resolved
Comment thread src/yamlLanguageFeatures.ts Resolved
oeisenberg and others added 2 commits October 29, 2026 00:09
ATTR_TAG_PATTERN used \w+, which silently skipped names like
site-name in linting, hover, and navigation, even though the
prompt renderer already accepts them via {{attr:([^}]+)}}.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…nces"

This reverts commit d4eccbc.

Attribute names can't contain hyphens: the ADK's
_validate_attribute_name (poly/resources/variant_attributes.py)
rejects any name that isn't a valid Python identifier on push, and
none of the 10,048 attribute names across agent-deployments have one.
The [^}]+ pattern d4eccbc copied from the prompt renderer governs the
flow viewer's badge styling, not name validation, so widening the
linter's pattern to match it doesn't catch any real hyphenated names
-- it just stops flagging config/variant_attributes.yaml ids that
haven't been translated on pull, which the ADK currently leaves as
raw UUIDs in VARIANT_ATTRIBUTES-<uuid> form instead of resolving to
the live attribute name. Catching those untranslated ids properly is
a separate follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@oeisenberg

Copy link
Copy Markdown
Contributor Author

Reverted d4eccbc in 0f94b27.

Attribute names can't contain hyphens — _validate_attribute_name in poly/resources/variant_attributes.py rejects anything that isn't a valid Python identifier on push, and none of the 10,048 attribute names in agent-deployments have one. The [^}]+ pattern was lifted from the prompt renderer's badge styling, not from validation, so widening the match doesn't catch any real hyphenated names — it just stops flagging untranslated VARIANT_ATTRIBUTES-<uuid> ids that the ADK leaves raw in variant_attributes.yaml/language_code on pull instead of resolving to the live name. Back to \w+; catching those untranslated ids properly is a separate follow-up.

@sophyphile sophyphile left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

dist/ is already gitignored and rebuilt by CI (yarn compile/package), so these shouldn't be committed.
@oeisenberg
oeisenberg merged commit f7bdedf into main Oct 29, 2026
2 checks passed
@oeisenberg
oeisenberg deleted the feat/yaml-fn-ft-attr-tags branch October 29, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants