prompttest-mobile 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CONTRIBUTING.md +80 -0
  2. package/LICENSE +42 -0
  3. package/LICENSES.md +81 -0
  4. package/README.md +526 -0
  5. package/SECURITY.md +56 -0
  6. package/TERMS.md +138 -0
  7. package/dist/bin/prompttest.d.ts +2 -0
  8. package/dist/bin/prompttest.js +1418 -0
  9. package/dist/bin/server.d.ts +1 -0
  10. package/dist/constants/commands.d.ts +125 -0
  11. package/dist/engine.bundle.js +1039 -0
  12. package/dist/index.d.ts +143 -0
  13. package/dist/index.js +1039 -0
  14. package/dist/lib/adaptive-timing.d.ts +55 -0
  15. package/dist/lib/adb-provisioner.d.ts +55 -0
  16. package/dist/lib/adb.d.ts +448 -0
  17. package/dist/lib/ai/heuristic-resolver.d.ts +19 -0
  18. package/dist/lib/ai/index.d.ts +16 -0
  19. package/dist/lib/ai/llm-provider.d.ts +40 -0
  20. package/dist/lib/ai/types.d.ts +64 -0
  21. package/dist/lib/baseline.d.ts +159 -0
  22. package/dist/lib/benchmark.d.ts +100 -0
  23. package/dist/lib/checkpoint.d.ts +61 -0
  24. package/dist/lib/ci.d.ts +49 -0
  25. package/dist/lib/config-loader.d.ts +87 -0
  26. package/dist/lib/config.d.ts +136 -0
  27. package/dist/lib/crawler.d.ts +335 -0
  28. package/dist/lib/data-loader.d.ts +53 -0
  29. package/dist/lib/dfs-engine.d.ts +149 -0
  30. package/dist/lib/dictionary.d.ts +41 -0
  31. package/dist/lib/doctor.d.ts +45 -0
  32. package/dist/lib/driver-interface.d.ts +50 -0
  33. package/dist/lib/enterprise.d.ts +71 -0
  34. package/dist/lib/errors.d.ts +68 -0
  35. package/dist/lib/explorer.d.ts +165 -0
  36. package/dist/lib/feedback.d.ts +35 -0
  37. package/dist/lib/form-filler.d.ts +101 -0
  38. package/dist/lib/ios-driver.d.ts +38 -0
  39. package/dist/lib/jail-guard.d.ts +59 -0
  40. package/dist/lib/license.d.ts +51 -0
  41. package/dist/lib/live-server.d.ts +52 -0
  42. package/dist/lib/lock.d.ts +30 -0
  43. package/dist/lib/logger.d.ts +68 -0
  44. package/dist/lib/memory.d.ts +259 -0
  45. package/dist/lib/patterns.d.ts +202 -0
  46. package/dist/lib/profiler.d.ts +75 -0
  47. package/dist/lib/prompt-runner.d.ts +101 -0
  48. package/dist/lib/quiescence.d.ts +44 -0
  49. package/dist/lib/recorder.d.ts +155 -0
  50. package/dist/lib/repl.d.ts +29 -0
  51. package/dist/lib/reporter.d.ts +269 -0
  52. package/dist/lib/runner-utils.d.ts +316 -0
  53. package/dist/lib/scaffold.d.ts +53 -0
  54. package/dist/lib/step-handlers.d.ts +390 -0
  55. package/dist/lib/triage.d.ts +50 -0
  56. package/dist/lib/wizard.d.ts +42 -0
  57. package/dist/lib/zip-util.d.ts +36 -0
  58. package/docs/ARCHITECTURE.md +154 -0
  59. package/docs/CLI_CONTRACT.md +131 -0
  60. package/docs/CLI_STUDIO_CONTRACT.md +123 -0
  61. package/docs/PERFORMANCE_BASELINE.md +71 -0
  62. package/docs/PRODUCT_STATUS.md +56 -0
  63. package/docs/USER_MANUAL.md +764 -0
  64. package/package.json +66 -0
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @module ai/types
3
+ * @description Core types and interfaces for the AI and Semantic Resolution layer.
4
+ */
5
+ import { UiNode } from '../crawler.js';
6
+ import { PromptStep } from '../prompt-runner.js';
7
+ /**
8
+ * Candidate element suggestion produced during locator self-healing.
9
+ */
10
+ export interface Suggestion {
11
+ /** The text or descriptor of the suggested element. */
12
+ text: string;
13
+ /** Confidence score between 0.0 and 1.0. */
14
+ score: number;
15
+ /** The matching UI node, if available in hierarchy. */
16
+ node?: UiNode;
17
+ /** The strategy that produced this suggestion. */
18
+ strategy: 'exact' | 'fuzzy' | 'synonym' | 'spatial' | 'llm';
19
+ /** Optional reasoning or explanation for the match. */
20
+ reason?: string;
21
+ }
22
+ /**
23
+ * Contextual metadata passed to semantic resolvers for informed decision-making.
24
+ */
25
+ export interface SemanticContext {
26
+ /** Target application package name. */
27
+ packageName?: string;
28
+ /** Current flattened screen hierarchy. */
29
+ screenHierarchy?: UiNode[];
30
+ /** Action being attempted (TAP, TYPE, VERIFY, etc.). */
31
+ action?: string;
32
+ /** Previous executed steps for intent chaining. */
33
+ previousSteps?: PromptStep[];
34
+ /** Live runtime variables. */
35
+ variables?: Map<string, string>;
36
+ /** Active language/locale for taxonomy matching. */
37
+ locale?: string;
38
+ }
39
+ /**
40
+ * Base interface for semantic intent and locator resolution.
41
+ */
42
+ export interface SemanticResolver {
43
+ /** Human-readable provider identifier (e.g. 'heuristic', 'openai', 'ollama', 'mock'). */
44
+ readonly providerName: string;
45
+ /**
46
+ * Expands a high-level natural language intent (e.g., "log in with default credentials")
47
+ * into an array of concrete, executable PromptSteps.
48
+ *
49
+ * @param intent - Natural language goal or user action.
50
+ * @param ctx - Contextual screen hierarchy and session state.
51
+ * @returns Array of expanded steps, or null if cannot be expanded.
52
+ */
53
+ resolveIntent(intent: string, ctx?: SemanticContext): Promise<PromptStep[] | null>;
54
+ /**
55
+ * Finds candidate elements matching a missing or outdated target locator
56
+ * to heal broken tests autonomously.
57
+ *
58
+ * @param missingTarget - Target locator that was not found on screen.
59
+ * @param flat - Current flattened list of visible UI nodes.
60
+ * @param ctx - Optional semantic context.
61
+ * @returns Ranked array of candidate suggestions.
62
+ */
63
+ findSuggestions(missingTarget: string, flat: UiNode[], ctx?: SemanticContext): Promise<Suggestion[]>;
64
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Rectangular region on the screen to ignore during visual comparison.
3
+ */
4
+ export interface MaskRegion {
5
+ /** The starting horizontal pixel coordinate or relative float (0.0 - 1.0). */
6
+ x: number;
7
+ /** The starting vertical pixel coordinate or relative float (0.0 - 1.0). */
8
+ y: number;
9
+ /** Width of the region in pixels or relative float (0.0 - 1.0). */
10
+ width: number;
11
+ /** Height of the region in pixels or relative float (0.0 - 1.0). */
12
+ height: number;
13
+ /** Optional human-readable label for the ignored region (e.g., 'Status Bar', 'Clock'). */
14
+ label?: string;
15
+ }
16
+ /**
17
+ * Predefined tolerance and sensitivity presets for visual comparison.
18
+ */
19
+ export type MatchingMode = 'strict' | 'moderate' | 'relaxed';
20
+ export declare const MATCHING_MODES: Record<MatchingMode, {
21
+ threshold: number;
22
+ pixelmatchThreshold: number;
23
+ label: string;
24
+ description: string;
25
+ }>;
26
+ /**
27
+ * Options for configuring visual baseline comparisons.
28
+ */
29
+ export interface BaselineCompareOptions {
30
+ /** Matching preset mode ('strict', 'moderate', 'relaxed'). Defaults to 'moderate'. */
31
+ mode?: MatchingMode;
32
+ /** Override the maximum allowed diffRatio (0.0 to 1.0) before failing. */
33
+ threshold?: number;
34
+ /** Array of bounding boxes to mask out (e.g. dynamic clocks, battery, animations). */
35
+ maskRegions?: MaskRegion[];
36
+ /** Perceptual color distance sensitivity for pixelmatch (0.0 to 1.0, default 0.1). */
37
+ pixelmatchThreshold?: number;
38
+ }
39
+ /**
40
+ * Represents the outcome of comparing a current screenshot against a saved baseline.
41
+ */
42
+ export interface BaselineDiffResult {
43
+ /** The descriptive name or index of the step being compared. */
44
+ stepName: string;
45
+ /** Absolute path to the reference baseline image. */
46
+ baselineFile: string;
47
+ /** Absolute path to the newly captured image that was compared. */
48
+ currentFile: string;
49
+ /** Fraction of pixels that differ (0.0 = identical, 1.0 = completely different). */
50
+ diffRatio: number;
51
+ /** Total count of mismatched pixels. */
52
+ diffPixels: number;
53
+ /** Total number of pixels compared. */
54
+ totalPixels: number;
55
+ /** True if the diffRatio is less than or equal to the defined threshold. */
56
+ passed: boolean;
57
+ /** The maximum allowed difference ratio used for this comparison. */
58
+ threshold: number;
59
+ /** Absolute path to the red-highlighted diff PNG image if differences were detected. */
60
+ diffImagePath?: string;
61
+ }
62
+ /**
63
+ * Manages storage, pixel-level diffing, and visual baseline artifacts for PromptTest.
64
+ */
65
+ export declare class BaselineManager {
66
+ private baselineDir;
67
+ /** Maximum allowed fraction of differing pixels before a comparison fails. */
68
+ private defaultThreshold;
69
+ /**
70
+ * Initializes the BaselineManager.
71
+ *
72
+ * @param baselineDir Directory path to store and retrieve baseline images. Defaults to './output/baselines'.
73
+ * @param threshold Default maximum difference ratio allowed (0.0 to 1.0). Defaults to 0.02 (2%).
74
+ */
75
+ constructor(baselineDir?: string, threshold?: number);
76
+ private filePath;
77
+ private diffFilePath;
78
+ private masksFilePath;
79
+ /**
80
+ * Retrieves saved mask regions for a specific test step.
81
+ *
82
+ * @param specName The name of the test specification.
83
+ * @param stepIndex The 0-based index of the step within the spec.
84
+ * @returns Array of MaskRegion bounding boxes.
85
+ */
86
+ getMasks(specName: string, stepIndex: number): Promise<MaskRegion[]>;
87
+ /**
88
+ * Persists mask regions to disk for a specific test step.
89
+ *
90
+ * @param specName The name of the test specification.
91
+ * @param stepIndex The 0-based index of the step within the spec.
92
+ * @param masks Array of MaskRegion bounding boxes.
93
+ * @returns The file path where masks were stored.
94
+ */
95
+ saveMasks(specName: string, stepIndex: number, masks: MaskRegion[]): Promise<string>;
96
+ /**
97
+ * Saves a new screenshot as the baseline reference for a specific test step.
98
+ * Uses an atomic write (via a temp file) to prevent partial writes.
99
+ *
100
+ * @param specName The name of the test specification.
101
+ * @param stepIndex The 0-based index of the step within the spec.
102
+ * @param screenshot The raw PNG image buffer.
103
+ * @returns A promise resolving to the file path where the baseline was saved.
104
+ */
105
+ saveBaseline(specName: string, stepIndex: number, screenshot: Buffer): Promise<string>;
106
+ /**
107
+ * Checks whether a baseline image already exists for a specific step.
108
+ *
109
+ * @param specName The name of the test specification.
110
+ * @param stepIndex The 0-based index of the step within the spec.
111
+ * @returns true if the baseline file exists, false otherwise.
112
+ */
113
+ hasBaseline(specName: string, stepIndex: number): boolean;
114
+ /**
115
+ * Compares a current screenshot buffer against the reference baseline using pixelmatch.
116
+ * If no baseline exists, current screenshot is automatically saved as the initial baseline.
117
+ *
118
+ * @param specName The name of the test specification.
119
+ * @param stepIndex The 0-based index of the step within the spec.
120
+ * @param currentScreenshot Raw PNG image buffer from the current run.
121
+ * @param optionsOrThreshold Optional threshold number or comparison options object.
122
+ * @returns A BaselineDiffResult detailing pixel match metrics and diff artifact path.
123
+ */
124
+ compare(specName: string, stepIndex: number, currentScreenshot: Buffer, optionsOrThreshold?: number | BaselineCompareOptions): Promise<BaselineDiffResult>;
125
+ /**
126
+ * Resizes an image onto a target canvas dimensions if dimensions differ.
127
+ */
128
+ private fitToCanvas;
129
+ /**
130
+ * Masks specified rectangular regions in-place by setting their RGBA values to 0.
131
+ * Supports both pixel coordinates and relative fractional coordinates (0.0 to 1.0).
132
+ */
133
+ private applyMasks;
134
+ /**
135
+ * Overwrites the golden baseline with the current screenshot or a provided buffer.
136
+ *
137
+ * @param specName The name of the test specification.
138
+ * @param stepIndex The 0-based index of the step within the spec.
139
+ * @param screenshot Optional replacement buffer; if omitted, copies current run screenshot.
140
+ */
141
+ approveBaseline(specName: string, stepIndex: number, screenshot?: Buffer): Promise<string>;
142
+ /**
143
+ * Deletes all saved baseline, current, and diff images for a given spec.
144
+ *
145
+ * @param specName The name of the test specification to clear baselines for.
146
+ */
147
+ clearBaselines(specName: string): Promise<void>;
148
+ /**
149
+ * Deletes all saved baseline, current, diff images, and masks for a single specific step.
150
+ *
151
+ * @param specName The name of the test specification.
152
+ * @param stepIndex The 1-based step index to delete.
153
+ */
154
+ deleteStepBaseline(specName: string, stepIndex: number): Promise<void>;
155
+ }
156
+ /**
157
+ * A globally accessible singleton instance of BaselineManager.
158
+ */
159
+ export declare const baselineManager: BaselineManager;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @module benchmark
3
+ * @description
4
+ * Performance benchmarking and diagnostic utilities for PromptTest.
5
+ * Measures latency and timing distributions (min, avg, p50, p95, max) for
6
+ * UI hierarchy dumping, screen captures, and fuzzy/spatial node matching.
7
+ */
8
+ import { AndroidDriver } from './adb.js';
9
+ import { UiNode } from './crawler.js';
10
+ /**
11
+ * Statistical latency metrics computed over a series of benchmark iterations.
12
+ */
13
+ export interface BenchmarkMetrics {
14
+ /** Minimum elapsed time in milliseconds */
15
+ minMs: number;
16
+ /** Maximum elapsed time in milliseconds */
17
+ maxMs: number;
18
+ /** Arithmetic average elapsed time in milliseconds */
19
+ avgMs: number;
20
+ /** 50th percentile (median) elapsed time in milliseconds */
21
+ p50Ms: number;
22
+ /** 95th percentile elapsed time in milliseconds */
23
+ p95Ms: number;
24
+ /** Number of recorded samples */
25
+ iterations: number;
26
+ /** Raw recorded durations in milliseconds */
27
+ durations: number[];
28
+ }
29
+ /**
30
+ * Complete benchmark report covering core device and engine operations.
31
+ */
32
+ export interface BenchmarkReport {
33
+ /** ISO 8601 timestamp when the benchmark was executed */
34
+ timestamp: string;
35
+ /** Device identifier or model tested */
36
+ device: string;
37
+ /** Target package tested, if specified */
38
+ package?: string;
39
+ /** Screen capture latency metrics */
40
+ screencap: BenchmarkMetrics;
41
+ /** UI hierarchy dump and parsing latency metrics */
42
+ uiHierarchy: BenchmarkMetrics;
43
+ /** Natural language node matching latency metrics on 1,000-node layout */
44
+ nodeMatching: BenchmarkMetrics;
45
+ /** Total elapsed time of the benchmark suite in milliseconds */
46
+ totalDurationMs: number;
47
+ }
48
+ /**
49
+ * Configuration options for running performance benchmarks.
50
+ */
51
+ export interface BenchmarkOptions {
52
+ /** Number of benchmark iterations per operation (default: 5) */
53
+ iterations?: number;
54
+ /** Target device serial number */
55
+ serial?: string;
56
+ /** Target application package name */
57
+ packageName?: string;
58
+ /** If true, executes against synthetic mock data even if device is present */
59
+ forceMock?: boolean;
60
+ }
61
+ /**
62
+ * Calculates a specific percentile (e.g. 50 for median, 95 for p95) from raw numbers.
63
+ *
64
+ * @param values - Array of numeric measurements.
65
+ * @param percentile - Target percentile in range [0, 100].
66
+ * @returns The calculated percentile value rounded to two decimal places.
67
+ */
68
+ export declare function calculatePercentile(values: number[], percentile: number): number;
69
+ /**
70
+ * Computes summary statistical metrics from an array of measured durations.
71
+ *
72
+ * @param durations - Array of measured durations in milliseconds.
73
+ * @returns Computed BenchmarkMetrics.
74
+ */
75
+ export declare function summarizeMetrics(durations: number[]): BenchmarkMetrics;
76
+ /**
77
+ * Generates a realistic synthetic 1,000-node UI hierarchy tree for benchmark matching.
78
+ * Models a complex mobile application screen containing headers, nested scroll lists,
79
+ * form inputs, action cards, and navigational tabs.
80
+ *
81
+ * @param nodeCount - Target number of nodes to generate (default: 1000).
82
+ * @returns An array of 1,000 structured UiNode elements.
83
+ */
84
+ export declare function generateSyntheticHierarchy(nodeCount?: number): UiNode[];
85
+ /**
86
+ * Runs the diagnostic benchmark across device screencap, hierarchy retrieval,
87
+ * and natural language node matching algorithms.
88
+ *
89
+ * @param driver - The AndroidDriver instance to benchmark against.
90
+ * @param options - Benchmark configuration options.
91
+ * @returns Completed BenchmarkReport.
92
+ */
93
+ export declare function runBenchmark(driver?: AndroidDriver, options?: BenchmarkOptions): Promise<BenchmarkReport>;
94
+ /**
95
+ * Formats a BenchmarkReport into an attractive CLI terminal summary table.
96
+ *
97
+ * @param report - The BenchmarkReport to format.
98
+ * @returns Multi-line formatted string.
99
+ */
100
+ export declare function formatBenchmarkTable(report: BenchmarkReport): string;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Structure of the saved checkpoint JSON data.
3
+ */
4
+ export interface CheckpointData {
5
+ /** The specification file name or identifier that was being executed. */
6
+ specFile: string;
7
+ /** The Android package name of the app under test. */
8
+ packageName: string;
9
+ /** The 0-based index of the last step that was successfully completed. */
10
+ lastPassedStep: number;
11
+ /** The total number of steps in the specification. */
12
+ totalSteps: number;
13
+ /** ISO 8601 timestamp of when the checkpoint was saved. */
14
+ savedAt: string;
15
+ }
16
+ /**
17
+ * Manages saving, loading, and clearing execution checkpoints for test runs.
18
+ */
19
+ export declare class CheckpointManager {
20
+ private checkpointDir;
21
+ /**
22
+ * Initializes a new CheckpointManager.
23
+ *
24
+ * @param checkpointDir The directory where checkpoint files should be stored. Defaults to './output/checkpoints'.
25
+ */
26
+ constructor(checkpointDir?: string);
27
+ private filePath;
28
+ /**
29
+ * Persists the index of the last successfully completed step (0-based).
30
+ *
31
+ * @param specName The name of the test specification.
32
+ * @param packageName The Android package name.
33
+ * @param lastPassedStep The 0-based index of the step just completed.
34
+ * @param totalSteps The total number of steps in the test.
35
+ */
36
+ save(specName: string, packageName: string, lastPassedStep: number, totalSteps: number): Promise<void>;
37
+ /**
38
+ * Loads an existing checkpoint from disk.
39
+ *
40
+ * @param specName The name of the test specification.
41
+ * @returns A Promise resolving to the parsed CheckpointData, or null if no checkpoint exists or it's invalid.
42
+ */
43
+ load(specName: string): Promise<CheckpointData | null>;
44
+ /**
45
+ * Deletes a checkpoint for a given spec. Should be called after a fully successful run.
46
+ *
47
+ * @param specName The name of the test specification.
48
+ */
49
+ clear(specName: string): Promise<void>;
50
+ /**
51
+ * Returns the 0-based step index to resume from, based on the last saved checkpoint.
52
+ *
53
+ * @param specName The name of the test specification.
54
+ * @returns The 0-based step index to resume from, or 0 if no checkpoint is found.
55
+ */
56
+ getResumeIndex(specName: string): Promise<number>;
57
+ }
58
+ /**
59
+ * A globally accessible singleton instance of CheckpointManager.
60
+ */
61
+ export declare const checkpointManager: CheckpointManager;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @file ci.ts
3
+ * @description One-Command CI/CD Workflow Scaffolder for PromptTest (CI-01).
4
+ * Generates automated regression workflows for GitHub Actions (using reactivecircus/android-emulator-runner)
5
+ * and GitLab CI with headless emulator virtualization and artifact reporting.
6
+ */
7
+ export type CiProvider = 'github-actions' | 'gitlab-ci';
8
+ export type CiTrigger = 'push' | 'pull_request' | 'schedule';
9
+ export type CiTarget = 'specs' | 'explore';
10
+ export interface CiWorkflowOptions {
11
+ /** Target CI provider platform */
12
+ provider?: CiProvider;
13
+ /** Trigger events to invoke the pipeline */
14
+ triggers?: CiTrigger[];
15
+ /** Execution mode: running specs vs autonomous exploration */
16
+ target?: CiTarget;
17
+ /** Spec file or glob pattern to execute */
18
+ specPattern?: string;
19
+ /** Target Android package name (required for explore target) */
20
+ packageName?: string;
21
+ /** Node.js runtime version to configure */
22
+ nodeVersion?: number;
23
+ /** Android API level for the emulator runner */
24
+ apiLevel?: number;
25
+ /** CPU architecture for the emulator image */
26
+ arch?: string;
27
+ }
28
+ export interface CiInitResult {
29
+ provider: CiProvider;
30
+ filePath: string;
31
+ fileName: string;
32
+ content: string;
33
+ }
34
+ /**
35
+ * Synthesizes a production-ready GitHub Actions YAML workflow
36
+ * utilizing headless Android emulator runners and artifact publishing.
37
+ */
38
+ export declare function generateGithubWorkflow(options?: CiWorkflowOptions): string;
39
+ /**
40
+ * Synthesizes a GitLab CI YAML configuration.
41
+ */
42
+ export declare function generateGitlabWorkflow(options?: CiWorkflowOptions): string;
43
+ /**
44
+ * Scaffolds the CI workflow file directly into the repository directory.
45
+ */
46
+ export declare function initCi(options?: CiWorkflowOptions & {
47
+ destDir?: string;
48
+ customFileName?: string;
49
+ }): Promise<CiInitResult>;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @module config-loader
3
+ * @description Discovers, parses, and merges PromptTest configuration from prompttest.config.json
4
+ * and environment variables (PROMPTTEST_*) over CONFIG defaults.
5
+ */
6
+ export interface PromptTestConfig {
7
+ adb: {
8
+ commandTimeoutMs: number;
9
+ binaryTimeoutMs: number;
10
+ retryCount: number;
11
+ retryBaseDelayMs: number;
12
+ };
13
+ polling: {
14
+ intervalMs: number;
15
+ jitterMs: number;
16
+ defaultTimeoutMs: number;
17
+ extendedTimeoutMs: number;
18
+ hierarchyCacheTtlMs: number;
19
+ verifyCacheTtlMs: number;
20
+ };
21
+ settle: {
22
+ tapMs: number;
23
+ backMs: number;
24
+ launchMs: number;
25
+ stopMs: number;
26
+ keyboardDismissMs: number;
27
+ scrollMs: number;
28
+ toggleMs: number;
29
+ selectMs: number;
30
+ inputFocusMs: number;
31
+ inputClearMs: number;
32
+ inputDoneMs: number;
33
+ submitWaitMs: number;
34
+ };
35
+ gestures: {
36
+ swipeDurationMs: number;
37
+ longPressDurationMs: number;
38
+ bottomNavThresholdRatio: number;
39
+ tapTargetYRatio: number;
40
+ };
41
+ recorder: {
42
+ staleTapTimeoutMs: number;
43
+ asyncRefreshDelayMs: number;
44
+ heartbeatIntervalMs: number;
45
+ };
46
+ screen: {
47
+ fallbackWidth: number;
48
+ fallbackHeight: number;
49
+ };
50
+ visual: {
51
+ overlapRatio: number;
52
+ };
53
+ device: {
54
+ maxDeviceRetries: number;
55
+ autoReconnect: boolean;
56
+ };
57
+ flow: {
58
+ maxLoopIterations: number;
59
+ waitUntilTimeoutMs: number;
60
+ defaultRetryCount: number;
61
+ };
62
+ ai: {
63
+ provider: 'heuristic' | 'openai' | 'anthropic' | 'ollama' | 'mock';
64
+ model: string;
65
+ selfHealing: boolean;
66
+ confidenceThreshold: number;
67
+ maxHealingAttempts: number;
68
+ endpoint: string;
69
+ };
70
+ locale: string;
71
+ }
72
+ /**
73
+ * Loads configuration by merging CONFIG defaults, prompttest.config.json (if present),
74
+ * and PROMPTTEST_* environment variables.
75
+ *
76
+ * @param configFilePath - Optional explicit path to configuration JSON file.
77
+ * @returns The resolved PromptTestConfig object.
78
+ */
79
+ export declare function loadConfig(configFilePath?: string): PromptTestConfig;
80
+ /**
81
+ * Returns the currently active configuration, loading it if not yet initialized.
82
+ */
83
+ export declare function getActiveConfig(): PromptTestConfig;
84
+ /**
85
+ * Resets the active configuration cache (useful for testing).
86
+ */
87
+ export declare function resetActiveConfig(): void;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * @module config
3
+ * @description Centralized PromptTest Engine Configuration.
4
+ *
5
+ * Consolidates all magic numbers, timeouts, settle durations,
6
+ * gesture thresholds, and polling strategies across the codebase.
7
+ * This guarantees consistent timing and reliable execution behavior
8
+ * during natural language script execution, autonomous crawling,
9
+ * and ADB interactions.
10
+ */
11
+ /**
12
+ * Helper to compute settle scaling factor from PROMPTTEST_SETTLE_FACTOR environment variable.
13
+ */
14
+ export declare function getSettleFactor(): number;
15
+ /**
16
+ * Scales a duration in milliseconds by the global settle factor, clamped to a minimum floor.
17
+ *
18
+ * @param ms - Target duration in milliseconds.
19
+ * @param minFloorMs - Minimum floor duration in milliseconds (default: 50).
20
+ * @returns Scaled millisecond duration.
21
+ */
22
+ export declare function scaleSettle(ms: number, minFloorMs?: number): number;
23
+ /**
24
+ * The global configuration settings for PromptTest.
25
+ */
26
+ export declare const CONFIG: {
27
+ /** Configuration related to ADB command execution and retry behavior. */
28
+ readonly adb: {
29
+ readonly commandTimeoutMs: 20000;
30
+ readonly binaryTimeoutMs: 45000;
31
+ readonly retryCount: 2;
32
+ readonly retryBaseDelayMs: 200;
33
+ };
34
+ /** Configuration for UI hierarchy polling and caching mechanisms. */
35
+ readonly polling: {
36
+ readonly intervalMs: 200;
37
+ readonly jitterMs: 80;
38
+ readonly defaultTimeoutMs: 3000;
39
+ readonly extendedTimeoutMs: 3500;
40
+ readonly hierarchyCacheTtlMs: 3500;
41
+ readonly verifyCacheTtlMs: 2000;
42
+ };
43
+ /** Delays applied after various UI interactions to allow animations or state changes to settle. */
44
+ readonly settle: {
45
+ readonly tapMs: number;
46
+ readonly backMs: number;
47
+ readonly launchMs: number;
48
+ readonly stopMs: number;
49
+ readonly keyboardDismissMs: number;
50
+ readonly scrollMs: number;
51
+ readonly toggleMs: number;
52
+ readonly selectMs: number;
53
+ readonly inputFocusMs: number;
54
+ readonly inputClearMs: number;
55
+ readonly inputDoneMs: number;
56
+ readonly submitWaitMs: number;
57
+ };
58
+ /** Parameters for Android gesture generation, calculating bounds, and swipe physics. */
59
+ readonly gestures: {
60
+ readonly swipeDurationMs: 300;
61
+ readonly longPressDurationMs: 1000;
62
+ readonly bottomNavThresholdRatio: 0.88;
63
+ readonly tapTargetYRatio: 0.96;
64
+ };
65
+ /** Settings for the AutonomousRecorder component monitoring live device usage. */
66
+ readonly recorder: {
67
+ readonly staleTapTimeoutMs: 3000;
68
+ readonly asyncRefreshDelayMs: 80;
69
+ readonly heartbeatIntervalMs: 1500;
70
+ };
71
+ /** Screen geometry defaults when device cannot report dimensions. */
72
+ readonly screen: {
73
+ readonly fallbackWidth: 1080;
74
+ readonly fallbackHeight: 2400;
75
+ };
76
+ /** Visual defect detection thresholds and settings. */
77
+ readonly visual: {
78
+ readonly overlapRatio: 0.2;
79
+ };
80
+ /** Device connection and resilience parameters. */
81
+ readonly device: {
82
+ readonly maxDeviceRetries: 2;
83
+ readonly autoReconnect: true;
84
+ };
85
+ /** Programmatic flow control, loops, and conditional execution. */
86
+ readonly flow: {
87
+ readonly maxLoopIterations: 50;
88
+ readonly waitUntilTimeoutMs: 10000;
89
+ readonly defaultRetryCount: 3;
90
+ };
91
+ /** AI step expansion, semantic locator resolution, and self-healing. */
92
+ readonly ai: {
93
+ readonly provider: "heuristic" | "openai" | "anthropic" | "ollama" | "mock";
94
+ readonly model: "gpt-4o-mini";
95
+ readonly selfHealing: true;
96
+ readonly confidenceThreshold: 0.75;
97
+ readonly maxHealingAttempts: 2;
98
+ readonly endpoint: "";
99
+ };
100
+ /** Autonomous locator learning and persistent memory configuration. */
101
+ readonly memory: {
102
+ readonly staleThresholdDays: number;
103
+ readonly staleDecayAmount: 0.2;
104
+ readonly minConfidenceFloor: 0.2;
105
+ readonly maxHealedConfidence: 0.65;
106
+ };
107
+ /** UI Hierarchy XML parser configuration (SP-05). */
108
+ readonly parser: {
109
+ readonly mode: "regex" | "streaming";
110
+ };
111
+ /** Safety guard configuration for autonomous actions (AX-09, AX-10). */
112
+ readonly safety: {
113
+ readonly mode: "strict" | "moderate" | "interactive" | "disabled";
114
+ readonly customBlacklist: readonly string[];
115
+ };
116
+ /** Autonomous Explorer v3 settings (AX-12, AX-15, AX-16). */
117
+ readonly explorer: {
118
+ readonly strategy: "dfs" | "heuristic";
119
+ readonly maxTabs: number;
120
+ readonly maxScreens: number;
121
+ readonly maxDepth: number;
122
+ readonly stepBudget: number;
123
+ readonly screenshots: "state-change" | "failure-only" | "all";
124
+ };
125
+ /** Localization and multilingual taxonomy configuration. */
126
+ readonly locale: "en";
127
+ };
128
+ /**
129
+ * Returns a polling delay with random jitter to prevent thundering herd
130
+ * and reduce contention with the ADB daemon.
131
+ *
132
+ * @param baseMs The base delay in milliseconds. Defaults to CONFIG.polling.intervalMs.
133
+ * @param jitterMs The maximum jitter range in milliseconds. Defaults to CONFIG.polling.jitterMs.
134
+ * @returns A computed delay in milliseconds including base and jitter.
135
+ */
136
+ export declare function getJitteredPollDelay(baseMs?: number, jitterMs?: number): number;