Trigger API Reference

Reference for repository trigger descriptors, event envelopes, condition matching, retry controls, and declarative app-tool actions.

Repository triggers use the generated ansight/triggers/ansight-trigger.d.ts contract. The copy generated by your installed CLI is authoritative for that version. The linked source and this guide provide an online reference.

Module shape

Every trigger exports a JSON-compatible descriptor and one default function:

import type {
  TriggerContext,
  TriggerDefinition
} from "./ansight-trigger.d.ts";

type Payload = {
  priority: string;
  message?: string;
};

export const trigger = {
  schemaVersion: 1,
  eventKind: "session.log.received",
  conditions: [
    {
      field: "payload.priority",
      operator: "equals",
      value: "Error"
    }
  ]
} satisfies TriggerDefinition<"session.log.received">;

export default function run({ event, app }: TriggerContext<Payload>) {
  return app.artifacts.request({
    providerId: "example.diagnostics",
    artifactId: "state",
    arguments: { message: event.payload.message ?? "" }
  });
}

The function returns nothing or exactly one declarative action. Version 1 supports app-tool actions; version 2 also supports host evidence actions. The function does not execute the action itself.

TriggerDefinition<TEventKind>

FieldTypeRequiredContract
schemaVersion1 | 2NoDefaults to version 1, which requires an SDK app-tool provider. Use version 2 for host evidence actions and capability requirements.
requires{ capabilities?: string[]; appTools?: string[] }NoVersion 2 only: refuse execution when a required capability or executable app tool is unavailable.
enabledbooleanNoDefaults to true. Disabled triggers remain discoverable but never match events.
appIdstringSometimesOptional when the repository has a registered app scope; otherwise required.
eventKindEventKindYesExact normalized event kind.
eventSchemaJsonSchemaNoDescribes event.payload; version 1 does not use it for matching.
functionTimeoutMsnumberNoTypeScript function bound: 10–1,000 ms; default 100.
actionTimeoutSecondsnumberNoSeparate app action bound: 1–300 seconds; default 30.
retryRetryPolicyNoHost-owned policy with 1–5 total attempts.
conditionsCondition[]NoAt most 16 conditions evaluated by the CLI; every condition must pass.

The descriptor is extracted without importing the module. Keep it a static object literal without variables, functions, spreads, or computed values.

TriggerContext<TPayload, TEventKind>

PropertyTypeMeaning
runReadonly<TriggerRun>Host-owned identity, attempt number, queue time, and effective limits.
eventReadonly<EventEnvelope<TPayload, TEventKind>>Immutable normalized event that matched.
appAppContextFactories for the one optional app-tool action.
ansightHost evidence contextCapability snapshot and factories for screenshot, file capture, and annotation actions.

Host evidence actions without the SDK

Version 2 triggers can return one of these host-owned actions:

FactoryWhen to return it
ansight.screenshots.capture(args?)Preserve the screen at the matched event, such as a failure log. Declare ui.screenshot; the session must still have a live capture provider when the action runs.
ansight.files.capture({ root?, path, maximumBytes? })Copy a known app-sandbox file into retained session evidence. Declare files.capture; choose a root-relative path and a bounded maximum size.
ansight.annotations.create(args)Mark the event’s time or screenshot with a short explanation when the existing evidence needs review context.

Declare requirements in the trigger descriptor. ansight.capabilities is the snapshot supplied to that invocation, with mode, app availability, and provider details; it is not the task API’s asynchronous snapshot() method. SDK app actions remain unavailable without an SDK provider. Missing capabilities are reported as capability_unavailable with no retry.

See the native-log trigger example for android-logcat and apple-unified-log conditions. Host capture actions still require their provider to be available when the action runs; a finalized session cannot supply a new live screenshot or sandbox read.

TriggerRun

PropertyTypeMeaning
runIdstringStable across retry attempts.
triggerIdstringRepository-relative trigger ID.
repositoryRootPathstringAbsolute connected repository root.
enqueuedAtUtcstringISO-8601 queue timestamp.
functionTimeoutMsnumberEffective TypeScript function bound.
actionTimeoutSecondsnumberEffective returned-action bound.
attemptNumbernumberOne-based current attempt.
maximumAttemptsnumberTotal attempts permitted.

EventEnvelope<TPayload, TEventKind>

PropertyTypeMeaning
eventIdstringStable source-event identity.
kindTEventKindNormalized event kind.
occurredAtUtcstringISO-8601 occurrence time.
appIdstringApp scope used for matching.
sessionIdstring | nullLive or captured session when present.
correlationIdstringPropagated into a returned app action.
causationIdstring | nullOptional causing event or operation.
payloadTPayloadEvent-specific normalized data.

EventKind

Each event links to its timing, payload, and usage guidance.

FamilyValues
Applicationapp.event, app.lifecycle.changed
Pairingapp.pairing.discoveryReceived, app.pairing.accepted, app.pairing.rejected, app.pairing.unknown
Capture lifecyclesession.capture.started, session.capture.updated, session.capture.stopped, session.capture.finalized, session.capture.unknown
Session transfersession.transfer.telemetry, session.transfer.log, session.transfer.appEvent, session.transfer.appProfile, session.transfer.screenshot, session.transfer.visualTree, session.transfer.touchInput, session.transfer.annotatedFeedback, session.transfer.unknown
Captured logssession.log.received
Trendstrends.check.failed, trends.regression.detected, trends.regression.recovered, trends.unknown

Condition

The CLI evaluates conditions before running the trigger.

interface Condition {
  field: ConditionField;
  operator: ConditionOperator;
  value?: unknown;
  ignoreCase?: boolean;
}

Top-level field values are eventId, kind, occurredAtUtc, appId, sessionId, correlationId, and causationId. Nested payload fields use payload.<path>.

OperatorNeeds valueBehavior
equalsYesExact equality.
notEqualsYesExact inequality.
containsYesString or supported collection containment.
startsWithYesString prefix.
endsWithYesString suffix.
existsNoField is present.
notExistsNoField is absent.

ignoreCase enables ordinal case-insensitive string comparison. Every condition must pass; there is no executable predicate or OR group in contract version 1.

RetryPolicy

FieldRangeDefault
maxAttempts1–5, including the first1
initialDelayMs10–60,000 ms250 when retries are enabled
backoffMultiplier1–102
maxDelayMsAt least the initial delay; at most 60,000 msEight times initial delay, capped at 60,000

Only failed and timed-out attempts retry. Each attempt runs the handler again and keeps the same run, event, and correlation identity.

app: action factories

These methods return an AppToolAction; they do not return a promise and do not call the app inside TypeScript. Return one action from the function so the CLI can validate, authorize, audit, and dispatch it.

NamespaceMethods
app.artifactsquery(args?), request(args)
app.uigetVisualTree(args?), getScreenshot(args?), inspectNode(args?), showOverlay(args?), getOverlay(args?), queryOverlays(args?), updateOverlay(args?), removeOverlay(args?), clearOverlays(args?)
app.fileslistDirectory(args?), readFile(args?), getChecksum(args?), download(args?), beginBinaryDownload(args?), push(args?), copy(args?), move(args?), delete(args?)
app.fileDescriptorslistOpen(args?), countOpen(args?), inspect(args?), getUsage(args?)
app.jniReferencescaptureGraph(args?)
app.preferenceslistKeys(args?), get(args?), set(args?), remove(args?)
app.clipboardgetText(), hasText(), setText(args), clear()
app.secureStorageget(args?), set(args?), remove(args?)
app.datalistDatabases(args?), describeSchema(args?), query(args?)
app.reflectionlistRoots(args?), inspectObject(args?), describeType(args?), setMemberValue(args?), invokeMethod(args?)
app.mauigetCurrentPage(args?), getVisualTree(args?), findElements(args?), getElement(args?), getBindableProperty(args?), setBindableProperty(args?), clearBindableProperty(args?), inflateXaml(args?), addElement(args?), removeElement(args?), setAppTheme(args?), getBindingContext(args?), getBindings(args?), getResourceState(args?), getNavigationState(args?), invokeElementAction(args?), waitForUi(args?), getLayoutDiagnostics(args?), getHandlerDiagnostics(args?), invokeBindingContextCommand(args?), setBindingContextProperty(args?)
app.reactgetComponentTree(args?), getShadowTree(args?), findComponents(args?), getComponent(args?), getNavigationState(args?), invokeComponentAction(args?)
app.fluttergetWidgetTree(args?), inspectWidget(args?), findWidgets(args?), getNavigationState(args?)
app.capacitorgetDocument(args?), inspectNode(args?), querySelector(args?), invokeAction(args?)
appcallTool(toolId, args?) for an app-defined tool

Clipboard factories return declarative actions backed by the native Clipboard suite. Reads require Read policy; set and clear require Write policy. See Clipboard Tools for registration, limits, and platform behavior.

The App Tool API explains what each method does. In a trigger, return one factory result; the host executes it after the function returns.

Returning app.files.beginBinaryDownload({ root, path }) streams the selected sandboxed file to the host. After the binary transfer completes, the host retains the file as an artifact on the originating session.

AppToolAction<TArguments>

Every factory produces the same declarative shape:

interface AppToolAction<TArguments extends AppToolArguments> {
  type: "appTool";
  toolId: string;
  arguments: TArguments;
}

The host preserves the matched event’s session and correlation identity. The action is rejected if no live session is available, the tool is absent, its arguments are invalid, or the app’s guard denies it.

Return contract

type TriggerFunction<TPayload, TEventKind> = (
  invocation: TriggerContext<TPayload, TEventKind>
) =>
  | AppToolAction
  | null
  | void
  | Promise<AppToolAction | null | void>;

Return null or nothing for a match that needs local computation only. A trigger cannot execute host-owned UI APIs, dispatch multiple app actions, register new event sources, or supply an executable predicate.

Execution rules

  • The exact App ID, event kind, and every condition are matched before the trigger runs.
  • The function timeout and action timeout are separate.
  • Repository trigger code is trusted local code, not a filesystem or network sandbox.
  • App actions retain the connected app’s grants and critical-tool policy.
  • Trigger catalogs must be explicitly connected before they receive events.
  • A repository can define up to 256 triggers; each module is limited to 1 MiB.