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:
| File | Derived ID |
|---|---|
ansight/tests/onboarding/complete.json | onboarding.complete |
ansight/tasks/map/validate-areas.ts | map.validate-areas |
ansight/triggers/diagnostics/capture-errors.ts | diagnostics.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/testscontains agentic JSON scenarios.ansight/taskscontains explicitly invoked deterministic modules.ansight/triggerscontains 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 listoransight repo automation inspectafter scripted changes.
Optional checked-in schemas can support repository-specific validation, but the running Ansight host remains the source of truth.
Common problems
| Symptom | Check |
|---|---|
| Definition is missing | Confirm its directory, extension, path-derived ID, size, and required descriptor/export. |
VS Code shows any for function parameters | Type the invocation with TaskInvocation or TriggerContext and verify the declaration import path. |
| Types cannot be resolved | Confirm the declaration is beside the module tree and included by tsconfig.json, or that the package dependency is installed. |
| Test validation fails | Keep appId, prompt, and validation non-empty; make every assertion a non-empty string. |
Task is Inconclusive | Record at least one passing named check assertion. |
Task is Rejected | Check any explicit hostTools entry, exact tool name, live session, serialized calls, tool guards, and action limit. |
| Trigger never records a run | Check connection state, App ID, exact event kind, every ANDed condition, and queue admission. |
| Updated code is not used | Refresh workspace discovery or reconnect triggers; changes are not hot-reloaded. |