Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>OtterScript Language ExtensionNew to Visual Studio Code? Get it now.
OtterScript Language Extension

OtterScript Language Extension

Sigurd Hansen

|
3 installs
| (0) | Free
OtterScript language support: syntax highlighting, IntelliSense (hover, completion, signature help), diagnostics with quick fixes, navigation, and snippets.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

OtterScript Language Extension

VS Marketplace Open VSX Build

Language support for OtterScript, the scripting language of Inedo's Otter, BuildMaster and ProGet: syntax highlighting, completion, hover documentation and signature help, diagnostics with quick fixes, module navigation, snippets, and checks for Adaptive Cards in Teams webhook templates.

Not affiliated with or endorsed by Inedo.

Otter, BuildMaster and ProGet are trademarks of Inedo.

Background

This extension started as a learning project while implementing custom webhook notification in ProGet.

Features

  • Syntax highlighting, including namespaced operations (ProGet::, Otter::, Windows::)
  • Hover documentation, completion and signature help for every function and operation in Inedo's Otter and BuildMaster reference, ProGet's notifier variables, and map/vector expressions; inside an operation call, completion and hover for its argument names (Copy-Files(To: ...))
  • Diagnostics for common mistakes (see the list of checks) — also for $ expressions in a text template's literal output, such as $ToJson(...) in a webhook body
  • Adaptive Card checks, triggered by a literal "type": "AdaptiveCard" object in a template: unknown types, values a property doesn't allow ("weight": "bold"), elements or properties newer than the card's "version", Action.ToggleVisibility targets with no matching "id", and Teams webhook mistakes such as a wrong "contentType" or Action.Submit. Completion inside the card offers "type" values, a property's allowed values and toggle targets. Based on the Adaptive Card 1.6 schema plus Teams-only elements; best-effort, not a full schema validation
  • Quick fixes, plus a Fix All Issues command (Ctrl+Shift+Alt+F, Cmd+Shift+Alt+F on macOS); fixes that would cause a new problem, or that guess a name, are left to the lightbulb. To apply the same fixes on save, add "editor.codeActionsOnSave": { "source.fixAll": "explicit" } to your settings
  • Module navigation: hover on call MyModule (its declaration and comment), completion and signature help for its arguments, Go to Definition (F12, also to a module declared in another workspace file), Find All References (Shift+F12) and Rename (F2) across workspace files, CodeLens reference counts, Outline and breadcrumbs, and Go to Symbol in Workspace (Ctrl+T); completion of module names after call, from this file and the rest of the workspace
  • Variables: hover shows where one of the file's own variables gets its value (the assignment lines, or the module parameter, foreach or operation output it comes from) and how often it's used; completion of the ones the file uses, Go to Definition (F12) to where they're assigned, Rename (F2) everywhere in the file (strings included), and highlighting all occurrences of a variable ($x, @list, %map, ${my var}) or module, with declarations and assignments marked as writes
  • with blocks and await: completion of the directives (retry, timeout, executionPolicy, async, lock, isolation, credentials) and of executionPolicy's values, hover on each, and checks for an unknown directive or a value it doesn't take; after await, completion of the file's async tokens, a hover listing the blocks it waits for, and a hint when no block in the file starts that token
  • Code folding via #region / #endregion and block structure
  • Snippets for common patterns: module, call, async / await, lock, forserver and foreachserver blocks, and teamscard: a complete Teams webhook body with an Adaptive Card

Status

Early-stage and in active development; features may change. Developed and tested mainly against ProGet — OtterScript is shared with Otter and BuildMaster, but their product-specific constructs are less tested. See the CHANGELOG for release notes.

What this extension does NOT do

  • It does not execute OtterScript — diagnostics are static, best-effort pattern checks, not proof a script will run correctly; they prefer missing a problem over flagging correct code
  • It does not connect to Otter, ProGet, or other Inedo services
  • It does not format your code, and fixes nothing on its own: fixes are only applied when you invoke a quick fix or Fix All Issues, or on save when you turn that on (see above)

Getting Started

Install OtterScript Language Extension from the Extensions view (Ctrl+Shift+X), then open any .otter or .oscript file. No configuration is required. Requires VS Code 1.85 or newer. It also works in VS Code for the Web, such as vscode.dev and github.dev, and in Restricted Mode and virtual workspaces, since it never runs your scripts.

