@actionable/flowscript
v0.1.0
Published
The specification layer for AI-generated code. AI writes flows, you verify intent, code is verified against spec.
Maintainers
Readme
FlowScript
AI writes flows, you verify the intent.
FlowScript is a specification layer for AI-generated code. AI writes flows that describe what SHOULD happen in plain English—then implementation code is verified against it. Non-developers verify intent, not code.
The Problem
When AI generates code:
- It's still code—cryptic syntax only developers understand
- Non-developers must trust blindly or ask someone to review
- No contract exists—you hope the code matches what you asked for
The Solution
FlowScript separates intent (what you want) from implementation (how it's done):
@flow("User Registration")
validate.email(input.email)
store.insert(users, userData)
notify.email(welcome)The flow is the contract:
- Non-developers read and approve the intent
- AI writes implementation code
- FlowScript verifies code matches the flow
- What was specified is what gets built—enforced, not hoped
How It Works
┌─────────────────────────────────────────────────────────────────┐
│ 1. AI writes a FLOW (the spec) │
│ Plain English: validate → store → notify │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. Non-devs VERIFY the intent │
│ "Yes, that's what I want" │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 3. AI writes IMPLEMENTATION code │
│ The actual TypeScript/Python/etc. │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 4. FlowScript VERIFIES code matches flow │
│ Implementation must match spec—enforced │
└─────────────────────────────────────────────────────────────────┘Installation
npm install @actionable/flowscriptQuick Start
user-registration.flow (AI generates this - human readable)
@flow("User Registration")
validate.email(input.email)
store.insert(users, { email: input.email, name: input.name })
notify.email(input.email, "Welcome!")register.ts (AI generates this - implementation)
async function registerUser(input: { email: string; name: string }) {
await validateEmail(input.email);
await db.insert('users', { email: input.email, name: input.name });
await email.send(input.email, 'Welcome!');
}verify.ts (FlowScript verifies they match)
import { parseFlow, verifyCode } from '@actionable/flowscript';
const flow = parseFlow(fs.readFileSync('user-registration.flow', 'utf-8'));
const code = fs.readFileSync('register.ts', 'utf-8');
const result = verifyCode(flow, code);
console.log(result.matches); // true
console.log(result.coverage); // 100%The Flow Language
Flows use standardized verbs that make intent clear:
Core Effects
| Category | Effects | Meaning |
|----------|---------|---------|
| validate | email, format, range, auth | Check/verify something |
| transform | hash, encrypt, parse, format | Convert data |
| store | insert, update, delete, query | Database operations |
| fetch | get, post, call | External API calls |
| notify | email, sms, push, webhook | Send notifications |
| auth | login, logout, token | Authentication |
| pay | charge, refund, subscribe | Payments |
Web3 Effects
| Category | Effects | Meaning |
|----------|---------|---------|
| wallet | connect, sign, balance | Wallet operations |
| token | transfer, approve, swap | Token operations |
| contract | read, write, deploy | Smart contracts |
| chain | tx, wait, gas | Blockchain state |
Examples
DeFi Token Swap
Flow (what you approve):
@flow("Token Swap")
wallet.connect()
token.approve(USDC, amount)
defi.swap(ETH, USDC, amount)
chain.wait(txHash)Anyone can read this: connect wallet → approve token → swap → wait.
Implementation (verified against flow):
await wallet.connect();
await usdc.approve(routerAddress, amount);
await router.swapExactTokensForTokens(amount, minOut, [ETH, USDC], address, deadline);
await provider.waitForTransaction(txHash);Payment Processing
Flow:
@flow("Process Payment")
validate.card(cardNumber)
pay.charge(amount, cardToken)
store.insert(transactions, { amount, status: "complete" })
notify.email(customerEmail, "Receipt")Verification ensures the implementation does exactly these steps—no more, no less.
Advanced Patterns
Parallel Execution
@flow("Parallel Notifications")
parallel:
notify.email(user.email, message)
notify.sms(user.phone, message)
notify.push(user.deviceId, message)Conditionals
@flow("Conditional Discount")
validate.membership(user.id) -> isMember
if isMember:
transform.apply(discount: 20%)
else:
transform.apply(discount: 0%)
pay.charge(finalAmount)Error Handling
@flow("Safe Payment")
try:
pay.charge(amount)
notify.email(receipt)
catch PaymentFailed:
notify.email(failureNotice)
store.insert(failedPayments, details)Runtime Tracing
FlowScript can also trace execution in real-time:
import { createTracer } from '@actionable/flowscript';
// Trace in dry-run mode (safe, nothing executes)
const tracer = createTracer();
const result = await tracer.run(code, services);
console.log(result.trace);
// [
// { effect: 'validate.email', disposition: 'simulated' },
// { effect: 'store.insert', disposition: 'simulated' },
// { effect: 'notify.email', disposition: 'simulated' }
// ]
// Or trace live execution
const liveTracer = createTracer({ execute: true });
const liveResult = await liveTracer.run(code, services);Why FlowScript?
| Without FlowScript | With FlowScript | |---------------------|------------| | Code is the only artifact | Flow (spec) + Code (implementation) | | Non-devs can't verify | Anyone can read the flow | | Trust AI got it right | Verify code matches spec | | Intent lost in syntax | Intent IS the contract |
Roadmap
- [x] Flow language specification
- [x] Parser with advanced patterns
- [x] Effect vocabulary (Web2 + Web3)
- [x] Static verification (flow vs code)
- [x] Runtime tracing
- [ ] VS Code extension
- [ ] Visual flow editor
- [ ] AI prompt templates
License
MIT
