Skip to content

Commit fe8eb1c

Browse files
committed
initial commit sentience sdk for TypeScript
0 parents  commit fe8eb1c

6,395 files changed

Lines changed: 1240394 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Sentience TypeScript SDK
2+
3+
**Status**: ✅ Week 1 Complete
4+
5+
TypeScript SDK for Sentience AI Agent Browser Automation.
6+
7+
## Installation
8+
9+
```bash
10+
cd sdk-ts
11+
npm install
12+
npm run build
13+
```
14+
15+
## Quick Start
16+
17+
```typescript
18+
import { SentienceBrowser, snapshot, find, click } from './src';
19+
20+
async function main() {
21+
const browser = new SentienceBrowser(undefined, false);
22+
23+
try {
24+
await browser.start();
25+
26+
await browser.getPage().goto('https://example.com');
27+
await browser.getPage().waitForLoadState('networkidle');
28+
29+
// Take snapshot
30+
const snap = await snapshot(browser);
31+
console.log(`Found ${snap.elements.length} elements`);
32+
33+
// Find and click a link
34+
const link = find(snap, 'role=link');
35+
if (link) {
36+
const result = await click(browser, link.id);
37+
console.log(`Click success: ${result.success}`);
38+
}
39+
} finally {
40+
await browser.close();
41+
}
42+
}
43+
```
44+
45+
## Features
46+
47+
### Day 2: Browser Harness
48+
- `SentienceBrowser` - Launch Playwright with extension loaded
49+
- Automatic extension loading and verification
50+
51+
### Day 3: Snapshot
52+
- `snapshot(browser, options)` - Capture page state
53+
- TypeScript types for type safety
54+
55+
### Day 4: Query Engine
56+
- `query(snapshot, selector)` - Find elements matching selector
57+
- `find(snapshot, selector)` - Find single best match
58+
- String DSL: `"role=button text~'Sign in'"`
59+
60+
### Day 5: Actions
61+
- `click(browser, elementId)` - Click element
62+
- `typeText(browser, elementId, text)` - Type into element
63+
- `press(browser, key)` - Press keyboard key
64+
65+
### Day 6: Wait & Assert
66+
- `waitFor(browser, selector, timeout)` - Wait for element
67+
- `expect(browser, selector)` - Assertion helper
68+
- `.toExist()`
69+
- `.toBeVisible()`
70+
- `.toHaveText(text)`
71+
- `.toHaveCount(n)`
72+
73+
## Examples
74+
75+
See `examples/` directory:
76+
- `hello.ts` - Extension bridge verification
77+
- `basic-agent.ts` - Basic snapshot
78+
- `query-demo.ts` - Query engine
79+
- `wait-and-click.ts` - Wait and actions
80+
81+
Run examples:
82+
```bash
83+
npm run example:hello
84+
npm run example:basic
85+
```
86+
87+
## Testing
88+
89+
```bash
90+
npm test
91+
```
92+
93+
## Documentation
94+
95+
- API Contract: `../spec/SNAPSHOT_V1.md`
96+
- Type Definitions: `../spec/sdk-types.md`

examples/basic-agent.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Day 3 Example: Basic snapshot functionality
3+
*/
4+
5+
import { SentienceBrowser, snapshot } from '../src';
6+
import * as fs from 'fs';
7+
8+
async function main() {
9+
const browser = new SentienceBrowser(undefined, false);
10+
11+
try {
12+
await browser.start();
13+
14+
// Navigate to a test page
15+
await browser.getPage().goto('https://example.com');
16+
await browser.getPage().waitForLoadState('networkidle');
17+
18+
// Take snapshot
19+
const snap = await snapshot(browser);
20+
21+
console.log(`Status: ${snap.status}`);
22+
console.log(`URL: ${snap.url}`);
23+
console.log(`Elements found: ${snap.elements.length}`);
24+
25+
// Show top 5 elements
26+
console.log('\nTop 5 elements:');
27+
snap.elements.slice(0, 5).forEach((el, i) => {
28+
console.log(`${i + 1}. [${el.role}] ${el.text || '(no text)'} (importance: ${el.importance})`);
29+
});
30+
31+
// Save snapshot
32+
fs.writeFileSync('snapshot_example.json', JSON.stringify(snap, null, 2));
33+
console.log('\n✅ Snapshot saved to snapshot_example.json');
34+
} finally {
35+
await browser.close();
36+
}
37+
}
38+
39+
main().catch(console.error);
40+

