Skip to content
Thyme Docs

thyme new

Create a new task inside the current Thyme project. new generates a functions/<task>/ directory with a defineTask template and the local files you need to run and test it.

Usage

thyme new [task]

If you omit task, the CLI prompts for the name interactively. Without a terminal the name is required as an argument — see CI & Non-Interactive Use.

Task name rules

Task names are validated by validateTaskName:

  • lowercase alphanumeric characters plus hyphens,
  • at most 64 characters,
  • no path traversal (.., /, or \),
  • not a reserved name: node_modules, dist, build, src, lib.

What it creates

functions/my-task/
├── index.ts          # defineTask template
├── args.json         # sample ctx.args for `thyme run`
├── storage.json      # ctx.storage seed ({})
└── .env.example      # secret template (MY_API_KEY=)
FilePurpose
index.tsThe task module — a defineTask template you edit.
args.jsonLocal test args injected as ctx.args (seeded with a sample targetAddress; replace it with your intended target).
storage.jsonThe ctx.storage seed; starts as {}. Written back only with --persist.
.env.exampleTemplate for per-task secrets (MY_API_KEY=); copy to .env and fill in.

The generated index.ts includes commented examples; its active behavior is equivalent to:

functions/my-task/index.ts
import { defineTask, z } from '@thyme-labs/sdk'
 
export default defineTask({
  schema: z.object({
    targetAddress: z.address(),
  }),
  async run(ctx) {
    const { targetAddress } = ctx.args
    ctx.logger.info(`Processing ${targetAddress}`)
 
    return {
      canExec: false,
      message: 'Task template is not configured yet',
    }
  },
})

The generated task starts inert and returns canExec: false. When you implement an action, encode the intended calldata with viem and return call descriptors. Empty calldata is not a guaranteed no-op.

Examples

Create a task by name:

thyme new price-oracle

Create one interactively:

thyme new

Behavior notes

Next steps