If hover or completion doesn't appear, check that the language mode in the status bar is OtterScript.

Settings

All features are enabled by default and can be toggled individually:

  • otterscript.completion.enable — completion suggestions
  • otterscript.signatureHelp.enable — signature help for functions and operations
  • otterscript.hover.enable — hover documentation
  • otterscript.codeLens.enable — CodeLens reference counts above module declarations
  • otterscript.workspaceSymbols.enable — modules in Go to Symbol in Workspace (Ctrl+T); cross-file module navigation works either way
  • otterscript.inlayHints.parameterNames — parameter names before a function call's positional arguments, $Substring($x, Offset: 2) (VS Code's editor.inlayHints.enabled also turns all inlay hints off, or on only while you hold Ctrl+Alt)

otterscript.product (default "any") is the Inedo product your scripts run in: ProGet, Otter or BuildMaster. Completion then leaves out what that product doesn't have, such as BuildMaster's release functions in a ProGet notifier, and hover says so when you use one anyway. Where a function's arguments differ between products ($PackageProperty), signature help and parameter-name hints follow that product's form.

otterscript.adaptiveCards.maxVersion (default "1.6") is the highest Adaptive Card version the host that shows your cards supports. Lower it if your cards go to an older host.

Turning individual diagnostics off

Every diagnostic has a code, shown in the Problems panel, where it links to this section. Use otterscript.diagnostics.rules to turn a check off ("off") or change its severity ("error", "warning", "information", "hint"):

"otterscript.diagnostics.rules": {
  "unknown-operation": "off",
  "assignment-in-condition": "hint"
}

Each diagnostic's lightbulb menu also offers Turn off '<code>' diagnostics, which adds the "off" entry to your workspace settings (or user settings when no folder is open).

Code Flags
unbalanced-symbol Unclosed or unexpected { }, ( ) or [ ]
missing-dollar A variable in a condition without its $
assignment-in-condition = in a condition where == was probably meant
invalid-operator & or \| where && or \|\| is required
incorrect-for-usage for used as a loop (use foreach)
duplicate-map-key The same key twice in a %(...) map
duplicate-module Two modules with the same name in one file
unknown-scalar-function Unknown $Name(...) function
unknown-vector-function Unknown @Name(...) function
unknown-map-function Unknown %Name(...) function
unknown-operation Unknown operation
unknown-namespace Unknown Namespace:: prefix
too-many-arguments More arguments than the function accepts
too-few-arguments Fewer arguments than the function requires
missing-required-argument Operation call without a required argument, e.g. Copy-Files without To (a hint)
unknown-argument Operation argument name that looks like a typo of a documented one, e.g. Fomr: in Copy-Files (a hint)
unknown-with-directive with directive that doesn't exist, e.g. retyr=3
invalid-with-directive-value with directive value it doesn't take, e.g. executionPolicy=sometimes, or a missing one
unknown-await-token await name; with no with async=name block in the file (a hint)
template-unexpected-close %> with no matching <%
template-unclosed <% that is never closed
template-end-keyword <% end %> where <% } %> is required
template-missing-brace Block tag such as <% if ... %> missing its {
template-in-expression <% %> inside an unclosed OtterScript expression
adaptivecard-missing-version Adaptive Card without a "version"
adaptivecard-unknown-type Unrecognized Adaptive Card "type"
adaptivecard-invalid-value Card property value that isn't allowed, e.g. "weight": "bold"
adaptivecard-version-too-low Card element, action or property newer than the card's "version"
adaptivecard-version-too-high Card "version" newer than otterscript.adaptiveCards.maxVersion
adaptivecard-templating-keyword Adaptive Card Templating key ("$data", "$when", ...) that OtterScript expands
adaptivecard-unknown-target Action.ToggleVisibility target that no element in the card has as its "id"
adaptivecard-duplicate-id "id" that another element in the card already has
adaptivecard-content-type Teams message attachment without the Adaptive Card "contentType"
adaptivecard-webhook-submit Action.Submit in a Teams message (webhooks don't support it)

Contributing

Contributions are welcome — see CONTRIBUTING.md. Report security issues as described in SECURITY.md. This project follows the Contributor Covenant Code of Conduct and is licensed under the MIT License.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft