// SPDX-License-Identifier: CC-BY-SA-4.0
// (PMPL-1.0-or-later preferred; MPL-2.0 required for VS Code marketplace)
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>

= K9-SVC -- VS Code Extension
:author: Jonathan D.A. Jewell
:revdate: 2026-03-17
:toc: preamble
:icons: font

Syntax highlighting, language configuration, and snippets for K9 -- the
security-tiered service configuration language built on Nickel. Supports both
`.k9` (Kennel format) and `.k9.ncl` (Nickel format) files.

== Installation

=== From the VS Code Marketplace

[source]
----
ext install hyperpolymath.k9-svc
----

=== From VSIX

[source,sh]
----
code --install-extension k9-svc-0.1.0.vsix
----

=== From Source

[source,sh]
----
cd editors/vscode
npx @vscode/vsce package
code --install-extension k9-svc-0.1.0.vsix
----

== Features

* *Two TextMate grammars* -- one for `.k9` (Kennel) and one for `.k9.ncl` (Nickel)
* *Language configuration* for both formats with bracket matching, auto-closing
  pairs, and `#` comment toggling
* *13 snippets* across both language variants for common K9 patterns
* Semantic colouring for trust levels: `kennel`, `yard`, `hunt`
* K9 magic number (`K9!`) highlighting
* Icon for K9 files (SVG)

== Supported File Extensions

[cols="1,1,2"]
|===
| Extension | Language ID | Description

| `.k9`
| `k9`
| K9 Kennel format -- YAML-like declarative syntax

| `.k9.ncl`
| `k9`
| K9 Nickel format -- programmable validators with contracts
|===

== K9 Kennel Format (.k9)

TextMate scopes for the YAML-like variant:

[cols="1,2"]
|===
| Element | Scope

| Magic number (`K9!`)
| `keyword.control.magic`

| Trust levels (`kennel`, `yard`, `hunt`)
| `entity.name.type.trust-level`

| Pedigree fields (name, version, etc.)
| `keyword.other.pedigree`

| Security levels
| `constant.language.security-level`

| Key-value pairs
| `entity.name.tag` / `string.unquoted`

| Comments, strings, numbers, booleans
| Standard scopes
|===

== K9 Nickel Format (.k9.ncl)

TextMate scopes for the Nickel variant:

[cols="1,2"]
|===
| Element | Scope

| `let` bindings
| `keyword.other.let` / `variable.other.binding`

| Contracts and types
| `entity.name.type.contract`

| `import` statements
| `keyword.control.import`

| Record literals
| `punctuation.definition.record`

| Recipe/validator blocks
| `keyword.other.recipe`

| Security level annotations
| `constant.language.security-level`

| Nickel keywords
| `keyword.control`

| Built-in types (Str, Num, Bool, etc.)
| `support.type.builtin`

| String interpolation (`%{...}`)
| `meta.interpolation`
|===

== Snippets

=== K9 Kennel (.k9)

[cols="1,1,2"]
|===
| Prefix | Name | Description

| `k9`
| K9 Magic Header
| File header with magic number and pedigree fields

| `validator`
| Validator
| Validator block with checks

| `recipe`
| Recipe
| Recipe with inputs/outputs/constraints

| `dep`
| Dependency
| Dependency entry with trust level

| `kennel`
| Kennel Trust
| Set trust to kennel (highest)

| `yard`
| Yard Trust
| Set trust to yard (medium)

| `hunt`
| Hunt Trust
| Set trust to hunt (lowest)
|===

=== K9 Nickel (.k9.ncl)

[cols="1,1,2"]
|===
| Prefix | Name | Description

| `k9ncl`
| K9 Nickel Validator
| Complete validator template with config import

| `let`
| Let Binding
| Let binding with contract annotation

| `rec`
| Record
| Record literal

| `contract`
| Contract
| Custom Nickel contract with label and value

| `import`
| Import
| Import statement

| `recipe`
| Recipe
| Nickel recipe block with typed fields
|===

== Configuration

The extension requires VS Code >= 1.75.0 and registers under the
"Programming Languages" category. No additional configuration is needed --
K9 files are automatically detected by extension.

=== Language Configuration

Both `.k9` and `.k9.ncl` files share:

* *Line comment* -- `#`
* *Bracket matching* -- `{}`, `[]`, `()`
* *Auto-closing pairs* -- braces, brackets, parentheses, quotes
* *Word pattern* -- `[\w][\w-]*` (allows hyphens in identifiers)

== Screenshots

_Screenshots of syntax highlighting for Kennel and Nickel formats will be
added in a future release._

== License

SPDX-License-Identifier: MPL-2.0

PMPL-1.0-or-later is the preferred license. MPL-2.0 is used because the
VS Code marketplace requires an OSI-approved license.

See link:LICENSE[LICENSE] for the full MPL-2.0 text.
See link:LICENSE-PMPL[LICENSE-PMPL] for the PMPL-1.0-or-later text.

== Part of the K9 Ecosystem

This extension is part of the
https://github.com/hyperpolymath/standards/tree/main/k9-svc[K9 Self-Validating Components]
suite within the `standards` monorepo. Related tools:

* link:../../bindings/[`bindings/`] -- Language bindings (Deno, Rust, Gleam, Elixir, Haskell)
* link:../../actions/validate/[`actions/validate/`] -- GitHub Action for CI validation
* link:../../pandoc/[`pandoc/`] -- Pandoc reader, writer, and filter
* link:../../SPEC.adoc[`SPEC.adoc`] -- K9 format specification
