@ansight/react-native 1.4.0 → 1.6.0
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.
- package/README.md +15 -3
- package/android/build.gradle +2 -2
- package/android/src/main/kotlin/ai/ansight/reactnative/AnsightReactNativeModule.kt +14 -0
- package/index.d.ts +7 -0
- package/index.js +8 -0
- package/ios/AnsightReactNative.swift +10 -0
- package/ios/AnsightReactNativeModule.m +4 -0
- package/package.json +5 -3
- package/purchases.d.ts +61 -0
- package/purchases.js +17 -0
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# @ansight/react-native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Ansight gives coding agents the runtime evidence to verify their own work in
|
|
4
|
+
React Native and Expo development builds. The SDK captures screenshots, visual trees, touches, logs,
|
|
5
|
+
crashes and unhandled errors, HTTP requests, screen views and navigation, lifecycle events, app events, custom metrics, and sampled memory,
|
|
6
|
+
FPS, frame timing, and battery while the app runs, and exposes app state,
|
|
7
|
+
preferences, secure storage, files, SQLite, artifacts, and your own custom
|
|
8
|
+
tools through guarded remote tools on request. Your agent reads all of it
|
|
9
|
+
through the `ansight` CLI. Nothing leaves your machine unless you export or
|
|
10
|
+
share it. See https://www.ansight.ai and the
|
|
11
|
+
[getting started guide](https://www.ansight.ai/docs/getting-started).
|
|
4
12
|
|
|
5
13
|
The package is intentionally thin: pairing, transport, telemetry, screen
|
|
6
14
|
capture, touch capture, native tool discovery, and native tool execution are
|
|
@@ -80,8 +88,8 @@ bundle; its API requires the native Ansight module.
|
|
|
80
88
|
|
|
81
89
|
This package version expects matching native SDK packages:
|
|
82
90
|
|
|
83
|
-
- CocoaPods: `Ansight`, `AnsightObjC` version `1.
|
|
84
|
-
- Maven: `ai.ansight:ansight-android:1.
|
|
91
|
+
- CocoaPods: `Ansight`, `AnsightObjC` version `1.6.0`
|
|
92
|
+
- Maven: `ai.ansight:ansight-android:1.6.0`
|
|
85
93
|
|
|
86
94
|
## Quickstart
|
|
87
95
|
|
|
@@ -672,3 +680,7 @@ It is pinned to Expo SDK 57 and React Native 0.86 with the New Architecture and
|
|
|
672
680
|
Hermes enabled. It validates Expo CNG/autolinking, the bundled config plugin,
|
|
673
681
|
Android and iOS native builds, and the same live host feature surface as the
|
|
674
682
|
baseline harness.
|
|
683
|
+
|
|
684
|
+
## Purchase diagnostics
|
|
685
|
+
|
|
686
|
+
See [purchase observations, adapters, and remote validation](../../docs/purchases.md) for the base SDK purchase suite.
|
package/android/build.gradle
CHANGED
|
@@ -67,6 +67,6 @@ repositories {
|
|
|
67
67
|
dependencies {
|
|
68
68
|
implementation("com.facebook.react:react-android")
|
|
69
69
|
def ansightAndroidVersion =
|
|
70
|
-
findProperty("ansightAndroidVersion") ?: "1.
|
|
71
|
-
implementation("ai.ansight:ansight-android:1.
|
|
70
|
+
findProperty("ansightAndroidVersion") ?: "1.6.0"
|
|
71
|
+
implementation("ai.ansight:ansight-android:1.6.0")
|
|
72
72
|
}
|
|
@@ -48,6 +48,8 @@ import ai.ansight.tools.filesystem.AndroidFileSystemRoot
|
|
|
48
48
|
import ai.ansight.tools.filesystem.AndroidFileSystemToolsOptions
|
|
49
49
|
import ai.ansight.tools.filesystem.withFileSystemTools
|
|
50
50
|
import ai.ansight.tools.preferences.AndroidPreferencesToolsOptions
|
|
51
|
+
import ai.ansight.tools.clipboard.ClipboardToolIds
|
|
52
|
+
import ai.ansight.tools.clipboard.withClipboardTools
|
|
51
53
|
import ai.ansight.tools.preferences.withPreferencesTools
|
|
52
54
|
import ai.ansight.tools.reflection.AndroidReflectionToolsOptions
|
|
53
55
|
import ai.ansight.tools.reflection.withReflectionTools
|
|
@@ -135,6 +137,13 @@ class AnsightReactNativeModule(
|
|
|
135
137
|
|
|
136
138
|
override fun onHostDestroy() = Unit
|
|
137
139
|
|
|
140
|
+
@ReactMethod
|
|
141
|
+
fun purchaseCommand(json: String, promise: Promise) {
|
|
142
|
+
try { promise.resolve(ai.ansight.runtime.purchases.PurchaseDiagnostics.shared.command(json)) }
|
|
143
|
+
catch (error: ai.ansight.runtime.purchases.PurchaseEnvironmentException) { promise.reject(ai.ansight.runtime.purchases.PurchaseEnvironmentException.ERROR_CODE, error.message, error) }
|
|
144
|
+
catch (error: Exception) { promise.reject("purchases_command_failed", "Purchase command failed.", error) }
|
|
145
|
+
}
|
|
146
|
+
|
|
138
147
|
@ReactMethod
|
|
139
148
|
fun addListener(eventName: String) {
|
|
140
149
|
listenerCount.incrementAndGet()
|
|
@@ -962,6 +971,11 @@ class AnsightReactNativeModule(
|
|
|
962
971
|
): AnsightOptions {
|
|
963
972
|
val remoteTools = map.getMapOrNull("remoteTools")
|
|
964
973
|
val builder = AnsightOptions.createBuilder(this)
|
|
974
|
+
val clipboardIds = setOf(ClipboardToolIds.GetText, ClipboardToolIds.HasText, ClipboardToolIds.SetText, ClipboardToolIds.Clear)
|
|
975
|
+
builder.withTools(initialTools.filterNot { it.definition.id in clipboardIds })
|
|
976
|
+
if (remoteTools.booleanValue("clipboard", true)) {
|
|
977
|
+
builder.withClipboardTools()
|
|
978
|
+
}
|
|
965
979
|
if (remoteTools.toolSuiteEnabled("visualTree", enableVisualTreeToolsByDefault)) {
|
|
966
980
|
builder.withVisualTreeTools()
|
|
967
981
|
}
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { PurchaseDiagnostics } from "./purchases";
|
|
2
|
+
export * from "./purchases";
|
|
3
|
+
export const purchases: PurchaseDiagnostics;
|
|
1
4
|
export type AnsightLifecycleState = "unknown" | "foreground" | "background";
|
|
2
5
|
export type AnsightToolPolicy = "read" | "write" | "critical";
|
|
3
6
|
|
|
@@ -144,6 +147,8 @@ export interface AnsightVisualTreeToolsOptions {
|
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
export interface AnsightRemoteToolsOptions {
|
|
150
|
+
/** Include native clipboard tools; defaults to true. */
|
|
151
|
+
clipboard?: boolean;
|
|
147
152
|
visualTree?: boolean | AnsightVisualTreeToolsOptions;
|
|
148
153
|
fileSystem?: AnsightFileSystemToolsOptions;
|
|
149
154
|
database?: AnsightDatabaseToolsOptions;
|
|
@@ -392,6 +397,7 @@ export class AnsightOptionsBuilder {
|
|
|
392
397
|
withoutVisualTreeTools(): this;
|
|
393
398
|
withFileSystemTools(options?: AnsightFileSystemToolsOptions): this;
|
|
394
399
|
withDatabaseTools(options?: AnsightDatabaseToolsOptions): this;
|
|
400
|
+
withClipboardTools(enabled?: boolean): this;
|
|
395
401
|
withPreferencesTools(options?: AnsightPreferencesToolsOptions): this;
|
|
396
402
|
withReflectionTools(options?: AnsightReflectionToolsOptions): this;
|
|
397
403
|
build(): AnsightOptions;
|
|
@@ -676,6 +682,7 @@ export function installErrorHandlers(options?: { chain?: boolean }): () => void;
|
|
|
676
682
|
export function createReactNavigationTracker(navigationRef: unknown, options?: { recordInitial?: boolean }): ReactNavigationTracker;
|
|
677
683
|
|
|
678
684
|
declare const Ansight: {
|
|
685
|
+
purchases: PurchaseDiagnostics;
|
|
679
686
|
initialize: typeof initialize;
|
|
680
687
|
initializeAndActivate: typeof initializeAndActivate;
|
|
681
688
|
activate: typeof activate;
|
package/index.js
CHANGED
|
@@ -608,6 +608,11 @@ class AnsightOptionsBuilder {
|
|
|
608
608
|
return this;
|
|
609
609
|
}
|
|
610
610
|
|
|
611
|
+
withClipboardTools(enabled = true) {
|
|
612
|
+
this._options.remoteTools = { ...this._options.remoteTools, clipboard: enabled };
|
|
613
|
+
return this;
|
|
614
|
+
}
|
|
615
|
+
|
|
611
616
|
withPreferencesTools(options = {}) {
|
|
612
617
|
this._options.remoteTools = {
|
|
613
618
|
...(this._options.remoteTools || {}),
|
|
@@ -2669,3 +2674,6 @@ module.exports.recordNetworkRequest = recordNetworkRequest;
|
|
|
2669
2674
|
module.exports.installNetworkCapture = installNetworkCapture;
|
|
2670
2675
|
module.exports.uninstallNetworkCapture = uninstallNetworkCapture;
|
|
2671
2676
|
module.exports.sanitizeNetworkRequest = sanitizeNetworkRequest;
|
|
2677
|
+
|
|
2678
|
+
module.exports.purchases = require("./purchases").createPurchaseDiagnostics((json) => nativeModule.purchaseCommand(json));
|
|
2679
|
+
module.exports.createPurchaseDiagnostics = require("./purchases").createPurchaseDiagnostics;
|
|
@@ -4,6 +4,15 @@ import React
|
|
|
4
4
|
|
|
5
5
|
@objc(AnsightReactNative)
|
|
6
6
|
final class AnsightReactNative: RCTEventEmitter {
|
|
7
|
+
@objc(purchaseCommand:resolver:rejecter:)
|
|
8
|
+
func purchaseCommand(_ json: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
9
|
+
Task {
|
|
10
|
+
do { resolve(try await PurchaseDiagnostics.shared.commandAsync(json)) }
|
|
11
|
+
catch PurchaseDiagnosticsError.environmentNotAllowed { reject(PurchaseDiagnosticsError.environmentErrorCode, "Purchase interop is restricted to simulators and emulators.", PurchaseDiagnosticsError.environmentNotAllowed) }
|
|
12
|
+
catch { reject("purchases_command_failed", "Purchase command failed.", error) }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
7
16
|
private final class PendingToolCall {
|
|
8
17
|
let semaphore = DispatchSemaphore(value: 0)
|
|
9
18
|
var result: AnsightToolExecutionResult?
|
|
@@ -1153,6 +1162,7 @@ final class AnsightReactNative: RCTEventEmitter {
|
|
|
1153
1162
|
remoteTools?["visualTree"],
|
|
1154
1163
|
defaultValue: useNativeAllInOneDefaults
|
|
1155
1164
|
),
|
|
1165
|
+
clipboard: boolValue(remoteTools, "clipboard", defaultValue: true),
|
|
1156
1166
|
database: databaseToolsOptions(remoteTools?["database"] as? NSDictionary),
|
|
1157
1167
|
fileSystem: fileSystemToolsOptions(remoteTools?["fileSystem"] as? NSDictionary),
|
|
1158
1168
|
preferences: preferencesToolsOptions(remoteTools?["preferences"] as? NSDictionary),
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
@interface RCT_EXTERN_MODULE(AnsightReactNative, RCTEventEmitter)
|
|
5
5
|
|
|
6
|
+
RCT_EXTERN_METHOD(purchaseCommand:(NSString *)json
|
|
7
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
6
10
|
RCT_EXTERN_METHOD(initialize:(NSDictionary *)options
|
|
7
11
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
8
12
|
rejecter:(RCTPromiseRejectBlock)reject)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ansight/react-native",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "React Native bridge for
|
|
3
|
+
"version": "1.6.0",
|
|
4
|
+
"description": "React Native bridge for Ansight: runtime evidence from your app for coding agents. Screenshots, UI trees, logs, network, telemetry, and app state.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
"expo-plugin.js",
|
|
35
35
|
"tsconfig.json",
|
|
36
36
|
"AnsightReactNative.podspec",
|
|
37
|
-
"react-native.config.js"
|
|
37
|
+
"react-native.config.js",
|
|
38
|
+
"purchases.js",
|
|
39
|
+
"purchases.d.ts"
|
|
38
40
|
],
|
|
39
41
|
"keywords": [
|
|
40
42
|
"ansight",
|
package/purchases.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface PurchaseObservation {
|
|
2
|
+
productId: string;
|
|
3
|
+
source: "store" | "app" | "backend";
|
|
4
|
+
transactionRef?: string | null;
|
|
5
|
+
observedAt?: number;
|
|
6
|
+
state?: "unknown" | "pending" | "purchased" | "cancelled" | "expired" | "revoked" | "failed" | "gracePeriod" | "billingRetry";
|
|
7
|
+
verification?: "unknown" | "verified" | "unverified";
|
|
8
|
+
entitled?: boolean | null;
|
|
9
|
+
deliveryCount?: number | null;
|
|
10
|
+
finished?: boolean | null;
|
|
11
|
+
acknowledged?: boolean | null;
|
|
12
|
+
consumed?: boolean | null;
|
|
13
|
+
expiresAt?: number | null;
|
|
14
|
+
gracePeriodExpiresAt?: number | null;
|
|
15
|
+
environment?: "unknown" | "xcode" | "sandbox" | "production";
|
|
16
|
+
productType?: "unknown" | "consumable" | "nonConsumable" | "subscription" | "nonRenewingSubscription";
|
|
17
|
+
}
|
|
18
|
+
export interface PurchaseProduct {
|
|
19
|
+
productId: string;
|
|
20
|
+
available: boolean;
|
|
21
|
+
observedAt?: number;
|
|
22
|
+
displayPrice?: string | null;
|
|
23
|
+
price?: string | null;
|
|
24
|
+
currencyCode?: string | null;
|
|
25
|
+
productType?: PurchaseObservation["productType"];
|
|
26
|
+
}
|
|
27
|
+
export interface PurchaseExpectations {
|
|
28
|
+
transactionRef?: string;
|
|
29
|
+
productId: string;
|
|
30
|
+
expectedEntitled: boolean;
|
|
31
|
+
requireVerified?: boolean;
|
|
32
|
+
requireBackendVerification?: boolean;
|
|
33
|
+
expectedDeliveryCount?: number;
|
|
34
|
+
maxAgeMilliseconds?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface PurchaseSnapshot {
|
|
37
|
+
schema: "ansight.purchases.v1";
|
|
38
|
+
capturedAt: number;
|
|
39
|
+
droppedEvents: number;
|
|
40
|
+
coverage: "observedOnly";
|
|
41
|
+
observations: PurchaseObservation[];
|
|
42
|
+
products: PurchaseProduct[];
|
|
43
|
+
}
|
|
44
|
+
export interface PurchaseValidationReport extends PurchaseSnapshot {
|
|
45
|
+
status: "pass" | "fail" | "inconclusive";
|
|
46
|
+
checks: { source: string; status: "pass" | "fail" | "inconclusive"; reason: string }[];
|
|
47
|
+
}
|
|
48
|
+
export interface PurchaseDiagnostics {
|
|
49
|
+
createTransactionReference(identifier: string): Promise<{ transactionRef: string }>;
|
|
50
|
+
/** Register read-only remote tools after SDK initialization. */
|
|
51
|
+
register(): Promise<{ success: boolean }>;
|
|
52
|
+
record(observation: PurchaseObservation): Promise<{ success: boolean }>;
|
|
53
|
+
recordProduct(product: PurchaseProduct): Promise<{ success: boolean }>;
|
|
54
|
+
/** Clear evidence on account switch. Does not clear store transactions. */
|
|
55
|
+
clear(): Promise<{ success: boolean }>;
|
|
56
|
+
snapshot(productId?: string): Promise<PurchaseSnapshot>;
|
|
57
|
+
validate(expectations: PurchaseExpectations): Promise<PurchaseValidationReport>;
|
|
58
|
+
/** Apple only. Reads StoreKit 2 using known product IDs. */
|
|
59
|
+
refreshStoreKit(productIds: string[]): Promise<PurchaseSnapshot>;
|
|
60
|
+
}
|
|
61
|
+
export function createPurchaseDiagnostics(send: (json: string) => Promise<string>): PurchaseDiagnostics;
|
package/purchases.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// All observation retention, validation and tools live in the native base SDK.
|
|
4
|
+
function createPurchaseDiagnostics(send) {
|
|
5
|
+
const command = async (action, fields = {}) => JSON.parse(await send(JSON.stringify({ action, ...fields })));
|
|
6
|
+
return {
|
|
7
|
+
createTransactionReference: (identifier) => command("reference", { identifier }),
|
|
8
|
+
register: () => command("register"),
|
|
9
|
+
record: (observation) => command("record", { observation: { observedAt: Date.now(), ...observation } }),
|
|
10
|
+
recordProduct: (product) => command("recordProduct", { product: { observedAt: Date.now(), productType: "unknown", ...product } }),
|
|
11
|
+
clear: () => command("clear"),
|
|
12
|
+
snapshot: (productId) => command("purchases.get_state", { arguments: productId === undefined ? {} : { productId } }),
|
|
13
|
+
validate: (expectations) => command("purchases.validate", { arguments: expectations }),
|
|
14
|
+
refreshStoreKit: (productIds) => command("refreshStoreKit", { productIds }),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
module.exports = { createPurchaseDiagnostics };
|