Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>HexaSync TemplatesNew to Visual Studio Code? Get it now.
HexaSync Templates

HexaSync Templates

Beehexa Corp

|
4 installs
| (1) | Free
A domain-specific IDE for HexaSync Template development.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

HexaSync Templates — VS Code Extension

A domain-specific IDE for HexaSync Template development: semantic IntelliSense, reference validation, component navigation, composition and visualization over the HexaSync template graph.

What it gives you

Open any *.yaml inside a project — a folder whose partials/ holds a main.yaml — and the extension builds that project's effective graph, inheritance included, then works from it:

IntelliSense Completion and hover from the schemas in assets/, including per-value documentation — hover a step's displayType and you get that type's paragraph, not all 41
Problems Unresolved references, dangling ids and deprecated (legacy) configuration, each on the line that causes it. Advisory: a project that cannot compose reports the failure rather than a cascade
Components tree Every collection in the project, each component's sub-tree — its puller, table, validations, transformations, dependencies, metrics — and what the project inherits
Navigation HexaSync: Find Project across the workspace, HexaSync: Find Component scoped to the open project and what it inherits. Both typo-tolerant
Preview A component in its ecosystem: overview, relations, data in and out, the authored guide, and a Flow diagram whose nodes jump to the step they name. Every stage — beforePullSteps → pullSteps → afterPullSteps → finalSteps, or steps → onErrorSteps → finalSteps — is one chart, each stage a box holding its own sub-flow. Zoom, pan, fit, fullscreen, and a top-down / left-right toggle. One panel is reused; pin a preview (HexaSync: Pin/Unpin Preview, or the 📌 on its tab) to keep it and send the next preview to a new panel
Dependency graph HexaSync: Show Dependency Graph draws a component and what connects to it, two hops out; click any node to open where it is declared. Bounded and honest about it — the page says how many components it left out
Provenance HexaSync: Explain This Value answers "where did this come from" for a value you did not write: contributing files in merge order, what each replaced, and which weight or index decided it. The one command that refuses rather than guess — on a stale snapshot it declines and says why
Compose HexaSync: Compose Current Project runs the real composer over your unsaved buffers and writes nothing; the result is explained rather than dumped
Rename F2 on a component or a reference renames it across the project as ranged edits. Refuses — with the reason — when the edit would reach a library file, an ancestor project, or a reference it cannot tell apart from another component's
Authoring Variable extraction and families, UUID generation, scaffolding, quick fixes for every reference rule

Forty-three commands, all prefixed HexaSync: in the Command Palette. Diagnostics and logs go to the HexaSync Templates output channel.

Requirements

