Ecko for VS Code
Language support for Ecko - the language where ai is a
keyword, not an import.
Diagnostics, completion, hover, go-to-definition and formatting come from
ecko lsp, which is the compiler itself, so your editor cannot disagree with a
build. Syntax highlighting and 37 snippets work with no server at all.
What Ecko looks like
An LLM call is a language construct, not a client library. There is nothing to
import and nothing to configure:
answer = ai "What is the capital of France?"
print(answer)
# Ask for a type and you get that type back, not a string to parse.
count = ai[Int] "How many moons does Mars have?"
print(count + 1)
Because calls are ordinary expressions, they compose the way everything else
does:
notes = "Meet me on 12 March, and again on 4 April."
dates = notes
|> ai "Extract every date"
|> ai "Format as ISO 8601, one per line"
print(dates)
Ask for one of your own types and the answer arrives already checked against it,
so match stays exhaustive. Mark a function @tool and the model can call it
while it works:
type Sentiment = Positive | Negative | Neutral
## Look up which plan a customer is on. The model may call this itself.
@tool("look up which plan a customer is on")
fn plan_for(customer) = "enterprise"
fn triage(message) = ai[Sentiment] message using [plan_for]
mood = triage("The build has been broken for three days.")
print(match mood {
Positive => "no action"
Negative => "escalate"
Neutral => "queue"
})
The parts that usually get bolted on afterwards are in the language. Untrusted
text is fenced off inside a prompt rather than concatenated into it, secrets
resist being printed by accident, and contracts are checked at the boundary:
key = secret("sk-live-abc123")
template ask(@untrusted question) = """
Answer only from company policy.
{input question}
"""
@requires(len(q) > 0)
@ensures(len(result) > 0)
fn helpdesk(q) = ai ask(q)
print(helpdesk("How do I reset my password?"))
There is more than the ai keyword: pattern matching over union types,
pipelines, sql { ... } blocks with real bind holes, share-nothing concurrency,
and a standard library that is already installed - import std.http is an HTTP
server, import std.sql is SQLite.
It all runs offline
Every example above runs with no API key. Ecko has a deterministic mock mode:
typed calls return schema-valid values, so pipelines, tools and contracts keep
working before you have configured a provider. Paste any of them into a file and
run it:
ecko example.ecko
Try the language in your browser first, if you would rather: the
playground is the real compiler built to WebAssembly,
running client-side with no backend.
What this extension gives you
From the language server (needs the ecko binary):
- Live diagnostics as you type - parse errors, undefined names with
did-you-mean, arity mismatches, use before definition, non-exhaustive matches,
unreachable code, unused imports and variables, shadowed builtins, and
unwrapped credentials
- Completion for keywords, builtins,
std modules, your own top-level
functions, types and variables, and a module's members after a .
- Hover showing signatures for your functions and labels for builtins
- Go to definition, document symbols for the outline and breadcrumbs, and
workspace symbol search
- Find All References and occurrence highlighting, scoped to the open file
and scope-aware - a name shadowed in an inner block resolves to its own
declaration, not to every occurrence of the spelling
- Quick fixes on four diagnostics: correct a misspelled name to the
suggestion the compiler already computed, remove an unused import, prefix an
unused binding with
_, or fill in the missing arms of a non-exhaustive
match
- Semantic highlighting, coloured by the compiler rather than the grammar,
so
std modules and types are told apart from ordinary names
- Format Document, the same result as
ecko fmt
Always, with no server:
- Syntax highlighting for
.ecko, covering string interpolation, raw and byte
strings, decimal literals, the ai clauses (using, with, on,
-> stream), sql { ... } blocks, contract and tool annotations, and ##
documentation comments
- 37 snippets -
ai, ai[T], ai ... using, template, @tool,
@requires, match, sql, secret and the rest
- Auto-closing brackets and quotes, indentation rules, and folding via
# region / # endregion
Requirements
The editing intelligence is served by ecko lsp, so you need the binary. It is
a single file with nothing to configure:
curl -fsSL https://ecko.sh/install | sh
The extension looks for it in this order:
ecko.server.path in your settings
- the
ECKO_BINARY environment variable
ecko on your PATH
~/.local/bin/ecko, then ~/.ecko/bin/ecko, then /usr/local/bin/ecko
Those fallbacks matter because VS Code and Cursor started from a desktop
launcher often do not inherit a shell's PATH, and "the server won't start" is
almost always that. Set ecko.server.path to an absolute path if so.
Without the binary you still get highlighting and snippets, and a notice
explaining how to switch the rest on.
Learn more
Licence
Ecko is proprietary software. It is free for personal and educational use, and
for evaluating it in a business for up to 30 days. Any other business use,
including internal tooling, needs a commercial licence - see
ecko.sh/enterprise.
The extension and the language share these terms; the full text is in LICENSE.