{"id":51079020,"url":"https://github.com/home-operations/yayamlls","last_synced_at":"2026-06-23T16:32:46.208Z","repository":{"id":359666307,"uuid":"1247030866","full_name":"home-operations/yayamlls","owner":"home-operations","description":"YAML language server in Go. Schema-driven diagnostics, completion, hover; pluggable rendering for Flux HelmRelease and Kustomization via flate.","archived":false,"fork":false,"pushed_at":"2026-06-21T18:58:38.000Z","size":718,"stargazers_count":17,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-21T20:13:41.243Z","etag":null,"topics":["0ver","flux","golang","json-schema","kubernetes","language-server","lsp","yaml"],"latest_commit_sha":null,"homepage":"https://github.com/home-operations/yamlls","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/home-operations.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-22T20:32:33.000Z","updated_at":"2026-06-21T18:49:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/home-operations/yayamlls","commit_stats":null,"previous_names":["home-operations/yamlls","home-operations/yayamlls"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/home-operations/yayamlls","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/home-operations%2Fyayamlls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/home-operations%2Fyayamlls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/home-operations%2Fyayamlls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/home-operations%2Fyayamlls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/home-operations","download_url":"https://codeload.github.com/home-operations/yayamlls/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/home-operations%2Fyayamlls/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34698687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-23T02:00:07.161Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["0ver","flux","golang","json-schema","kubernetes","language-server","lsp","yaml"],"created_at":"2026-06-23T16:32:45.582Z","updated_at":"2026-06-23T16:32:46.201Z","avatar_url":"https://github.com/home-operations.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# yayamlls\n\n**Y**et **A**nother **YAML** **L**anguage **S**erver in Go. Schema-driven diagnostics, completion, and\nhover; pluggable rendering for Flux `HelmRelease` and `Kustomization`\nsources via [home-operations/flate][flate].\n\nPer-document schema resolution, highest priority first:\n\n1. in-file modeline (`# yaml-language-server: $schema=\u003curl\u003e`)\n2. workspace `schemas:` glob in `.yayamlls.yaml`\n3. JSON Schema Store catalog (filename match)\n4. Kubernetes `apiVersion`+`kind` → `kubernetes.schemaUrl` template\n\nMulti-doc files validate each document against its own schema. The\ndefault `kubernetes.schemaUrl` is\n`https://k8s-schemas.home-operations.com/{groupSeg}{kindLower}_{versionLower}.json`;\noverride in `.yayamlls.yaml` to point elsewhere. 404s are silently skipped.\n\nKubernetes support — apiVersion+kind detection, Flux rendering, and code\nlenses — is on by default. Disable it to run as a generic YAML language server:\n\n```yaml\nkubernetes:\n    enabled: false\n```\n\n## vs. redhat/yaml-language-server\n\n|                                                | yayamlls                                       | redhat/yaml-language-server                                 |\n| ---------------------------------------------- | ---------------------------------------------- | ----------------------------------------------------------- |\n| Runtime                                        | static Go binary                               | Node.js ≥ 12                                                |\n| Diagnostics, completion, hover                 | yes                                            | yes                                                         |\n| Symbols, folding, links, code actions          | yes                                            | yes                                                         |\n| Code lens                                      | rendered output, diff                          | none                                                        |\n| Kubernetes auto-detect                         | URL template from apiVersion+kind (toggleable) | `yaml.kubernetesCRDStore` ([datreeio/CRDs-catalog][datree]) |\n| Workspace config file                          | `.yayamlls.yaml`                               | editor settings only                                        |\n| Flux `HelmRelease` / `Kustomization` rendering | via [flate][flate]                             | no                                                          |\n| Pluggable renderers (`kustomize`, `helm`, …)   | config-declared subprocess                     | no                                                          |\n| Formatting                                     | no                                             | yes (Prettier)                                              |\n| Custom YAML tags (`!Ref`, etc.)                | passthrough (skip validation)                  | yes                                                         |\n| Diagnostic suppression comments                | yes (`# yayamlls-disable*`)                    | yes                                                         |\n| JSON Schema drafts                             | 04, 06, 07, 2019-09, 2020-12                   | 04, 07, 2019-09, 2020-12                                    |\n\n[datree]: https://github.com/datreeio/CRDs-catalog\n\n## Install\n\nHomebrew:\n\n```sh\nbrew install home-operations/tap/yayamlls\n```\n\nGo:\n\n```sh\ngo install github.com/home-operations/yayamlls/cmd/yayamlls@latest\n```\n\nPrebuilt binaries for linux/darwin/windows (amd64+arm64) are attached to\neach [GitHub release](https://github.com/home-operations/yayamlls/releases).\n\nFlux rendering is built in via [flate][flate]; no separate install is needed.\n\n## Command line\n\n`yayamlls validate` (alias `lint`) validates files for CI or ad-hoc checks,\nresolving schemas exactly as the editor does. Pass files or directories\n(directories are walked for `*.yaml`/`*.yml`):\n\n```sh\nyayamlls validate kubernetes/                 # whole tree\nyayamlls validate app/helmrelease.yaml ks.yaml\n```\n\nDiagnostics print ruff-style, `path:line:col: source message`, and the exit\ncode is `1` if any error was reported, `2` on a usage/IO error, else `0`.\n`--root \u003cdir\u003e` pins the workspace root for `.yayamlls.yaml` (default:\nauto-detect).\n\nAdd `--render` to also render Flux `HelmRelease`/`Kustomization` documents via\n[flate][flate] and validate the rendered manifests — the apply-time check, not\njust the source files:\n\n```sh\nyayamlls validate --render kubernetes/\n```\n\nRendering shells out to git/helm, so it is opt-in and slower than raw\nvalidation; the render tree is built once per run and reused across documents,\nso validating a whole directory in one invocation is far cheaper than\nfile-by-file. A render that can't resolve a document (e.g. a component base\ntemplate with unsubstituted `${vars}`) is reported as a warning and does not\nfail the run; only schema violations in rendered output do.\n\n## Editor setup\n\n`yayamlls` speaks LSP 3.16 over stdio. Put the binary on `$PATH` or pass\nan absolute path.\n\nPackaged extensions for **VS Code** and **Zed** live in [`editors/`](editors);\nthey download the matching `yayamlls` release binary automatically.\nThe snippets below are for editors with built-in LSP support.\n\n### Neovim\n\nUse the built-in `vim.lsp.config`/`vim.lsp.enable` API (0.11+):\n\n```lua\nvim.lsp.config(\"yayamlls\", {\n  cmd = { \"yayamlls\" },\n  filetypes = { \"yaml\" },\n  root_markers = { \".yayamlls.yaml\", \".git\" },\n})\n\nvim.lsp.enable(\"yayamlls\")\n```\n\nWith no marker found the server still attaches in single-file mode.\n\n### VSCode\n\nUse the extension in [`editors/vscode`](editors/vscode); it downloads the\n`yayamlls` binary on first activation, and exposes `yayamlls.*` settings. To build and run it locally, press \u003ckbd\u003eF5\u003c/kbd\u003e\nfrom that directory; to package a `.vsix`, run `vsce package`. See its\n[README](editors/vscode/README.md) for settings and publishing.\n\n### Helix\n\n```toml\n# ~/.config/helix/languages.toml\n[language-server.yayamlls]\ncommand = \"yayamlls\"\n\n[[language]]\nname = \"yaml\"\nlanguage-servers = [\"yayamlls\"]\n```\n\n### Zed\n\nUse the extension in [`editors/zed`](editors/zed); it registers `yayamlls` as a\nlanguage server for the YAML language and downloads the binary for you (install\nit via **zed: install dev extension**). Since Zed bundles its own\n`yaml-language-server`, make `yayamlls` the only one in\n`~/.config/zed/settings.json`:\n\n```jsonc\n{\n    \"languages\": {\n        \"YAML\": { \"language_servers\": [\"yayamlls\", \"!yaml-language-server\"] },\n    },\n}\n```\n\nWithout the extension, Zed's `lsp` key only accepts known language-server\nidentifiers (`yayamlls` as a top-level key triggers `Property yayamlls is not\nallowed`), so the settings-only alternative is to override the bundled\n`yaml-language-server` binary:\n\n```jsonc\n// ~/.config/zed/settings.json\n{\n    \"lsp\": {\n        \"yaml-language-server\": {\n            \"binary\": {\n                \"ignore_system_version\": true,\n                \"path\": \"yayamlls\",\n            },\n            \"initialization_options\": {\n                \"catalog\": true,\n            },\n        },\n    },\n}\n```\n\n### Gram\n\n[Gram](https://gram-editor.com) is a Zed fork that installs Zed extensions, so use\nthe same [`editors/zed`](editors/zed) extension with the settings above. Gram\ncompiles it to WASM locally at install time, so it needs a Rust toolchain that can\ntarget WASM (`rustup target add wasm32-wasip2`) and `clang`; see the\n[Gram install docs][gram-install].\n\nInstall via the Extension Gallery (`gram::Extensions`) → **Install Local**,\nselecting the [`editors/zed`](editors/zed) directory. **Install From URL** clones\nthe repo and reads `extension.toml` from its root, so it can't reach the\n`editors/zed` subdirectory; use Install Local.\n\n[gram-install]: https://gram-editor.com/docs/extensions/installing-extensions/\n\n### Claude Code\n\n`yayamlls` ships as a [Claude Code](https://claude.com/claude-code) plugin in\n[`editors/claude`](editors/claude): it registers the language server over LSP\n(live diagnostics, hover, completion), adds a hook that runs `yayamlls validate`\nafter each YAML edit and feeds the results back, and bundles a skill. This repo\nis itself a plugin marketplace:\n\n```\n/plugin marketplace add home-operations/yayamlls\n/plugin install yayamlls@yayamlls\n```\n\nThe plugin doesn't bundle the binary — install it first (`brew install\nhome-operations/tap/yayamlls`, `go install`, or a release) so `yayamlls` is on\n`$PATH`; the hook also needs `jq`. Full guide: [`editors/claude/README.md`](editors/claude/README.md).\n\n### OpenCode\n\n[OpenCode](https://opencode.ai) registers custom language servers through the\n`lsp` key in `opencode.json` (project root or `~/.config/opencode/`). OpenCode\nships a built-in YAML server (Red Hat's `yaml-language-server`, keyed `yaml-ls`),\nso disable it alongside the `yayamlls` entry to avoid duplicate diagnostics. Put\nthe binary on `$PATH`, then:\n\n```jsonc\n// opencode.json\n{\n    \"$schema\": \"https://opencode.ai/config.json\",\n    \"lsp\": {\n        \"yaml-ls\": { \"disabled\": true },\n        \"yayamlls\": {\n            \"command\": [\"yayamlls\"],\n            \"extensions\": [\".yaml\", \".yml\"]\n        }\n    }\n}\n```\n\nEach `lsp` entry also accepts `env` and `initialization` (the server reads\n`kubernetes`, `catalog`, `catalogUrl`, `schemas`, `renderers`). Prefer a\nworkspace `.yayamlls.yaml` for those so the config stays editor-agnostic.\n\n### Flux rendering\n\nOpening a `HelmRelease` or `Kustomization` surfaces schema violations on the\n[flate][flate]-rendered manifests as\n`[rendered \u003ckind\u003e/\u003cname\u003e @ \u003cjsonptr\u003e]` on the source document. A code lens\non the resource offers **View rendered** and **Diff rendered**; running it\nopens the result in the editor via a `window/showDocument` request, so no\nclient-specific glue is needed.\n\nClients that open local-file `showDocument` requests display it directly —\nNeovim ≥ 0.11 and VS Code do. Zed currently no-ops local-file `showDocument`\n([zed#53123][zed-showdoc]), so the lens runs but nothing opens; it will work\nunchanged once Zed supports it. Other features (diagnostics, completion, hover,\ncode actions) are unaffected everywhere.\n\n[zed-showdoc]: https://github.com/zed-industries/zed/discussions/53123\n\n### Debugging\n\n```sh\nyayamlls --log-file /tmp/yayamlls.log -v 2\n```\n\n`-v 0` is silent (default), `1` is info, `2+` is debug.\n\n## Configuration\n\n`.yayamlls.yaml` in the workspace root:\n\n```yaml\nschemas:\n    \"https://json.schemastore.org/github-workflow.json\":\n        - \".github/workflows/*.yml\"\n    \"./schemas/local.json\":\n        - \"k8s/**/*.yaml\"\n\ncatalog: true\ncatalogUrl: \"\"\n\n# Optional. Kubernetes apiVersion+kind auto-detect (on by default). Set\n# enabled: false to run as a generic YAML language server. schemaUrl overrides\n# the lookup template; placeholders: {group}, {groupSeg}, {groupFirst},\n# {groupFirstSeg}, {kind}, {kindLower}, {version}, {versionLower}.\n# kubernetes:\n#   enabled: false\n#   schemaUrl: \"https://schemas.example.com/{groupSeg}{kindLower}_{versionLower}.json\"\n\n# Optional. Defaults shown.\n# renderers:\n#   flate:\n#     enabled: true\n#     # Narrow the Flux entry flate builds from (defaults to the workspace\n#     # root), so a HelmRelease resolves a source defined elsewhere. Output is\n#     # scoped to the edited resource by metadata.name. Relative to workspace root.\n#     path: kubernetes\n#   # Declare your own renderer for any kind by shelling out to a command.\n#   # No recompile needed — flate is just the built-in version of this.\n#   kustomize:\n#     match: { kind: Kustomization, group: kustomize.toolkit.fluxcd.io }\n#     command: [\"kustomize\", \"build\", \"{dir}\"]\n\n# Optional. Debounce (ms) before a document change triggers a renderer.\n# Default: 750.\n# renderDebounceMs: 750\n\n# Optional. Max time (ms) a single render may run before its deadline trips.\n# Raise it if a slow source fetch (git/OCI) trips \"context deadline exceeded\".\n# Default: 30000.\n# renderTimeoutMs: 30000\n\n# Optional. YAML tags resolved by an external tool (Flux, CloudFormation,\n# Vault, …). Nodes carrying one skip schema validation, since the value\n# present in the file is a placeholder, not the resolved value.\n# customTags:\n#   - \"!Ref\"\n#   - \"!vault\"\n```\n\nBy default `flate` builds from the workspace root, following Flux's `spec.path`\nreferences to resolve sources (such as an `OCIRepository`) defined elsewhere and\nscoping the build to the edited resource's `metadata.name`. Set\n`renderers.flate.path` (typically your cluster root) to point at a narrower Flux\nentry; relative paths anchor at the workspace root.\n\n### Custom renderers\n\nA `renderers:` entry with `match` and `command` declares a subprocess\nrenderer, so any tool that prints Kubernetes YAML can drive the rendered-output\ncode lens and diagnostics — no recompile. `match` selects documents by `kind`\n(and optional `group`, matched on a group boundary). `command` is the argv to\nrun; its stdout is parsed as multi-document YAML. Placeholders: `{dir}` (the\ndocument's directory), `{file}` (its path), `{name}` (`metadata.name`). The\ncommand runs with its working directory set to the document's directory.\nA config-declared renderer takes precedence over a built-in one matching the\nsame kind, and a missing command binary is treated as \"renderer unavailable\"\n(silent).\n\nSee [`.yayamlls.yaml.example`](.yayamlls.yaml.example) for a copyable starter.\n\nSame shape works via `initializationOptions` or\n`workspace/didChangeConfiguration`. Precedence (low → high):\n`.yayamlls.yaml` → `initializationOptions` → `didChangeConfiguration`.\n\n## Suppressing diagnostics\n\nComments mute diagnostics so the language server stops reporting them:\n\n```yaml\nage: not-a-number  # yayamlls-disable-line\n\n# yayamlls-disable-line\nage: not-a-number\n\n# yayamlls-disable\nfoo: bad\nbar: also-bad\n# yayamlls-enable\n```\n\n- `# yayamlls-disable-line`: trailing a value, suppresses that line; on its\n  own line, suppresses the line below.\n- `# yayamlls-disable` / `# yayamlls-enable`: suppress every line in between.\n- `# yayamlls-disable-file`: suppress the whole file (place it anywhere).\n\n## Capabilities\n\n`textDocument/`: diagnostics, completion (trigger characters `:`, ` `, `-`;\nsnippet expansion when the client supports it), hover, foldingRange,\ndocumentLink, documentSymbol, codeAction (enum + suppress quick-fix), codeLens.\n\n`workspace/`: didChangeConfiguration, didChangeWorkspaceFolders,\ndidChangeWatchedFiles (config hot-reload + render cache invalidation),\nexecuteCommand.\n\n## Commands\n\n- `yayamlls.showRendered \u003curi\u003e`: rendered output for a Flux source.\n- `yayamlls.showRenderedDiff \u003curi\u003e`: unified diff between the open-time\n  render and the current render.\n\n## CLI flags\n\n```\nyayamlls --version              print version and exit\nyayamlls --log-file PATH        append logs to PATH instead of stderr\nyayamlls -v N                   log verbosity (0=silent, 1=info, 2+=debug)\n```\n\n## Validate (one-shot, for CI)\n\n`yayamlls validate` (alias `lint`) checks files without an editor, resolving\nschemas the same way the server does (modeline, `.yayamlls.yaml` globs,\ncatalog, Kubernetes auto-detect) and honouring `# yayamlls-disable*`\ncomments. Directory arguments are walked for `*.yaml`/`*.yml`.\n\n```sh\nyayamlls validate deploy.yaml            # one file\nyayamlls validate k8s/                   # walk a directory\nyayamlls validate --root . manifests/    # pin the workspace root for .yayamlls.yaml\n```\n\nDiagnostics print as `path:line:col: severity: message`. The exit code is\n`1` when any error-severity diagnostic is reported, `2` on a usage or I/O\nerror, `0` otherwise. The workspace root is auto-detected (nearest\n`.yayamlls.yaml` or `.git`) unless `--root` is given.\n\n## Development\n\n```sh\nmise install   # toolchain\nmise run test\nmise run lint\nmise run build\n```\n\n[flate]: https://github.com/home-operations/flate\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhome-operations%2Fyayamlls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhome-operations%2Fyayamlls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhome-operations%2Fyayamlls/lists"}