Version Why
../hexasync-cli-nodejs a sibling clone Required to build at all today. The @beehexa/* composer packages are not published yet, so every build resolves them from source. Clone it beside this repo, or point HEXASYNC_CLI_PATH at it
Node ≥ 22.13 The strictest floor in the toolchain, therefore binding
yarn 4.18.0 Pinned via packageManager, matching the sibling hexasync-cli-nodejs so both repos resolve the same yarn. nmHoistingLimits: dependencies keeps the structural half of the dependency-boundary enforcement: an undeclared transitive does not resolve from the root
VS Code ≥ 1.74.0 The documented baseline for web extensions; every other API this project needs predates it
redhat.vscode-yaml ≥ 1.22.0 · mandatory Renders every schema description. Below 1.22.0 it drops markdownDescription that sits beside a $ref — and these schemas are heavily $ref-federated, so authored hovers vanish with no error

Each dependency is classified mandatory, optional or bundled in package.json under hexasync.requiredExtensions. On activation the extension checks them and says what is missing, what is too old, and — for an optional one — which capability you are without. A mandatory gap is a warning with a Show Extension button that opens the Extensions view filtered to it; an optional gap is an information notice.

Today there is exactly one dependency, and it is mandatory. The optional and bundled branches are implemented and covered by tests, and nothing in the shipped manifest exercises them — said plainly rather than padded with a dependency the extension does not really have.

In a browser (vscode.dev)

The extension runs in a web host: one build graph produces both entry points, and the browser bundle carries no Node builtin — verified against the built artefact, not assumed (docs/decisions/0015-the-web-target.md).

Nothing is unavailable in a browser. Every capability reaches the filesystem through the editor's own API, which a web host has; the desktop entry point installs a faster reader, and that is an optimisation rather than a capability. What differs:

In a browser
IntelliSense, diagnostics, navigation, pickers, the Components tree slower — reading the workspace goes through the editor filesystem API, measured about 4,000× slower than Node on a desktop host, so a large project takes proportionally longer to index
Compose Current Project slower, for the same reason: it composes from the same reads
Install / Update IntelliSense writes 77 files through the editor API. A workspace opened read-only — a repository through vscode.dev, for instance — cannot be written to at all, and the command says so, naming the environment
Preview, Dependency Graph, Explain This Value, compose report, rename, variable authoring identical

HexaSync: Show Info prints the same list for the host you are actually on. It is generated from one inventory (src/lib/webCapabilities.ts), so this table and that output cannot drift apart.

Not benchmarked in a browser. The figures above are desktop measurements of the API a browser is obliged to use. No web budget is claimed until one is measured in a real browser host; see ADR 0015 for what would close that.

Develop

git clone <this repo> && cd hexasync-templates-vscode-ext
git clone <the CLI repo> ../hexasync-cli-nodejs   # required — see Requirements
corepack yarn install         # yarn comes from the packageManager field
corepack yarn build:local     # builds BOTH entry points
corepack yarn test            # vitest
corepack yarn typecheck       # tsc --noEmit

build:local, not build. They differ by one flag, and build resolves @beehexa/* from a registry — where nothing is published yet, so it fails naming the flag. Every :local script is the one that works today; the plain one is the path that starts working at the first publish. Same split as package / package:local.

Then press F5 — "Run Extension (Node host)" or "Run Extension (Web host)" — to launch an Extension Development Host. Its pre-launch task is the default build task, which runs build:local, so F5 works from a clean clone with the sibling present. corepack yarn watch:local rebuilds on change.

Verify it loaded: HexaSync: Show Extension Info in the Command Palette.

Debug

Two launch configurations in .vscode/launch.json, and which one you pick is a real choice: the web host has no Node builtins, so a defect that only appears there is usually an import that should not exist. Test in the Node host, reproduce host-specific bugs in the web host.

corepack yarn watch:local   # rebuild on save; reload the dev host window to pick it up
  • Breakpoints work in src/** directly — both bundles are built with source maps (--production strips them, and yarn package:local uses --production, so debug an unminified yarn build:local instead).
  • The log first. Open View → Output → HexaSync Templates. Every subsystem reports there with timings: project discovery, the per-project graph build, validation, tree expansion, reveal. Most "it's slow" and "nothing happened" questions are answered by that channel in one line, and the timings are why three performance defects were found by measurement rather than guesswork.
  • Reload after installing a build. An installed .vsix is only picked up by a window reload (Developer: Reload Window), which is also why yarn install:vscode-server 0.0.31 takes an optional version: bumping it makes the host list a new folder, so you can see at a glance which build is loaded.
  • A stale graph is marked, not hidden. If the tree or a hover says provisional, the project could not be rebuilt from the current text and you are reading the last good snapshot — look for the parse error.

Package and install

corepack yarn package:local              # produces the .vsix alone, resolving @beehexa/* from source
corepack yarn install:vscode-server      # browser VS Code: build, package, install, verify
corepack yarn install:vscode             # desktop VS Code
corepack yarn install:vscode-server 0.0.31   # …packaged AS that version, without editing package.json

Use package:local today, not package. They differ by one flag — package builds in registry mode, and nothing under @beehexa/* is published yet, so it fails with a message naming the flag (see Working against local packages below). package is the release path and starts working at the first publish; package:local is the one that produces a .vsix right now. Both run the same three gates.

The two install:* scripts build with --local, pick the right CLI, and check the host actually registered the extension — see Install the extension.

To install a .vsix by hand, which is all either script ultimately does:

# Desktop VS Code
code --install-extension hexasync-templates-<version>.vsix

# Browser VS Code — use the CLI belonging to the RUNNING server, not a `code-server` on PATH
~/.vscode/cli/serve-web/<build>/bin/code-server --install-extension hexasync-templates-<version>.vsix

Mind the version. package:local names the .vsix after package.json, which is still 0.0.1. If you have previously installed an ad-hoc build (yarn install:vscode-server 0.0.38), the CLI treats 0.0.1 as a downgrade, refuses it, and still exits 0 — reported success, and the old build still loaded after a reload. Pass a higher version (yarn install:vscode-server 0.0.39) or uninstall first.

That second path is the whole reason yarn install:vscode-server exists. Installing with the wrong CLI writes into a directory the running server never reads, and reports success — the machine this was first written against had five serve-web builds and a code on PATH older than the running server. The script finds the right one, installs, and then verifies the host actually registered the extension; by hand, you are picking that build yourself.

Either way the extension is read from the file on disk. No Marketplace access is required at any step — nothing in the install path resolves a registry. Marketplace publication is prepared but deliberately not a precondition for internal adoption.

Then Developer: Reload Window. No CLI can do that part.

Validate dependencies

Three kinds of dependency, checked in three different places, because they fail in three different ways.

1. Editor extensions the developer must install. Declared in package.json under hexasync.requiredExtensions, each with a minimum version, a mandatory | optional | bundled classification and a reason:

{ "id": "redhat.vscode-yaml", "minVersion": "1.22.0", "classification": "mandatory",
  "reason": "Renders every schema description. Below 1.22.0 it drops markdownDescription beside a $ref…",
  // Required on an OPTIONAL entry: the capability a developer loses without it. A reason explains a
  // mechanism; this names the thing that stops working, which is what the notice says.
  "capability": "Schema descriptions on hover and in completion" }

The extension checks these on activation and reports what is missing or too old, with the reason — the alternative being hovers that are silently empty. Add a dependency by adding an entry; no code changes.

2. Node builtins that must never reach the web host. The web extension host provides no fs, child_process, path, process, os, util or url:

corepack yarn check:web-bundle   # audits the emitted bundle AND every source file

Two guards, because one is not enough: an esbuild plugin fails the web build on such an import and names the importing file, and check:web-bundle audits the emitted bundle, so a builtin arriving through a dependency is caught too. Node-only modules are exempted by an explicit allowlist, each justified by a test.

3. The shared @beehexa/* packages. See below — resolution is a build flag, never ambient.

corepack yarn check:assets   # the asset bundle integer was bumped if assets/ changed
corepack yarn prose:check    # schema descriptions match their authored Markdown source
corepack yarn coverage:check # coverage has not regressed against the recorded baseline

corepack yarn package:local runs the production build and then four gates — the web-bundle audit, the prose check, the coverage check and the asset-version check — before it will produce a .vsix, so a broken bundle cannot be packaged by accident.

Two entry points, one build graph

main → dist/extension.node.js · browser → dist/extension.browser.js

Both delegate to src/extension.shared.ts, so behaviour cannot drift between hosts.

Working against local @beehexa/* packages

No publish step is needed to iterate on the shared composer packages — pass --local:

corepack yarn build --local        # @beehexa/* resolve from ../hexasync-cli-nodejs
corepack yarn dev --local          # same, in watch mode
corepack yarn build:prod --local

corepack yarn build                # no flag → published versions

The flag is the only input. There is no persisted mode and no auto-detection: both were tried and replaced. A persisted mode put the answer to "what am I building against?" in a file you last touched days ago; auto-detection meant merely having a sibling checkout on disk silently changed what your build contained. A flag is visible in the command, in shell history and in CI logs.

If your checkout is not the conventional sibling, point at it:

HEXASYNC_CLI_PATH=../elsewhere/hexasync-cli-nodejs corepack yarn build --local

Nothing under @beehexa/* is published yet, so yarn build without the flag fails today — deliberately, with a message naming the flag. Registry mode starts working when the publish story runs.

Why @beehexa/hexasync-template-assets is not in dependencies yet: it is not published. Declaring an unpublishable version breaks install, and declaring a link: path would create a second resolution mechanism competing with the flag. Until publication, resolution comes from the bundler plugin (--local) and tsconfig paths (editor-time types). The dependencies entry lands with the first publish.

Note: the bundler is given tsconfig.json with paths stripped. esbuild honours paths, which would resolve @beehexa/* to local sources regardless of the flag — making the flag decorative and silently mixing the two. Only the plugin decides. paths remains for tsc and the editor, where resolving to local sources is intended.

Release versioning

Four streams, each with one owner. Confusing them is how a consumer ends up running something nobody intended.

Stream Format Owner Meaning
Extension semver (package.json) this repo What a developer installs
@beehexa/* packages semver hexasync-cli-nodejs The shared composer library
Compose contract single integer hexasync-cli-nodejs Bumped only when merge, inheritance or substitution semantics change. Semver cannot express this, so a dedicated integer does
Asset bundle single integer (assets/BUNDLE_VERSION) this repo Assets expose no API to break, so ordering is the only question: is my copy older than what is available?

To cut a release of the extension:

  1. Bump version in package.json — the extension stream, and the only one a release touches by default.
  2. Bump assets/BUNDLE_VERSION if anything under assets/ changed, because a consumer comparing integers is the only way they can tell their copy is behind. yarn check:assets is now part of package and package:local, so a forgotten bump stops the build — but note what it compares: origin/main...HEAD, so it sees committed asset changes, not uncommitted ones. There is no CI in this repository yet; this gate is the enforcement.
  3. Leave the compose contract alone unless composition semantics changed — it is stamped into every published diagnostic set, and bumping it for a refactor makes every consumer think their graph is stale.
  4. corepack yarn package:local and attach the .vsix — package is the registry-mode path and does not build today, exactly as under Package and install above.

For a throwaway build, yarn install:vscode-server <version> packages as that version without editing package.json — useful for confirming which build a host has loaded, and never a release.

Stay up to date

Nobody should file a bug against a build from three weeks ago, so the extension can tell you when a newer one exists. It is off until you point it somewhere:

// settings.json — a URL, or a workspace-reachable path
"hexasync.updateManifest": "https://internal.example/hexasync-templates/manifest.json"

The manifest is JSON. version is required; the rest is optional and unknown fields are ignored:

{ "version": "0.0.40", "from": "https://internal.example/releases", "notes": "Flow diagram fixes." }

from is what the notice tells you to do next — only whoever publishes the build knows how it is distributed, so the extension quotes it rather than inventing one.

Empty by default, deliberately. The manifest's hosting location is not yet decided, so nothing is guessed: with no value set, nothing is read and nothing is shown. When it IS set, every failure is silent — a missing file, an unreachable host, an HTML error page and a half-written manifest all produce a line in the HexaSync Templates output channel and nothing on screen. Dismissing a notice silences that version only; the next build speaks again.

The check reads and nothing more: a bare GET with no query string, no body and no header identifying you, your editor or your workspace (NFR-20). There is no telemetry in this extension.

Layout

src/
  extension.node.ts       # "main"    — Node host entry
  extension.browser.ts    # "browser" — web host entry
  extension.shared.ts     # host-agnostic activation
  lib/                    # pure, testable, no vscode and no Node builtins
  adapters/               # VS Code adapters
assets/
  intellisense/           # canonical schemas — THIS repo is upstream
  docs/                   # long-form Markdown, source for hovers and guides
scripts/                  # build and CI tooling (Node-only, never bundled)
docs/decisions/           # why this repository looks like this
test/                     # vitest; `*Budget.spec.ts` run serialised, see decision 0008

This repository holds VS Code adapters only, no domain logic — the semantic model lives in the @beehexa/* packages so it can also serve the CLI and CI.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft