Authoring and Validation

Initialize an Ansight test workspace, derive stable IDs, enable TypeScript completion and checking, validate definitions, and refresh Studio discovery safely.

CLI v0.23.1

Tests, tasks, and triggers are ordinary files committed to source control, often with the app source. Ansight provides workspace scaffolding, versioned schemas, editor declarations, Studio authoring and focused CLI validation around those files.

Initialize the workspace

Run initialization from the directory that will own the workspace:

ansight workspace init .

In an interactive terminal, initialization asks for the App ID to register with this workspace. Registering enables automatic flow, quality, and trend analysis after every finalized session for that app. Leave the prompt blank or pass --no-register to skip it. For scripts and CI, register without a prompt:

ansight workspace init . --app-id com.example.app

The command creates missing directories and support files:

ansight/
  package.json
  tasks/
    ansight-task.d.ts
    tsconfig.json
  tests/
  flows/
  quality/
  sanitizers/
    ansight-sanitizer.d.ts
    tsconfig.json
  triggers/
    ansight-automation.d.ts
    tsconfig.json
  schema/
    task-definition.v1.schema.json
    test-definition.v1.schema.json
    flow-definition.v1.schema.json
    quality-definition.v1.schema.json
    trigger-definition.v1.schema.json

Every listed directory also receives an editable README.md with a plain-language guide, a starter example, and the important constraints for that definition type.

Initialization is idempotent. Customized support files are preserved. Use --force only when you intend to replace them with the canonical files from the installed Ansight host.

The generated package.json sets "type": "module", so plain .ts files use ES module semantics under both Node and TypeScript’s NodeNext resolution.

Create individual definitions with:

ansight workspace add test . <id> --app-id <app-id>
ansight workspace add task . <id> --app-id <app-id>
ansight workspace add trigger . <id> --app-id <app-id>

Use ansight app list to find App IDs known to the host. Existing definition files fail safely unless --force is supplied.

IDs and paths

Definition IDs come from paths beneath their respective directories:

FileDerived ID
ansight/tests/onboarding/complete.jsononboarding.complete
ansight/tasks/map/validate-areas.tsmap.validate-areas
ansight/triggers/diagnostics/capture-errors.tsdiagnostics.capture-errors

CLI-created test and task IDs can contain letters, numbers, dots, hyphens, and underscores and are limited to 160 characters. Trigger IDs use the same characters and are limited to 120 characters. Start and end a CLI-created ID with a letter or number and avoid consecutive dots.

Prefer stable, domain-oriented IDs. Renaming or moving a definition changes its path-derived identity and can break prompts, scripts, or saved references.

Author in Studio

Studio’s Test workspace groups the definitions by detected app:

  • ansight/tests contains agentic JSON scenarios.
  • ansight/tasks contains explicitly invoked deterministic modules.
  • ansight/triggers contains event-driven modules.

Select a workspace app, create or open a definition, use the contextual snippets, and save it beneath the indicated directory. Studio validates test JSON and the static task or trigger module shape before saving. Repository tasks can also be saved and tested against an exact open simulator session from this editor.

Tests may reference qualityChecks in the current schema. Definitions beneath ansight/flows turn stable SDK event labels into reusable semantic time windows; ansight/quality applies deterministic telemetry expectations to those windows and can add a trend policy directly to measurements that need historical monitoring. This co-locates authoring without combining behavior: quality and trend evaluation remain distinct host operations after the functional test, not part of the model prompt. Complete login-FPS and memory-flattening examples live in examples/workspace-tests. Versioned sessions make one release comparison against a pinned earlier version; unversioned sessions use a fixed reference formed from their earliest comparable runs.

The host also monitors ordinary sessions automatically after an app is linked to its trusted codebase with ansight app register <app-id> --codebase <path>. On session finalization it evaluates matching definitions for flows observed in that session. The served local explorer’s Trends view browses current and baseline values across registered apps and app versions.

For a full TypeScript editing experience, open the repository in an external editor such as Visual Studio Code.

Static task and trigger descriptors

Every task and trigger module contains one statically extractable descriptor:

export const task = {
  "schemaVersion": 1,
  "title": "Verify home",
  "description": "Checks the signed-in home state."
};
export const trigger = {
  "schemaVersion": 1,
  "eventKind": "app.event"
};

Keep descriptors as JSON-compatible object literals with double-quoted keys and values. Do not use variables, spreads, functions, template substitutions, or computed properties inside a descriptor. Studio reads the descriptor without importing or executing the module.

An invalid task produces a warning while other valid tasks remain discoverable. An invalid trigger rejects that repository’s trigger catalog, so validate every trigger before connecting it.

Visual Studio Code completion and checking

VS Code provides completion and diagnostics through its built-in TypeScript language service. The generated tsconfig.json makes each module directory a strict, no-emit TypeScript project that matches Node’s native type-stripping limits:

