writetrack 0.5.0 → 0.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 +90 -16
- package/dist/browser/index.js +1 -1
- package/dist/ckeditor/index.d.ts +4 -0
- package/dist/ckeditor/index.js +1 -1
- package/dist/esm/index.d.ts +35 -5
- package/dist/esm/index.js +1 -1
- package/dist/esm/verify.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/prosemirror/index.d.ts +4 -0
- package/dist/prosemirror/index.js +1 -1
- package/dist/quill/index.d.ts +4 -0
- package/dist/quill/index.js +1 -1
- package/dist/react/index.d.ts +12 -0
- package/dist/react/index.js +1 -1
- package/dist/tiptap/index.d.ts +4 -0
- package/dist/tiptap/index.js +1 -1
- package/dist/vue/index.d.ts +12 -0
- package/dist/vue/index.js +1 -1
- package/dist/writetrack.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@ Detect AI-generated and pasted text through keystroke dynamics.
|
|
|
4
4
|
|
|
5
5
|
WriteTrack analyzes _how_ text was entered, not what was written. Human typing has natural variation in timing, rhythm, and corrections. Pasted or AI-generated text arrives all at once with no behavioral fingerprint. WriteTrack captures the difference.
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- **0** dependencies
|
|
7
|
+
- **~100KB** gzipped (15KB JS + 86KB WASM)
|
|
8
|
+
- **0** runtime dependencies
|
|
9
9
|
- **<1ms** per keystroke
|
|
10
10
|
- **100%** client-side
|
|
11
11
|
|
|
@@ -15,28 +15,64 @@ WriteTrack analyzes _how_ text was entered, not what was written. Human typing h
|
|
|
15
15
|
npm install writetrack
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
Then register for a free trial:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx writetrack init
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
## Quick Start
|
|
19
25
|
|
|
20
26
|
```typescript
|
|
21
27
|
import { WriteTrack } from 'writetrack';
|
|
22
28
|
|
|
23
29
|
const responseField = document.getElementById('response-field')!;
|
|
24
|
-
const tracker = new WriteTrack(
|
|
30
|
+
const tracker = new WriteTrack({
|
|
31
|
+
target: responseField,
|
|
32
|
+
license: process.env.WRITETRACK_LICENSE_KEY, // omit for dev/demo mode
|
|
33
|
+
});
|
|
25
34
|
|
|
26
35
|
tracker.start();
|
|
27
36
|
|
|
28
37
|
// User types...
|
|
29
38
|
|
|
30
39
|
// Collect captured data
|
|
31
|
-
const
|
|
32
|
-
const
|
|
40
|
+
const data = tracker.getData();
|
|
41
|
+
const analysis = await tracker.getAnalysis();
|
|
33
42
|
|
|
34
43
|
tracker.stop();
|
|
35
44
|
```
|
|
36
45
|
|
|
37
|
-
Works with any text input, textarea, or contenteditable element.
|
|
46
|
+
Works with any text input, textarea, or contenteditable element. TypeScript definitions included.
|
|
47
|
+
|
|
48
|
+
## Framework Integrations
|
|
49
|
+
|
|
50
|
+
First-party bindings available as subpath exports:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { useWriteTrack } from 'writetrack/react';
|
|
54
|
+
import { useWriteTrack } from 'writetrack/vue';
|
|
55
|
+
import { WriteTrackExtension } from 'writetrack/tiptap';
|
|
56
|
+
import { WriteTrackPlugin } from 'writetrack/ckeditor';
|
|
57
|
+
import { WriteTrackPlugin } from 'writetrack/prosemirror';
|
|
58
|
+
import { WriteTrackModule } from 'writetrack/quill';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Output Sinks
|
|
62
|
+
|
|
63
|
+
Stream session data to your analytics stack via `.pipe()`:
|
|
38
64
|
|
|
39
|
-
|
|
65
|
+
```typescript
|
|
66
|
+
import { webhook, datadog, segment, opentelemetry } from 'writetrack/pipes';
|
|
67
|
+
|
|
68
|
+
tracker
|
|
69
|
+
.pipe(webhook({ url: '/api/writetrack' }))
|
|
70
|
+
.pipe(datadog({ client: dd }))
|
|
71
|
+
.pipe(segment({ client: analytics }))
|
|
72
|
+
.pipe(opentelemetry({ tracer }));
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## What It Captures
|
|
40
76
|
|
|
41
77
|
WriteTrack instruments your text inputs and records the behavioral signals behind every keystroke:
|
|
42
78
|
|
|
@@ -45,8 +81,9 @@ WriteTrack instruments your text inputs and records the behavioral signals behin
|
|
|
45
81
|
- **Correction patterns** — backspaces, rewrites, hesitation
|
|
46
82
|
- **Clipboard events** — paste, copy, cut with content and context
|
|
47
83
|
- **Selection events** — text selections via mouse, keyboard, or programmatic
|
|
84
|
+
- **Composition events** — IME input for CJK and other non-Latin scripts
|
|
48
85
|
|
|
49
|
-
## Use
|
|
86
|
+
## Use Cases
|
|
50
87
|
|
|
51
88
|
**Education** — Flag essays that were pasted rather than composed. Give instructors behavioral context alongside content.
|
|
52
89
|
|
|
@@ -62,6 +99,20 @@ WriteTrack instruments your text inputs and records the behavioral signals behin
|
|
|
62
99
|
new WriteTrack(options: WriteTrackOptions | HTMLElement)
|
|
63
100
|
```
|
|
64
101
|
|
|
102
|
+
### Options
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
interface WriteTrackOptions {
|
|
106
|
+
target: HTMLElement;
|
|
107
|
+
license?: string; // Omit for development/demo mode
|
|
108
|
+
userId?: string; // Opaque user identifier, included in output metadata
|
|
109
|
+
contentId?: string; // Opaque document identifier, included in output metadata
|
|
110
|
+
metadata?: Record<string, unknown>; // Arbitrary metadata, included in output
|
|
111
|
+
wasmUrl?: string; // Custom URL for the WASM analysis binary
|
|
112
|
+
persist?: boolean; // Enable IndexedDB persistence (requires contentId)
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
65
116
|
### Methods
|
|
66
117
|
|
|
67
118
|
| Method | Returns | Description |
|
|
@@ -74,6 +125,7 @@ new WriteTrack(options: WriteTrackOptions | HTMLElement)
|
|
|
74
125
|
| `getClipboardEvents()` | `ClipboardEvent[]` | Paste/copy/cut events |
|
|
75
126
|
| `getSelectionEvents()` | `SelectionEvent[]` | Text selection events |
|
|
76
127
|
| `getUndoRedoEvents()` | `UndoRedoEvent[]` | Undo/redo events |
|
|
128
|
+
| `getCompositionEvents()` | `CompositionEvent[]` | IME composition events |
|
|
77
129
|
| `getProgrammaticInsertionEvents()` | `ProgrammaticInsertionEvent[]` | Programmatic insertion events |
|
|
78
130
|
| `getSessionDuration()` | `number` | Session duration in ms |
|
|
79
131
|
| `getKeystrokeCount()` | `number` | Total keystrokes captured |
|
|
@@ -83,18 +135,36 @@ new WriteTrack(options: WriteTrackOptions | HTMLElement)
|
|
|
83
135
|
| `on(event, handler)` | `this` | Register an event listener |
|
|
84
136
|
| `isLicenseValid()` | `boolean` | Whether license is valid |
|
|
85
137
|
| `isLicenseValidated()` | `boolean` | Whether license check has completed |
|
|
86
|
-
| `
|
|
138
|
+
| `isTargetDetached()` | `boolean` | Whether the target element was removed |
|
|
139
|
+
| `clearPersistedData()` | `Promise<void>` | Clear IndexedDB persisted session |
|
|
87
140
|
|
|
88
|
-
###
|
|
141
|
+
### Properties
|
|
142
|
+
|
|
143
|
+
| Property | Type | Description |
|
|
144
|
+
| ----------- | --------------- | ------------------------------------------- |
|
|
145
|
+
| `wasmReady` | `boolean` | Whether WASM module is loaded (getter) |
|
|
146
|
+
| `ready` | `Promise<void>` | Resolves when persisted session is restored |
|
|
147
|
+
|
|
148
|
+
### Server-Side Analysis
|
|
149
|
+
|
|
150
|
+
Analyze previously captured data without a DOM element:
|
|
89
151
|
|
|
90
152
|
```typescript
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
153
|
+
import { analyzeEvents } from 'writetrack';
|
|
154
|
+
|
|
155
|
+
const data = JSON.parse(savedSessionJson); // from your API, database, etc.
|
|
156
|
+
const analysis = await analyzeEvents(data, {
|
|
157
|
+
licenseKey: process.env.WRITETRACK_LICENSE_KEY,
|
|
158
|
+
});
|
|
95
159
|
```
|
|
96
160
|
|
|
97
|
-
|
|
161
|
+
### Exported Types
|
|
162
|
+
|
|
163
|
+
Full type definitions are included in the package:
|
|
164
|
+
|
|
165
|
+
**Functions:** `analyzeEvents`, `formatIndicator`, `getHighResolutionTime`
|
|
166
|
+
|
|
167
|
+
**Types:** `KeystrokeEvent`, `ClipboardEvent`, `SelectionEvent`, `UndoRedoEvent`, `CompositionEvent`, `ProgrammaticInsertionEvent`, `ModifierState`, `WriteTrackDataSchema`, `DataQualityMetrics`, `SessionMetadata`, `SessionAnalysis`, `SessionReport`, `IndicatorOutput`, `AnalyzeEventsOptions`, `WriteTrackSink`
|
|
98
168
|
|
|
99
169
|
## Browser Support
|
|
100
170
|
|
|
@@ -109,7 +179,11 @@ All features including license verification work at these versions. License vali
|
|
|
109
179
|
|
|
110
180
|
## Privacy
|
|
111
181
|
|
|
112
|
-
WriteTrack runs entirely client-side.
|
|
182
|
+
WriteTrack runs entirely client-side. No servers, no tracking, no external requests. Event data (including paste content and selected text) stays in the browser unless you explicitly export it via `getData()` or an output sink.
|
|
183
|
+
|
|
184
|
+
## Documentation
|
|
185
|
+
|
|
186
|
+
Full documentation at [writetrack.dev/docs](https://writetrack.dev/docs).
|
|
113
187
|
|
|
114
188
|
## License
|
|
115
189
|
|