> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automate.ax/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Automate.ax automations are TypeScript programs.
> Use Bun for installation and command examples.
> Use Automate.ax for the product name and automate.ax for the package, CLI, and domain.
> Treat documented public APIs as current; do not invent transitional or deprecated names.

# Signals

> Compose typed values and dependencies before runtime data exists.

A `Signal<T>` is a typed reference to a value that will materialize during
execution. Triggers and actions return signals immediately while Automate.ax
obtains their concrete values later.

Signals are not promises. Do not `await` them.

## Access properties

Property access creates another signal:

```ts theme={null}
const email = onNewEmail()
const messageId = email.messageId // Signal<string>
const subjectLength = email.subject.length // Signal<number>
```

This is shorthand for deriving those properties after `email` materializes.
Chained access works across objects and primitive properties.

## Transform values

Use `.transform()` for calculations that need the concrete value:

```ts theme={null}
const email = onNewEmail()
const normalizedSubject = email.subject.transform((subject) =>
  subject.trim().toLowerCase(),
)

log({ value: normalizedSubject })
```

Transform functions are pure computations. Automate.ax records their input
signals during composition and invokes them only after those values are
available.

Use the top-level `transform` function when one result depends on several
signals:

```ts theme={null}
const summary = transform(
  [email.from, email.subject],
  (from, subject) => `${from?.address ?? "unknown"}: ${subject}`,
)
```

## Interpolate strings

Use the `t` tagged template to combine text and signals without resolving them
early:

```ts theme={null}
const responseSubject = t`Re: ${email.subject}`

sendEmail({
  to: "person@example.com",
  subject: responseSubject,
  text: "We received your message.",
})
```

The result is a `Signal<string>` that depends only on the signals interpolated
into the template.

## Connect actions

Every action input accepts either its ordinary TypeScript value or a compatible
signal. Passing a signal creates a durable dependency:

```ts theme={null}
const matches = searchMessages({ query: "is:unread", limit: 25 })

markAsRead({
  messageIds: matches.transform((messages) =>
    messages.map((message) => message.messageId),
  ),
})
```

`markAsRead` becomes ready only after the search succeeds and its transform
produces the message IDs.

## Execution order

Signal dependencies—not line order—control readiness.

```ts theme={null}
const starred = star({ messageIds: email.messageId })
const labeled = addLabel({ label: "Processed", messageIds: email.messageId })

archive({ messageIds: labeled })
```

`star` and `addLabel` can execute independently. `archive` waits for `addLabel`
because it consumes `labeled`; it does not wait for `star`.

## Conditional paths

Use `filter` to keep a value only when it matches a predicate, or `branch` when
two different sections should depend on a boolean signal:

```ts theme={null}
const urgent = email.subject.transform((subject) => subject.includes("URGENT"))

branch(urgent, () => {
  markAsImportant({ messageIds: email.messageId })
})
```

Automate.ax still traverses the code deterministically, but only the selected
signal path materializes during execution.

## Closure and failure

A signal can emit a value, close without one, or fail. Ordinary dependent
signals and actions propagate closure or failure instead of executing with a
missing value. The `closed(signal)` and `failed(signal)` helpers expose those
outcomes when an automation needs an explicit recovery path.

<Note>
  Generic JavaScript methods reached through signal property access can lose
  precise generic inference. Use `.transform()` when TypeScript reports an
  imprecise result such as `Signal<unknown[]>`.
</Note>