{
  "compilerOptions": {
    "allowImportingTsExtensions": true,
    "erasableSyntaxOnly": true,
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "noEmit": true,
    "verbatimModuleSyntax": true,
    "target": "ES2022",
    "strict": true
  },
  "include": [
    "*.ts",
    "*.d.ts",
    "**/*.ts",
    "**/*.d.ts"
  ]
}

Import the canonical declaration with import type, constrain the descriptor with satisfies, and type the default function’s invocation parameter.

Task module:

import type { TaskDefinition, TaskInvocation } from "./ansight-task.d.ts";

type ValidateAreaInput = { area: string };

export const task = {
  "schemaVersion": 1,
  "title": "Validate area",
  "description": "Validates one named map area."
} satisfies TaskDefinition;

export default async function validateArea(
  { input, ansight, check }: TaskInvocation<ValidateAreaInput>
) {
  // VS Code completes input, ansight, and check here.
}

Trigger module:

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

type ErrorPayload = { message: string };

export const trigger = {
  "schemaVersion": 1,
  "eventKind": "session.log.received"
} satisfies TriggerDefinition;

export default async function captureError(
  { event, app }: TriggerContext<ErrorPayload>
) {
  // VS Code completes event and app here.
}

Adjust the import when the module is nested. For example, ansight/tasks/map/validate-area.ts normally imports ../ansight-task.d.ts.

If a file is not receiving project diagnostics, run TypeScript: Go to Project Configuration in VS Code and confirm that it resolves to the expected tsconfig.json. Restart the TypeScript language server after replacing a declaration file if its old shape remains cached.

Are the declaration files required at runtime?

No. Studio ignores .d.ts and tsconfig.json, and Node erases import type declarations. They exist only so editors and tsc can understand the authoring API.

The declarations must be resolvable somewhere for completion to work. The current workspace initializer copies them locally so .NET, Swift, Kotlin, Flutter, and other repositories get offline editor support without requiring a JavaScript package manager. A repository that supplies the same contract from a dependency can import that dependency instead and omit the local declaration copy.

The local declarations have one additional benefit: they come from the installed host and therefore match its exact contract. Keep dependency-provided contracts aligned with the Studio version that will load the modules.

ESLint is optional and separate

tsc catches type errors, invalid contract properties, implicit any, and incorrect function usage. ESLint adds rule-based checks such as unused variables and consistency rules.

For an npm-enabled repository, install ESLint and the VS Code ESLint extension:

npm install --save-dev eslint @eslint/js globals typescript-eslint

An eslint.config.mjs scoped to Ansight modules can start with:

import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";

export default tseslint.config(
  js.configs.recommended,
  ...tseslint.configs.recommended,
  {
    files: ["ansight/{tasks,triggers,sanitizers}/**/*.ts"],
    languageOptions: {
      globals: globals.node
    }
  }
);

ESLint is not required for Studio discovery or execution.

Validate locally and in CI

Validate test, flow, and quality definitions—including embedded trend policies—through the host contract:

ansight test validate .

Install TypeScript as a development dependency when the repository does not already provide tsc, then type-check all three projects:

npm install --save-dev typescript
npx tsc -p ansight/tasks/tsconfig.json
npx tsc -p ansight/triggers/tsconfig.json
npx tsc -p ansight/sanitizers/tsconfig.json

Inspect the host’s task and trigger catalogs without executing code:

ansight task list --app-id com.example.app --repository .
ansight repo automation inspect com.example.app .

TypeScript modules are stripped by Node at runtime; Studio does not type-check them before execution. Run the matching local or CI type check for .ts modules.

Refresh discovery

Contract version 1 does not watch repository files automatically.

  • Saving through Studio refreshes the selected workspace definitions.
  • After external edits, refresh or reopen workspace discovery.
  • Reconnect repository triggers after changing their definitions.
  • Re-run ansight task list or ansight repo automation inspect after scripted changes.

Optional checked-in schemas can support repository-specific validation, but the running Ansight host remains the source of truth.

Common problems

SymptomCheck
Definition is missingConfirm its directory, extension, path-derived ID, size, and required descriptor/export.
VS Code shows any for function parametersType the invocation with TaskInvocation or TriggerContext and verify the declaration import path.
Types cannot be resolvedConfirm the declaration is beside the module tree and included by tsconfig.json, or that the package dependency is installed.
Test validation failsKeep appId, prompt, and validation non-empty; make every assertion a non-empty string.
Task is InconclusiveRecord at least one passing named check assertion.
Task is RejectedCheck any explicit hostTools entry, exact tool name, live session, serialized calls, tool guards, and action limit.
Trigger never records a runCheck connection state, App ID, exact event kind, every ANDed condition, and queue admission.
Updated code is not usedRefresh workspace discovery or reconnect triggers; changes are not hot-reloaded.