Syntax Guide
The Intend DSL looks like TypeScript but replaces function bodies with natural language steps.
Basic Structure
// Imports work just like TypeScript
import { User } from "./types";
// 'entry' marks this as a public function
export entry intent CreateUser(name: string) -> User {
// A step defines an action
step "Validate the name is not empty"
// Steps can produce variables
step "Create a new user object" => const user
// Steps can define return types if ambiguous
step "Save user to database" => const savedUser: User
// Invariants define constraints
invariant "User email must be unique"
// Ensure defines post-conditions
ensure user.id is defined
}Keywords Reference
intent
Defines a function specification. It acts like function in TypeScript, but the body is defined by goals (steps), not implementation code.
export intent HashPassword(pwd: string) -> string { ... }step
A simplified instruction for the AI. It can be a plain text instruction or capture a result into a variable.
Usage:
// Simple action
step "Validate email format"
// Capture result into a constant
step "Hash the password" => const hash
// Capture result into a mutable variable
step "Calculate current age" => let ageDirect Calls
You can invoke other intents or functions directly using standard call syntax. This provides deterministic control flow.
Usage:
// Call an intent and capture the result
HashPassword(inputPassword) => const hashedPassword
// Call without capturing result
LogAudit(userId)invariant
A hard rule or constraint that must be true throughout or before the logic runs. The AI uses this to add validation logic or choose implementation paths that satisfy the constraint.
Usage:
invariant "Password length > 8"
invariant "User must be authorized"ensure
A post-condition check. Intend generates runtime assertions to guarantee these are true before the function returns. If the condition is not met, the code will throw a validation error.
Usage:
ensure user is defined
ensure age is a number
ensure result.status === 'success'return
Explicitly return a variable from the intent.
Usage:
step "Calculate total" => const total
return totalentry
Marks an intent as an entry point. This tells the compiler to generate a top-level exported function in the output TypeScript file. Without entry, the intent is treated as an internal helper (unless exported).
export
Makes the intent available for import in other .intent files.
import
Works exactly like TypeScript import. You can import types or other intents.
import { User } from "./types";
import { HelperIntent } from "./helpers.intent";context
Defines a global system prompt or rule set for the entire file. It must be placed at the very top of the file. This is useful for sharing domain knowledge across multiple intents in the same file.
Usage:
context "All currency values are in cents (integers)."
import { ... } from ...
export intent ...Standard Libraries (Auto-Import)
Intend knows about standard Node.js/Bun modules. You can use them in your steps logic naturally without manually importing them. The compiler detects their usage and injects the necessary imports automatically.
Supported Modules:
http,httpsfs(FileSystem),pathcrypto(for UUIDs, hashing)os,child_processurl,events,util
Example:
// You don't need to write 'import fs from "fs"'
step "Read the config file" => const config
// The AI will generate: fs.readFileSync(...) and the compiler will add the import!Member Access in Calls
You can pass nested properties directly to intents or function calls.
// Valid syntax
CreateUserStory(user.name)
LogAudit(ctx.request.user.id) => const logId
return result.data