sentience-ts 0.10.3

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 (62) hide show
  1. package/README.md +193 -0
  2. package/dist/actions.d.ts +9 -0
  3. package/dist/actions.d.ts.map +1 -0
  4. package/dist/actions.js +113 -0
  5. package/dist/actions.js.map +1 -0
  6. package/dist/browser.d.ts +24 -0
  7. package/dist/browser.d.ts.map +1 -0
  8. package/dist/browser.js +236 -0
  9. package/dist/browser.js.map +1 -0
  10. package/dist/cli.d.ts +5 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +158 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/expect.d.ts +16 -0
  15. package/dist/expect.d.ts.map +1 -0
  16. package/dist/expect.js +66 -0
  17. package/dist/expect.js.map +1 -0
  18. package/dist/generator.d.ts +16 -0
  19. package/dist/generator.d.ts.map +1 -0
  20. package/dist/generator.js +205 -0
  21. package/dist/generator.js.map +1 -0
  22. package/dist/index.d.ts +16 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +52 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/inspector.d.ts +13 -0
  27. package/dist/inspector.d.ts.map +1 -0
  28. package/dist/inspector.js +147 -0
  29. package/dist/inspector.js.map +1 -0
  30. package/dist/query.d.ts +8 -0
  31. package/dist/query.d.ts.map +1 -0
  32. package/dist/query.js +337 -0
  33. package/dist/query.js.map +1 -0
  34. package/dist/read.d.ts +40 -0
  35. package/dist/read.d.ts.map +1 -0
  36. package/dist/read.js +86 -0
  37. package/dist/read.js.map +1 -0
  38. package/dist/recorder.d.ts +44 -0
  39. package/dist/recorder.d.ts.map +1 -0
  40. package/dist/recorder.js +256 -0
  41. package/dist/recorder.js.map +1 -0
  42. package/dist/screenshot.d.ts +17 -0
  43. package/dist/screenshot.d.ts.map +1 -0
  44. package/dist/screenshot.js +37 -0
  45. package/dist/screenshot.js.map +1 -0
  46. package/dist/snapshot.d.ts +20 -0
  47. package/dist/snapshot.d.ts.map +1 -0
  48. package/dist/snapshot.js +101 -0
  49. package/dist/snapshot.js.map +1 -0
  50. package/dist/types.d.ts +71 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +6 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/wait.d.ts +7 -0
  55. package/dist/wait.d.ts.map +1 -0
  56. package/dist/wait.js +37 -0
  57. package/dist/wait.js.map +1 -0
  58. package/package.json +58 -0
  59. package/spec/README.md +72 -0
  60. package/spec/SNAPSHOT_V1.md +208 -0
  61. package/spec/sdk-types.md +259 -0
  62. package/spec/snapshot.schema.json +148 -0
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "sentience-ts",
3
+ "version": "0.10.3",
4
+ "description": "TypeScript SDK for Sentience AI Agent Browser Automation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "jest",
10
+ "prepare": "npm run build",
11
+ "prepublishOnly": "npm test && npm run build",
12
+ "example:hello": "ts-node examples/hello.ts",
13
+ "example:basic": "ts-node examples/basic-agent.ts",
14
+ "cli": "ts-node src/cli.ts"
15
+ },
16
+ "bin": {
17
+ "sentience": "./dist/cli.js"
18
+ },
19
+ "dependencies": {
20
+ "playwright": "^1.40.0",
21
+ "turndown": "^7.2.2",
22
+ "zod": "^3.22.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/jest": "^29.5.14",
26
+ "@types/node": "^20.0.0",
27
+ "@types/turndown": "^5.0.3",
28
+ "jest": "^29.0.0",
29
+ "ts-jest": "^29.0.0",
30
+ "ts-node": "^10.9.0",
31
+ "typescript": "^5.0.0"
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "spec",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "keywords": [
40
+ "browser-automation",
41
+ "playwright",
42
+ "ai-agent",
43
+ "web-automation",
44
+ "sentience"
45
+ ],
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/SentienceAPI/sentience-ts.git"
49
+ },
50
+ "bugs": {
51
+ "url": "https://github.com/SentienceAPI/sentience-ts/issues"
52
+ },
53
+ "homepage": "https://github.com/SentienceAPI/sentience-ts#readme",
54
+ "license": "MIT",
55
+ "engines": {
56
+ "node": ">=20.0.0"
57
+ }
58
+ }
package/spec/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Sentience API Specification
2
+
3
+ This directory contains the **single source of truth** for the API contract between the Chrome extension and SDKs.
4
+
5
+ ## Files
6
+
7
+ - **`snapshot.schema.json`** - JSON Schema for snapshot response validation
8
+ - **`SNAPSHOT_V1.md`** - Human-readable snapshot API contract
9
+ - **`sdk-types.md`** - SDK-level type definitions (ActionResult, WaitResult, TraceStep)
10
+
11
+ ## Purpose
12
+
13
+ These specifications ensure:
14
+ 1. **Consistency**: Both Python and TypeScript SDKs implement the same contract
15
+ 2. **Validation**: SDKs can validate extension responses
16
+ 3. **Type Safety**: Strong typing in both languages
17
+ 4. **Documentation**: Clear reference for developers
18
+
19
+ ## Usage
20
+
21
+ ### For SDK Developers
22
+
23
+ 1. **Read** `SNAPSHOT_V1.md` for human-readable contract
24
+ 2. **Use** `snapshot.schema.json` for JSON Schema validation
25
+ 3. **Reference** `sdk-types.md` for SDK-level types
26
+
27
+ ### For Extension Developers
28
+
29
+ 1. **Ensure** extension output matches `snapshot.schema.json`
30
+ 2. **Update** schema when adding new fields
31
+ 3. **Version** schema for breaking changes
32
+
33
+ ## Versioning
34
+
35
+ - **v1.0.0**: Initial stable version (Day 1)
36
+ - Future versions: Increment major version for breaking changes
37
+ - SDKs should validate version and handle compatibility
38
+
39
+ ## Validation
40
+
41
+ Both SDKs should validate extension responses:
42
+
43
+ **Python**:
44
+ ```python
45
+ import jsonschema
46
+ from spec.snapshot.schema import load_schema
47
+
48
+ schema = load_schema()
49
+ jsonschema.validate(snapshot_data, schema)
50
+ ```
51
+
52
+ **TypeScript**:
53
+ ```typescript
54
+ import Ajv from 'ajv';
55
+ import schema from './spec/snapshot.schema.json';
56
+
57
+ const ajv = new Ajv();
58
+ const validate = ajv.compile(schema);
59
+ validate(snapshot_data);
60
+ ```
61
+
62
+ ## Testing
63
+
64
+ - Validate against real extension output
65
+ - Test with edge cases (empty pages, many elements, errors)
66
+ - Verify type coercion and defaults
67
+
68
+ ---
69
+
70
+ **Last Updated**: Day 1 Implementation
71
+ **Status**: ✅ Stable
72
+
@@ -0,0 +1,208 @@
1
+ # Sentience Snapshot API Contract v1
2
+
3
+ **Version**: 1.0.0
4
+ **Last Updated**: [Current Date]
5
+ **Status**: Stable
6
+
7
+ This document defines the **single source of truth** for the snapshot data structure returned by `window.sentience.snapshot()`. Both Python and TypeScript SDKs must implement this contract exactly.
8
+
9
+ ## Overview
10
+
11
+ The snapshot API returns a structured representation of the current page state, including:
12
+ - All interactive elements with semantic roles
13
+ - Element positions (bounding boxes)
14
+ - Importance scores (AI-optimized ranking)
15
+ - Visual cues (primary actions, colors, clickability)
16
+ - Optional screenshot
17
+
18
+ ## Response Structure
19
+
20
+ ### Top-Level Object
21
+
22
+ ```typescript
23
+ {
24
+ status: "success" | "error",
25
+ timestamp?: string, // ISO 8601
26
+ url: string,
27
+ viewport?: { width: number, height: number },
28
+ elements: Element[],
29
+ screenshot?: string, // Base64 data URL
30
+ screenshot_format?: "png" | "jpeg",
31
+ error?: string, // If status is "error"
32
+ requires_license?: boolean // If license required
33
+ }
34
+ ```
35
+
36
+ ### Element Object
37
+
38
+ ```typescript
39
+ {
40
+ id: number, // REQUIRED: Unique identifier (registry index)
41
+ role: string, // REQUIRED: Semantic role
42
+ text: string | null, // Text content, aria-label, or placeholder
43
+ importance: number, // REQUIRED: Importance score (-300 to ~1800)
44
+ bbox: BBox, // REQUIRED: Bounding box
45
+ visual_cues: VisualCues, // REQUIRED: Visual analysis
46
+ in_viewport: boolean, // Is element visible in viewport
47
+ is_occluded: boolean, // Is element covered by overlay
48
+ z_index: number // CSS z-index (0 if auto)
49
+ }
50
+ ```
51
+
52
+ ### BBox (Bounding Box)
53
+
54
+ ```typescript
55
+ {
56
+ x: number, // Left edge in pixels
57
+ y: number, // Top edge in pixels
58
+ width: number, // Width in pixels
59
+ height: number // Height in pixels
60
+ }
61
+ ```
62
+
63
+ ### VisualCues
64
+
65
+ ```typescript
66
+ {
67
+ is_primary: boolean, // Visually prominent primary action
68
+ background_color_name: string | null, // Named color from palette
69
+ is_clickable: boolean // Has pointer cursor or actionable role
70
+ }
71
+ ```
72
+
73
+ ## Field Details
74
+
75
+ ### `id` (required)
76
+ - **Type**: `integer`
77
+ - **Description**: Unique element identifier, corresponds to index in `window.sentience_registry`
78
+ - **Usage**: Used for actions like `click(id)`
79
+ - **Stability**: May change between page loads (not persistent)
80
+
81
+ ### `role` (required)
82
+ - **Type**: `string`
83
+ - **Values**: `"button"`, `"link"`, `"textbox"`, `"searchbox"`, `"checkbox"`, `"radio"`, `"combobox"`, `"image"`, `"generic"`
84
+ - **Description**: Semantic role inferred from HTML tag, ARIA attributes, and context
85
+ - **Usage**: Primary filter for query engine
86
+
87
+ ### `text` (optional)
88
+ - **Type**: `string | null`
89
+ - **Description**: Text content extracted from element:
90
+ - `aria-label` if present
91
+ - `value` or `placeholder` for inputs
92
+ - `alt` for images
93
+ - `innerText` for other elements (truncated to 100 chars)
94
+ - **Usage**: Text matching in query engine
95
+
96
+ ### `importance` (required)
97
+ - **Type**: `integer`
98
+ - **Range**: -300 to ~1800
99
+ - **Description**: AI-optimized importance score calculated from:
100
+ - Role priority (inputs: 1000, buttons: 500, links: 100)
101
+ - Area score (larger elements score higher, capped at 200)
102
+ - Visual prominence (+200 for primary actions)
103
+ - Viewport/occlusion penalties (-500 off-screen, -800 occluded)
104
+ - **Usage**: Ranking and filtering elements
105
+
106
+ ### `bbox` (required)
107
+ - **Type**: `BBox` object
108
+ - **Description**: Element position and size in viewport coordinates
109
+ - **Coordinates**: Relative to viewport (0,0) at top-left
110
+ - **Usage**: Spatial queries, visual grounding, click coordinates
111
+
112
+ ### `visual_cues` (required)
113
+ - **Type**: `VisualCues` object
114
+ - **Description**: Visual analysis results
115
+ - **Fields**:
116
+ - `is_primary`: True if element is visually prominent primary action
117
+ - `background_color_name`: Nearest named color (32-color palette) or null
118
+ - `is_clickable`: True if element has pointer cursor or actionable role
119
+
120
+ ### `in_viewport` (optional)
121
+ - **Type**: `boolean`
122
+ - **Description**: True if element is visible in current viewport
123
+ - **Default**: `true` (if not present, assume visible)
124
+
125
+ ### `is_occluded` (optional)
126
+ - **Type**: `boolean`
127
+ - **Description**: True if element is covered by another element
128
+ - **Default**: `false` (if not present, assume not occluded)
129
+
130
+ ### `z_index` (optional)
131
+ - **Type**: `integer`
132
+ - **Description**: CSS z-index value (0 if "auto" or not set)
133
+ - **Default**: `0`
134
+
135
+ ## Element Sorting
136
+
137
+ Elements in the `elements` array are sorted by:
138
+ 1. **Primary sort**: `importance` (descending) - most important first
139
+ 2. **Secondary sort**: `bbox.y` (ascending) - top-to-bottom reading order (if limit applied)
140
+
141
+ ## Example Response
142
+
143
+ ```json
144
+ {
145
+ "status": "success",
146
+ "timestamp": "2025-01-20T10:30:00Z",
147
+ "url": "https://example.com",
148
+ "viewport": {
149
+ "width": 1280,
150
+ "height": 800
151
+ },
152
+ "elements": [
153
+ {
154
+ "id": 42,
155
+ "role": "button",
156
+ "text": "Sign In",
157
+ "importance": 850,
158
+ "bbox": {
159
+ "x": 100,
160
+ "y": 200,
161
+ "width": 120,
162
+ "height": 40
163
+ },
164
+ "visual_cues": {
165
+ "is_primary": true,
166
+ "background_color_name": "blue",
167
+ "is_clickable": true
168
+ },
169
+ "in_viewport": true,
170
+ "is_occluded": false,
171
+ "z_index": 0
172
+ }
173
+ ]
174
+ }
175
+ ```
176
+
177
+ ## Error Response
178
+
179
+ ```json
180
+ {
181
+ "status": "error",
182
+ "error": "Headless mode requires a valid license key...",
183
+ "requires_license": true
184
+ }
185
+ ```
186
+
187
+ ## SDK Implementation Requirements
188
+
189
+ Both Python and TypeScript SDKs must:
190
+
191
+ 1. **Validate** snapshot response against this schema
192
+ 2. **Parse** all required fields correctly
193
+ 3. **Handle** optional fields gracefully (defaults)
194
+ 4. **Type-check** all fields (Pydantic for Python, TypeScript types for TS)
195
+ 5. **Preserve** field names exactly (no renaming)
196
+
197
+ ## Versioning
198
+
199
+ - **v1.0.0**: Initial stable version
200
+ - Future versions will increment major version for breaking changes
201
+ - SDKs should validate version and handle compatibility
202
+
203
+ ## Related Documents
204
+
205
+ - `snapshot.schema.json` - JSON Schema validation
206
+ - Extension implementation: `sentience-chrome/injected_api.js`
207
+ - WASM implementation: `sentience-chrome/src/lib.rs`
208
+
@@ -0,0 +1,259 @@
1
+ # SDK-Level Type Definitions
2
+
3
+ **Purpose**: Define SDK-level types that extend the snapshot contract with action results, wait results, and trace steps.
4
+
5
+ ## Core Types
6
+
7
+ ### Snapshot
8
+ ```typescript
9
+ interface Snapshot {
10
+ status: "success" | "error";
11
+ timestamp?: string;
12
+ url: string;
13
+ viewport?: { width: number; height: number };
14
+ elements: Element[];
15
+ screenshot?: string;
16
+ screenshot_format?: "png" | "jpeg";
17
+ error?: string;
18
+ requires_license?: boolean;
19
+ }
20
+ ```
21
+
22
+ ### Element
23
+ ```typescript
24
+ interface Element {
25
+ id: number;
26
+ role: string;
27
+ text: string | null;
28
+ importance: number;
29
+ bbox: BBox;
30
+ visual_cues: VisualCues;
31
+ in_viewport: boolean;
32
+ is_occluded: boolean;
33
+ z_index: number;
34
+ }
35
+ ```
36
+
37
+ ### BBox
38
+ ```typescript
39
+ interface BBox {
40
+ x: number;
41
+ y: number;
42
+ width: number;
43
+ height: number;
44
+ }
45
+ ```
46
+
47
+ ### Viewport
48
+ ```typescript
49
+ interface Viewport {
50
+ width: number;
51
+ height: number;
52
+ }
53
+ ```
54
+
55
+ ### VisualCues
56
+ ```typescript
57
+ interface VisualCues {
58
+ is_primary: boolean;
59
+ background_color_name: string | null;
60
+ is_clickable: boolean;
61
+ }
62
+ ```
63
+
64
+ ## Action Types
65
+
66
+ ### ActionResult
67
+ ```typescript
68
+ interface ActionResult {
69
+ success: boolean;
70
+ duration_ms: number;
71
+ outcome?: "navigated" | "dom_updated" | "no_change" | "error";
72
+ url_changed?: boolean;
73
+ snapshot_after?: Snapshot; // Optional in Week 1, required in Week 2
74
+ error?: {
75
+ code: string;
76
+ reason: string;
77
+ recovery_hint?: string;
78
+ };
79
+ }
80
+ ```
81
+
82
+ **Fields**:
83
+ - `success`: True if action completed successfully
84
+ - `duration_ms`: Time taken in milliseconds
85
+ - `outcome`: What happened after action (navigation, DOM update, no change, error)
86
+ - `url_changed`: True if URL changed (for navigation detection)
87
+ - `snapshot_after`: Post-action snapshot (optional in MVP, required for recorder)
88
+ - `error`: Error details if action failed
89
+
90
+ ## Wait & Assert Types
91
+
92
+ ### WaitResult
93
+ ```typescript
94
+ interface WaitResult {
95
+ found: boolean;
96
+ element?: Element;
97
+ duration_ms: number;
98
+ timeout: boolean;
99
+ }
100
+ ```
101
+
102
+ **Fields**:
103
+ - `found`: True if element was found
104
+ - `element`: Found element (if found)
105
+ - `duration_ms`: Time taken to find (or timeout)
106
+ - `timeout`: True if wait timed out
107
+
108
+ ### AssertionError
109
+ ```typescript
110
+ class AssertionError extends Error {
111
+ predicate: string | object;
112
+ timeout: number;
113
+ element?: Element;
114
+ }
115
+ ```
116
+
117
+ ## Trace Types (for Recorder)
118
+
119
+ ### Trace
120
+ ```typescript
121
+ interface Trace {
122
+ version: string; // "1.0.0"
123
+ created_at: string; // ISO 8601
124
+ start_url: string;
125
+ steps: TraceStep[];
126
+ }
127
+ ```
128
+
129
+ ### TraceStep
130
+ ```typescript
131
+ interface TraceStep {
132
+ ts: number; // Timestamp (milliseconds since start)
133
+ type: "navigation" | "click" | "type" | "press" | "wait" | "assert";
134
+ selector?: string; // Semantic selector (inferred)
135
+ element_id?: number; // Element ID
136
+ text?: string; // For type actions (may be masked)
137
+ key?: string; // For press actions
138
+ url?: string; // For navigation
139
+ snapshot?: Snapshot; // Optional: snapshot at this step
140
+ }
141
+ ```
142
+
143
+ **Step Types**:
144
+ - `navigation`: `goto(url)`
145
+ - `click`: Click on element
146
+ - `type`: Type text into element
147
+ - `press`: Press keyboard key
148
+ - `wait`: Wait for element/predicate
149
+ - `assert`: Assertion check
150
+
151
+ ## Query Types
152
+
153
+ ### QuerySelector
154
+ ```typescript
155
+ // String DSL
156
+ type QuerySelectorString = string; // e.g., "role=button text~'Sign in'"
157
+
158
+ // Structured object
159
+ interface QuerySelectorObject {
160
+ role?: string;
161
+ text?: string | RegExp;
162
+ name?: string | RegExp;
163
+ clickable?: boolean;
164
+ isPrimary?: boolean;
165
+ importance?: number | { min?: number; max?: number };
166
+ }
167
+
168
+ type QuerySelector = QuerySelectorString | QuerySelectorObject;
169
+ ```
170
+
171
+ ## Python Equivalents (Pydantic)
172
+
173
+ ```python
174
+ from pydantic import BaseModel
175
+ from typing import Optional, List, Union
176
+ from datetime import datetime
177
+
178
+ class BBox(BaseModel):
179
+ x: float
180
+ y: float
181
+ width: float
182
+ height: float
183
+
184
+ class Viewport(BaseModel):
185
+ width: float
186
+ height: float
187
+
188
+ class VisualCues(BaseModel):
189
+ is_primary: bool
190
+ background_color_name: Optional[str]
191
+ is_clickable: bool
192
+
193
+ class Element(BaseModel):
194
+ id: int
195
+ role: str
196
+ text: Optional[str]
197
+ importance: int
198
+ bbox: BBox
199
+ visual_cues: VisualCues
200
+ in_viewport: bool = True
201
+ is_occluded: bool = False
202
+ z_index: int = 0
203
+
204
+ class Snapshot(BaseModel):
205
+ status: str # "success" | "error"
206
+ timestamp: Optional[str] = None
207
+ url: str
208
+ viewport: Optional[Viewport] = None
209
+ elements: List[Element]
210
+ screenshot: Optional[str] = None
211
+ screenshot_format: Optional[str] = None
212
+ error: Optional[str] = None
213
+ requires_license: Optional[bool] = None
214
+
215
+ class ActionResult(BaseModel):
216
+ success: bool
217
+ duration_ms: int
218
+ outcome: Optional[str] = None
219
+ url_changed: Optional[bool] = None
220
+ snapshot_after: Optional[Snapshot] = None
221
+ error: Optional[dict] = None
222
+
223
+ class WaitResult(BaseModel):
224
+ found: bool
225
+ element: Optional[Element] = None
226
+ duration_ms: int
227
+ timeout: bool
228
+
229
+ class TraceStep(BaseModel):
230
+ ts: int
231
+ type: str
232
+ selector: Optional[str] = None
233
+ element_id: Optional[int] = None
234
+ text: Optional[str] = None
235
+ key: Optional[str] = None
236
+ url: Optional[str] = None
237
+ snapshot: Optional[Snapshot] = None
238
+
239
+ class Trace(BaseModel):
240
+ version: str
241
+ created_at: str
242
+ start_url: str
243
+ steps: List[TraceStep]
244
+ ```
245
+
246
+ ## Type Validation Rules
247
+
248
+ 1. **Required Fields**: Must be present and non-null
249
+ 2. **Optional Fields**: May be omitted or null
250
+ 3. **Type Coercion**: Numbers should be validated (no NaN, Infinity)
251
+ 4. **Enum Values**: String enums must match exactly
252
+ 5. **Array Bounds**: Elements array should be validated (not empty for success status)
253
+
254
+ ## Compatibility Notes
255
+
256
+ - SDKs should handle missing optional fields gracefully
257
+ - Default values should match extension behavior
258
+ - Type coercion should be minimal (prefer validation errors)
259
+