examples/hello.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Day 2 Example: Verify extension bridge is loaded
3+
*/
4+
5+
import { SentienceBrowser } from '../src';
6+
7+
async function main() {
8+
const browser = new SentienceBrowser(undefined, false);
9+
10+
try {
11+
await browser.start();
12+
13+
// Check if extension API is available
14+
const bridgeOk = await browser.getPage().evaluate(
15+
() => typeof (window as any).sentience !== 'undefined'
16+
);
17+
18+
console.log(`bridge_ok=${bridgeOk}`);
19+
20+
if (bridgeOk) {
21+
console.log('✅ Extension loaded successfully!');
22+
} else {
23+
console.log('❌ Extension not loaded');
24+
}
25+
} finally {
26+
await browser.close();
27+
}
28+
}
29+
30+
main().catch(console.error);
31+

examples/query-demo.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Day 4 Example: Query engine demonstration
3+
*/
4+
5+
import { SentienceBrowser, snapshot, query, find } from '../src';
6+
7+
async function main() {
8+
const browser = new SentienceBrowser(undefined, false);
9+
10+
try {
11+
await browser.start();
12+
13+
// Navigate to a page with links
14+
await browser.getPage().goto('https://example.com');
15+
await browser.getPage().waitForLoadState('networkidle');
16+
17+
const snap = await snapshot(browser);
18+
19+
// Query examples
20+
console.log('=== Query Examples ===\n');
21+
22+
// Find all buttons
23+
const buttons = query(snap, 'role=button');
24+
console.log(`Found ${buttons.length} buttons`);
25+
26+
// Find all links
27+
const links = query(snap, 'role=link');
28+
console.log(`Found ${links.length} links`);
29+
30+
// Find clickable elements
31+
const clickables = query(snap, 'clickable=true');
32+
console.log(`Found ${clickables.length} clickable elements`);
33+
34+
// Find element with text containing "More"
35+
const moreLink = find(snap, "text~'More'");
36+
if (moreLink) {
37+
console.log(`\nFound 'More' link: ${moreLink.text} (id: ${moreLink.id})`);
38+
} else {
39+
console.log('\nNo "More" link found');
40+
}
41+
42+
// Complex query: clickable links
43+
const clickableLinks = query(snap, 'role=link clickable=true');
44+
console.log(`\nFound ${clickableLinks.length} clickable links`);
45+
} finally {
46+
await browser.close();
47+
}
48+
}
49+
50+
main().catch(console.error);
51+

examples/wait-and-click.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Day 5-6 Example: Wait for element and click
3+
*/
4+
5+
import { SentienceBrowser, snapshot, find, waitFor, click, expect } from '../src';
6+
7+
async function main() {
8+
const browser = new SentienceBrowser(undefined, false);
9+
10+
try {
11+
await browser.start();
12+
13+
// Navigate to example.com
14+
await browser.getPage().goto('https://example.com');
15+
await browser.getPage().waitForLoadState('networkidle');
16+
17+
// Take initial snapshot
18+
const snap = await snapshot(browser);
19+
20+
// Find a link
21+
const link = find(snap, 'role=link');
22+
23+
if (link) {
24+
console.log(`Found link: ${link.text} (id: ${link.id})`);
25+
26+
// Click it
27+
const result = await click(browser, link.id);
28+
console.log(`Click result: success=${result.success}, outcome=${result.outcome}`);
29+
30+
// Wait for navigation
31+
await browser.getPage().waitForLoadState('networkidle');
32+
console.log(`New URL: ${browser.getPage().url()}`);
33+
} else {
34+
console.log('No link found');
35+
}
36+
37+
// Example: Wait for element using waitFor
38+
console.log('\n=== Wait Example ===');
39+
await browser.getPage().goto('https://example.com');
40+
await browser.getPage().waitForLoadState('networkidle');
41+
42+
const waitResult = await waitFor(browser, 'role=link', 5000);
43+
if (waitResult.found) {
44+
console.log(`✅ Found element after ${waitResult.duration_ms}ms`);
45+
} else {
46+
console.log(`❌ Element not found (timeout: ${waitResult.timeout})`);
47+
}
48+
49+
// Example: Expect assertion
50+
console.log('\n=== Expect Example ===');
51+
try {
52+
const element = await expect(browser, 'role=link').toExist(5000);
53+
console.log(`✅ Element exists: ${element.text}`);
54+
} catch (e: any) {
55+
console.log(`❌ Assertion failed: ${e.message}`);
56+
}
57+
} finally {
58+
await browser.close();
59+
}
60+
}
61+
62+
main().catch(console.error);
63+

node_modules/.bin/acorn

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/baseline-browser-mapping

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/browserslist

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/create-jest

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/esparse

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)