Examples
Walkthrough workflows for common patterns.
These examples live under examples/ in the repository and run directly with
tide run. Each one is small and self-contained.
Hello world
examples/hello-world/main.ts — write a file, read it back, clean up, sleep.
const schema = S.object({});
export default {
schema,
main: async (_ctx: Infer<typeof schema>) => {
log("Hello from Tide!");
await writeFile("test_output.txt", "Tide runtime wrote this file.");
const contents = await readFile("test_output.txt");
log("Read back:", contents);
await removeFile("test_output.txt");
log("Cleaned up.");
await sleep(100);
log("Sleep completed!");
},
};Demonstrates the empty schema (S.object({}) needs no input), the VFS
(writeFile / readFile / removeFile), journaled log, and sleep (which is
skipped on replay).
tide run examples/hello-world/main.ts -i hello-001 # first run
tide run examples/hello-world/main.ts -i hello-001 # replay — sleep is skippedTyped input
examples/input-schema/main.ts — required, optional, defaulted, and nested
fields, plus a step.
const schema = S.object({
name: S.text(),
count: S.integer(),
priority: S.default(S.enum(["low", "medium", "high"]), "medium"),
tags: S.optional(S.list(S.text())),
config: S.object({
retries: S.default(S.integer(), 3),
verbose: S.optional(S.boolean()),
}),
});
export default {
schema,
main: async (ctx: Infer<typeof schema>) => {
log("Processing:", ctx.name, "priority:", ctx.priority);
if (ctx.tags) log("Tags:", ctx.tags.join(", "));
log("retries:", ctx.config.retries);
await writeFile("result.txt", `Processed ${ctx.count} items for ${ctx.name}`);
const result = await step("process", async () => {
return { processed: ctx.count, name: ctx.name };
});
log("Step result:", JSON.stringify(result));
},
};priority and config.retries are defaulted, so callers may omit them and
main still sees a value.
tide run examples/input-schema/main.ts \
--input '{"name":"widgets","count":5}'Validation reports every error at once with a JSON-path:
tide run examples/input-schema/main.ts --input '{"name":123}'
# Input validation failed:
# $.name: expected Text string, got number 123
# $.count: required but missing
# $.config: required but missingSee Schema (S) reference for the full builder.
Steps
examples/step-test/main.ts — atomic file writes, chained steps, sleep
inside a step.
const result = await step("write-files", async () => {
await writeFile("hello.txt", "Hello from step!");
await writeFile("world.txt", "World from step!");
return { hello: await readFile("hello.txt"), world: await readFile("world.txt") };
});
// Files written inside a committed step persist outside it.
const hello = await readFile("hello.txt");
const count = await step("count-files", async () => {
return { fileCount: 2 };
});
await step("timed-step", async () => {
await sleep(500);
return "done";
});Multiple writes inside a step commit atomically; a later step reads what an earlier one wrote. See Steps.
tide run examples/step-test/main.ts -i step-001
tide run examples/step-test/main.ts -i step-001 # replay — steps return stored resultsHuman-in-the-loop
examples/wait-for-human/main.ts — suspend for a human decision.
const schema = S.object({ documentId: S.text() });
export default {
schema,
main: async (ctx: Infer<typeof schema>) => {
const decision = await hitl.wait({
title: `Review extracted evidence for ${ctx.documentId}`,
priority: "high",
moduleName: "evidence_review",
payload: { summary: "", review_notes: "" },
});
log("Human action:", decision.action);
await writeFile("human-decision.json", JSON.stringify(decision, null, 2));
},
};tide run examples/wait-for-human/main.ts -i review-1 --input '{"documentId":"doc-42"}'
# suspends; then:
tide resume review-1 examples/wait-for-human/main.ts --action approvedSee Human-in-the-loop.
LLM generate
examples/ai-generate/main.ts — text and structured output from ai.llm.
const verdictSchema = S.object({
decision: S.enum(["approved", "denied", "needs_review"]),
riskScore: S.nat(),
reason: S.optional(S.text()),
});
// Structured object out, typed via Infer<typeof verdictSchema>.
const verdict = await ai.llm.generate("gpt-5.4", [
{ role: "system", content: "You are a strict approver." },
{ role: "user", content: `Should we pay this invoice? ${ctx.invoiceText}` },
], { outputSchema: verdictSchema });
log("decision:", verdict.decision); // "approved" | "denied" | "needs_review"ai.* requires the host to be configured with provider credentials; the same
S builder describes both input and structured output.
Driving an ontology
examples/employment-onboarding/ — a full Argon project: tide run builds
the ontology and drives it through the typed ctx.argon client. See
Driving Argon for the walkthrough.
Related
- Your first workflow — guided setup.
- Steps · Human-in-the-loop · Driving Argon.
- Schema (S) reference · CLI reference.