Workflow API
defineWorkflow, the workflow context, step, hitl, the VFS, and time.
A workflow is a TypeScript module that export defaults { schema, main }.
Most of the API is global — no imports — while the typed authoring entry is
importable from the virtual tide module. Type definitions live in
runtime/src/tide.d.ts.
The workflow shape
const schema = S.object({ name: S.text() });
export default {
schema, // built with S — validates input
main: async (ctx: Infer<typeof schema>) => {
// ctx is the validated, defaulted input
},
};defineWorkflow
defineWorkflow is typed sugar over { schema, main }: it gives the body a
discoverable ctx and (optionally) a typed Argon client. It returns
{ schema, main }, so the module still export defaults its result.
import { defineWorkflow, S } from "tide";
export default defineWorkflow({
argon: sdk, // optional: the generated typed Argon SDK
input: S.object({ ... }), // optional: defaults to S.object({})
async run(input, ctx) { // input typed via Infer<typeof input>
// ...
},
});The workflow context (ctx)
| Field | What it is |
|---|---|
argon | The typed, in-process, journaled Argon client — present and typed only when an argon SDK was passed. See Driving Argon. |
step | Journaled, replayable step runner. |
hitl | Human-in-the-loop wait (hitl.wait(...)). |
llm | Large-language-model calls (ai.llm). |
ai | The full ai.* surface (llm, agent, tool, code). |
log, sleep, readFile, writeFile, readFileBytes, writeFileBytes, removeFile, listFiles | The sandbox capabilities. |
The same capabilities are available as globals in the core { schema, main }
form.
step
step<T>(name: string, fn: () => Promise<T>, opts?: { retries?: number }): Promise<T>Runs fn as an atomic, journaled transaction. On success its return value is
recorded; on replay a completed step returns that value without re-running the
body. On failure the step's buffered operations and VFS changes are rolled back.
With { retries: n } the body is retried up to n times before the error
propagates. Nested steps are not supported. See Steps.
const result = await step("charge", async () => {
await writeFile("receipt.txt", "charged");
return { ok: true };
}, { retries: 3 });hitl
hitl.wait(request: HitlWaitRequest): Promise<HumanWaitOutcome>Suspends the run for a human decision; resumes via tide resume. request
requires a title; description, tags, priority, payload,
classification, moduleName, and others are optional. The returned outcome
carries action, payload, comment, resolvedBy, and resolvedAt. See
Human-in-the-loop.
Virtual file system
All file operations run against an in-memory, sandboxed VFS — never the host filesystem. State is derived from journal replay.
| Function | Description |
|---|---|
readFile(path): Promise<string> | Read a text file. |
writeFile(path, contents): Promise<void> | Write a text file. |
readFileBytes(path): Promise<Uint8Array> | Read a binary file. |
writeFileBytes(path, data): Promise<void> | Write a Uint8Array. |
removeFile(path): Promise<void> | Delete a file. |
listFiles(path?): Promise<{ name, isFile }[]> | List directory entries. |
Console and logging
log(...) and console.log(...) write to stdout; console.error(...) to
stderr. Output is journaled and replayed deterministically — live logging during
replay is suppressed to avoid duplicates. Changing log messages does not
break determinism.
Time and sleep
sleep(ms: number): Promise<void>sleep pauses on first run and is skipped on replay. Date.now() and
new Date() return a frozen timestamp captured on first run and replayed
thereafter; performance.now() returns 0. See
Deterministic time.
AI capabilities
ai.llm.generate(model, prompt, options?) returns text, or a typed object when
an outputSchema (built with S) is supplied. ai.agent(...) runs a stateful
ReAct tool loop, ai.tool(...) declares a tool, and ai.code.* drives cloud
coding agents. These require the host to be configured with the relevant
credentials; in the disabled default posture they refuse deterministically. Full
signatures are in runtime/src/tide.d.ts.
The tide module exports
Most APIs are global; the importable surface is:
| Import | Description |
|---|---|
import { defineWorkflow } from "tide" | Typed authoring entry. |
import { connectArgon } from "tide" | Bind the generated Argon SDK to the journaled client (for tide test files). |
import { S, step, log, sleep, hitl, ai, readFile, … } from "tide" | The globals, importable when you prefer explicit imports. |
import { describe, test, it, assert, expect } from "tide:test" | The test harness. |
Related
- Schema (S) reference — the input builder and
Infer. - state.* API — the untyped world-state surface.
- Steps · Human-in-the-loop · Driving Argon.