@incodetech/core 0.0.0-dev-20260928-e8e00ca9 → 0.0.0-dev-20260928-85249f77

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 (90) hide show
  1. package/dist/{BrowserDiagnosticsCryptoProvider-CglolaLX.esm.js → BrowserDiagnosticsCryptoProvider-BuzqvbhN.esm.js} +6 -24
  2. package/dist/{FaceDetectionProvider-ZWuTisXf.esm.js → FaceDetectionProvider-CSjiXOo7.esm.js} +7 -7
  3. package/dist/{MotionSensorProvider-Bti5f6op.esm.js → MotionSensorProvider-1Ul_1GPn.esm.js} +1 -1
  4. package/dist/ae-signature.esm.js +1 -1
  5. package/dist/{apiError-DqxsUXGC.esm.js → apiError-DmDlw1pl.esm.js} +1 -1
  6. package/dist/authentication.d.ts +2 -2
  7. package/dist/authentication.esm.js +2 -2
  8. package/dist/{authenticationManager-DgCLrxXN.esm.js → authenticationManager-B9l6NeDe.esm.js} +4 -4
  9. package/dist/{authenticationManager-B-MR_-Si.d.ts → authenticationManager-DE40FMUU.d.ts} +1 -1
  10. package/dist/{authenticationStateMachine-DECsoldb.esm.js → authenticationStateMachine-BGme0djA.esm.js} +3 -3
  11. package/dist/camera.esm.js +1 -1
  12. package/dist/consent.d.ts +1 -1
  13. package/dist/{consentManager-Cv_0QKLD.d.ts → consentManager-CTdFloVJ.d.ts} +1 -1
  14. package/dist/{createCameraCycleOwnership-BjoMVvya.esm.js → createCameraCycleOwnership-P1AtkhRJ.esm.js} +6 -1
  15. package/dist/{deepsightLoader-DidR7w-7.esm.js → deepsightLoader-BY2NIp7n.esm.js} +6 -6
  16. package/dist/document-capture.d.ts +1 -1
  17. package/dist/document-capture.esm.js +2 -2
  18. package/dist/{documentCaptureManager-CbAGkHWh.d.ts → documentCaptureManager-C8eO0hbv.d.ts} +1 -1
  19. package/dist/{documentCaptureManager-7e1RLKhG.esm.js → documentCaptureManager-DRAn04PI.esm.js} +1 -1
  20. package/dist/{documentCaptureStateMachine-DyJb_vDQ.esm.js → documentCaptureStateMachine-BS9VBtqN.esm.js} +2 -2
  21. package/dist/dynamic-forms.esm.js +2 -2
  22. package/dist/{dynamicFormsManager-B5GSLZvO.esm.js → dynamicFormsManager-CTJzsDqC.esm.js} +1 -1
  23. package/dist/{dynamicFormsStateMachine-DAq-HoCA.esm.js → dynamicFormsStateMachine-8oOTouxq.esm.js} +1 -1
  24. package/dist/ekyb.esm.js +3 -3
  25. package/dist/{ekybManager-7ljnpTt2.esm.js → ekybManager-CKNCVYs7.esm.js} +1 -1
  26. package/dist/{ekybStateMachine-CD8oLnoa.esm.js → ekybStateMachine-BDQHv558.esm.js} +1 -1
  27. package/dist/electronic-signature.esm.js +1 -1
  28. package/dist/{electronicSignatureManager-r2Zci23-.esm.js → electronicSignatureManager-BbgLJk1x.esm.js} +1 -1
  29. package/dist/extensibility.d.ts +9 -9
  30. package/dist/extensibility.esm.js +12 -12
  31. package/dist/{faceCaptureManagerFactory-OSygJ72q.esm.js → faceCaptureManagerFactory-DG4z3rkR.esm.js} +3 -3
  32. package/dist/{faceCaptureManagerFactory-BgbP5N1j.d.ts → faceCaptureManagerFactory-s0Vhw_wP.d.ts} +80 -40
  33. package/dist/{faceCaptureSetup-DSvOibxj.esm.js → faceCaptureSetup-GzW2oNiM.esm.js} +261 -58
  34. package/dist/{feature-management-BhzWEsyZ.esm.js → feature-management-02JHuEhD.esm.js} +1 -1
  35. package/dist/feature-management.esm.js +1 -1
  36. package/dist/flow.esm.js +3 -3
  37. package/dist/{flowCompletionService-B-ri1Pvq.esm.js → flowCompletionService-BAg6qc6d.esm.js} +1 -1
  38. package/dist/{flowServices-C62Eyo7N.esm.js → flowServices-Dc-EUuwB.esm.js} +5 -5
  39. package/dist/geolocation.esm.js +2 -2
  40. package/dist/{geolocationManager-BU4OLtRY.esm.js → geolocationManager-v0LZK1kW.esm.js} +1 -1
  41. package/dist/{geolocationStateMachine-D8UrSeXQ.esm.js → geolocationStateMachine-DfdsEj7L.esm.js} +1 -1
  42. package/dist/id-ocr.d.ts +1 -1
  43. package/dist/id-selfie-flow.esm.js +9 -10
  44. package/dist/id.d.ts +2 -2
  45. package/dist/id.esm.js +4 -4
  46. package/dist/{idCaptureDefaults-B6gkShby.esm.js → idCaptureDefaults-Ba-m1uO3.esm.js} +3 -3
  47. package/dist/{idCaptureManager-DIT7ZyEa.esm.js → idCaptureManager-Bfrj7DvH.esm.js} +6 -5
  48. package/dist/{idCaptureManager-poTdJI74.d.ts → idCaptureManager-DfHdJLmj.d.ts} +29 -5
  49. package/dist/{idCaptureServices-Cl67CI_t.esm.js → idCaptureServices-DKeVf0Gu.esm.js} +67 -12
  50. package/dist/{idCaptureStateMachine-BADMFRXg.esm.js → idCaptureStateMachine-BL3MnDOu.esm.js} +222 -77
  51. package/dist/{idOcrManager-DT3kPIB3.d.ts → idOcrManager-BTdHlJ9D.d.ts} +1 -1
  52. package/dist/identity-reuse.d.ts +1 -1
  53. package/dist/{identityReuseManager-x2QG6QAm.d.ts → identityReuseManager-D0-4bAeK.d.ts} +1 -1
  54. package/dist/index.d.ts +1 -1
  55. package/dist/index.esm.js +1 -1
  56. package/dist/mandatory-consent.d.ts +1 -1
  57. package/dist/{mandatoryConsentManager-DzIGk6u7.d.ts → mandatoryConsentManager-S94mjtTG.d.ts} +1 -1
  58. package/dist/{multipartRecordingService-Dw0scizg.esm.js → multipartRecordingService-mwKFTlhR.esm.js} +42 -1
  59. package/dist/{permissionGuards-DAyjPT2R.esm.js → permissionGuards-DS36X5Hh.esm.js} +1 -1
  60. package/dist/{permissionServices-DIaG8BlW.esm.js → permissionServices-B9IqVf3c.esm.js} +2 -2
  61. package/dist/qe-signature.esm.js +1 -1
  62. package/dist/{runChildModule-CoWvzHhB.esm.js → runChildModule-DQbERvPv.esm.js} +1 -1
  63. package/dist/{safeStorage-C511Hltw.esm.js → safeStorage-Q_iUpxa8.esm.js} +1 -1
  64. package/dist/{sdkVersion-sSFpdmZk.esm.js → sdkVersion-kGZmwBhf.esm.js} +1 -1
  65. package/dist/selfie.d.ts +2 -2
  66. package/dist/selfie.esm.js +7 -7
  67. package/dist/{selfieManager-Be-moOeO.esm.js → selfieManager-B-F-lrAH.esm.js} +4 -4
  68. package/dist/{selfieManager-oSsnyvBl.d.ts → selfieManager-PVc2k2Oq.d.ts} +1 -1
  69. package/dist/{selfieStateMachine-0bHX1R9_.esm.js → selfieStateMachine--KjoErrq.esm.js} +2 -2
  70. package/dist/{session-DjUhUWYA.esm.js → session-Bb5KuwEu.esm.js} +3 -3
  71. package/dist/session.esm.js +4 -4
  72. package/dist/{sessionInitializer-_BmsjkUB.esm.js → sessionInitializer-D-gzxDwN.esm.js} +4 -4
  73. package/dist/{setup-CHHZ8BBM.d.ts → setup-BdeKbA9K.d.ts} +4 -17
  74. package/dist/{setup-D7B4g7Jc.esm.js → setup-Cb7Ws1HA.esm.js} +8 -58
  75. package/dist/{tri-4RsGrIt6.esm.js → tri-xzRLIIMN.esm.js} +0 -10
  76. package/dist/tri.esm.js +1 -1
  77. package/dist/{trueSightService-Bb116pCE.esm.js → trueSightService-D8dk4ZID.esm.js} +16 -554
  78. package/dist/video-selfie.esm.js +5 -5
  79. package/dist/{videoSelfieCameraWarmer-CeZLd5w_.esm.js → videoSelfieCameraWarmer-CkdLS8NK.esm.js} +5 -5
  80. package/dist/{warmup-REsua-sF.esm.js → warmup-DLq_t-Zu.esm.js} +5 -0
  81. package/dist/wasm.d.ts +1 -1
  82. package/dist/wasm.esm.js +3 -3
  83. package/dist/{wasmDsFlagSync-Czjlp68o.esm.js → wasmDsFlagSync-DyNj8RY_.esm.js} +1 -1
  84. package/dist/workflow.esm.js +15 -15
  85. package/package.json +2 -7
  86. package/dist/FaceDetectionProvider-Di1DmZu1.d.ts +0 -36
  87. package/dist/StreamCanvasProcessingSession-CBnbTnOr.esm.js +0 -42
  88. package/dist/personhood.d.ts +0 -537
  89. package/dist/personhood.esm.js +0 -1574
  90. package/dist/types-CfuWgAi-.d.ts +0 -1
@@ -1,537 +0,0 @@
1
- import { A as StateMachine, i as ActorRefFrom, l as AnyStateMachine } from "./spawn-D9jgw9pW.js";
2
- import { t as Manager } from "./Manager-C9T5amUN.js";
3
- import "./Actor-DpTj5PFb.js";
4
- import { y as IncodeCanvas } from "./createFaceAvatar-DXgmQmQy.js";
5
- import { i as IStorageCapability, t as IWasmUtilCapability } from "./IWasmUtilCapability-VC40Kx9N.js";
6
- import { n as PermissionStatus, t as PermissionResult } from "./types-BEwVKkLJ.js";
7
- import { n as DetectionStatus } from "./types-Ch-wwRAh.js";
8
- import { n as DeepsightService, t as StreamCanvasCapture } from "./StreamCanvasCapture-CeBBJ_RC.js";
9
- import { t as FaceDetectionProvider } from "./FaceDetectionProvider-Di1DmZu1.js";
10
- import { t as CameraStream } from "./camera-9wWD-pwg.js";
11
- //#region src/modules/personhood/types.d.ts
12
- /**
13
- * Head pose (degrees) computed per-frame from the WASM face detector.
14
- * Used internally by the personhood detection actor to accumulate the
15
- * yaw/pitch range that feeds the server-side `headMotion` spoof check.
16
- *
17
- * Re-exported from `@incodetech/core/personhood` as a convenience type
18
- * for integrators running their own face-tracking pipelines (e.g.
19
- * MediaPipe FaceLandmarker) that want to share a pose shape with
20
- * other code that consumes personhood internals — the SDK itself
21
- * does not expose a runtime pose stream.
22
- *
23
- * `faceSizeRatio` is an orientation-invariant 0–1 proxy for how close
24
- * the user is to the camera, computed by the producer as
25
- * `sqrt(face.width * face.height) / min(frame.width, frame.height)`.
26
- * Same value on landscape (laptop) or portrait (phone) cameras since
27
- * the denominator is the frame's *narrower* dimension. Optional —
28
- * absent when the producer doesn't have access to frame size.
29
- */
30
- type HeadPose = {
31
- pitch: number;
32
- yaw: number;
33
- roll: number;
34
- faceSizeRatio?: number;
35
- };
36
- /** Signals we hand back to the integrator alongside the human verdict. */
37
- type DeviceBehavioralSignals = {
38
- /** Visitor fingerprint hash from the Thumbmark provider. */
39
- deviceFingerprint: string;
40
- /** Standard browser / OS info (model, os, browser name + version). */
41
- userAgentClass: string;
42
- /** Matches automation markers (phantom, nightmare, domAutomation, etc.). */
43
- emulator: boolean;
44
- /** `navigator.webdriver` is truthy — chromedriver / geckodriver / playwright. */
45
- webdriver: boolean;
46
- /** Liveness / injection surface reported by local detection. */
47
- headlessHints: readonly string[];
48
- };
49
- /**
50
- * One element of the `spoofCheckResults` array. Carries a single
51
- * anti-spoof / liveness / automation check the on-device pipeline
52
- * ran, with its outcome and (when failed) a short tag explaining
53
- * why. The same shape is sent to `/omni/personhood/verify` and
54
- * exposed on {@link PersonhoodVerdict.spoofCheckResults} so
55
- * integrators and UIs can introspect what passed and what failed
56
- * without parsing the comma-joined `reason` string.
57
- *
58
- * Check ids the SDK currently emits:
59
- * - `physicalAttack` — Deepsight pipeline anti-spoof. Failed
60
- * when `analysisStatus` carries an explicit spoof signal
61
- * (`spoof_suspected`, `injection`, etc.).
62
- * - `virtualCamera` — label-based detection of OBS / ManyCam /
63
- * etc. on the camera track.
64
- * - `motionLiveness` — Deepsight's motion-based liveness check
65
- * (accelerometer + temporal frame analysis).
66
- * - `headMotion` — accumulated yaw + pitch range. Failed
67
- * when below the minimum motion threshold (user held still).
68
- * - `faceDetection` — terminal detection outcome (success vs
69
- * timeout / error).
70
- * - `webdriver` — `navigator.webdriver` is truthy.
71
- * - `emulator` — automation framework markers
72
- * (PhantomJS / Selenium / Nightmare / etc.).
73
- * - `headlessBrowser` — headless-browser fingerprinting hints.
74
- *
75
- * `result: 'unknown'` is reserved for checks that ran but couldn't
76
- * render a definitive verdict (e.g. desktop with no accelerometer
77
- * permission for motion liveness). Absence of evidence is
78
- * intentionally not the same as evidence of a spoof.
79
- *
80
- * `reason` is populated only when `result === 'failed'` and gives
81
- * a short stable tag the integrator's server can pattern-match on:
82
- * the same tags that show up in the verdict's `reason` string
83
- * (`no_motion`, `spoof_suspected`, `virtual_camera`, etc.) plus
84
- * raw underlying values (`analysisStatus` strings, detection
85
- * outcome) where useful.
86
- */
87
- type SpoofCheckResult = {
88
- check: string;
89
- result: 'passed' | 'failed' | 'unknown';
90
- reason?: string;
91
- };
92
- /** On-device liveness outcome — filled in after the detection loop succeeds. */
93
- type LivenessOutcome = {
94
- /** True when the camera stream is a known virtual cam (OBS/ManyCam/etc.). */
95
- virtualCamera: boolean;
96
- /** Opaque Deepsight pipeline check status (string like "PASS"/"FAIL"). */
97
- analysisStatus: string;
98
- /** Deepsight motion status string. */
99
- motionStatus: string;
100
- /** Range of yaw observed during detection (degrees). */
101
- yawRange: number;
102
- /** Range of pitch observed during detection (degrees). */
103
- pitchRange: number;
104
- /**
105
- * Full Deepsight metadata blob from `wasmUtil.getMetadata()`. Opaque
106
- * string (typically a JSON-serialized payload of the pipeline's
107
- * collected signals — frame quality, motion features, environment
108
- * fingerprints, etc.) intended for server-side cross-referencing
109
- * with the evidence record. Empty when the Deepsight pipeline isn't
110
- * available (e.g. WASM init failed).
111
- */
112
- metadata: string;
113
- /**
114
- * Deepsight pipeline state string (e.g. running / completed / error
115
- * substates). Useful for diagnosing why an analysis status came
116
- * back negative — the state often carries the underlying cause that
117
- * `analysisStatus` only summarizes.
118
- */
119
- pipelineState: string;
120
- };
121
- /** Final verdict returned from `/omni/personhood/verify`. */
122
- type PersonhoodVerdict = {
123
- human: boolean;
124
- confidence: number;
125
- evidenceId: string;
126
- /**
127
- * Comma-joined list of failure tags when `human === false`. Same
128
- * tags that appear individually in {@link spoofCheckResults}
129
- * entries' `reason` fields — kept for backward compat and quick
130
- * inspection. Undefined when the verdict is human.
131
- */
132
- reason?: string;
133
- signals: DeviceBehavioralSignals;
134
- /** Present for the on-device path. Absent on server fallback. */
135
- liveness?: LivenessOutcome;
136
- /**
137
- * Per-check breakdown of every anti-spoof / liveness / automation
138
- * gate the on-device pipeline ran. Lets integrators see WHICH
139
- * checks passed or failed instead of having to parse the
140
- * collapsed `reason` string. The same array is the body of the
141
- * `/omni/personhood/verify` POST. Empty on the server-fallback
142
- * path (no on-device pipeline ran).
143
- */
144
- spoofCheckResults: SpoofCheckResult[];
145
- };
146
- type PersonhoodConfig = {
147
- /** Integrator's site key (equivalent to a reCAPTCHA site key). */
148
- siteKey: string;
149
- /**
150
- * OAuth2 client-credentials used to mint the `Authorization: Bearer`
151
- * token for the verify hop (`POST /omni/oauth2/token`,
152
- * `grant_type=client_credentials&scope=openid`). Required for the
153
- * live (non-mock) flow; without them the token fetch fails and the
154
- * flow halts before the camera opens.
155
- *
156
- * ⚠️ These are sent from the browser, so `clientSecret` is exposed to
157
- * anyone who can read the page's source / network traffic. Acceptable
158
- * only where that exposure is tolerable; a server-minted Bearer token
159
- * is the hardened alternative.
160
- */
161
- clientId?: string;
162
- clientSecret?: string;
163
- /**
164
- * Origin of the authorization server that mints the OAuth2 Bearer token
165
- * (e.g. `https://auth.stage.incode.com`). The path is fixed — the token
166
- * is `POST`ed to this origin's own `/oauth2/token`.
167
- *
168
- * When set, the browser calls the auth server DIRECTLY through a
169
- * dedicated HTTP client (topology B): the auth origin is separate from
170
- * the omni `apiURL`, so this is a genuine cross-origin call and the auth
171
- * server must allow the integrator's `Origin` (CORS). The dedicated
172
- * client inherits the omni client's `customHeaders` (notably
173
- * `x-api-key`, which the auth server requires) from the active SDK
174
- * config, so no extra credential plumbing is needed here.
175
- *
176
- * When omitted, the token is minted through the shared omni client at
177
- * `/omni/oauth2/token` — i.e. the omni gateway is expected to front the
178
- * auth server (topology A). Single-origin deployments need not set this.
179
- *
180
- * Only the auth-token hop honors this; the verify hop
181
- * (`/omni/personhood/verify`) always uses the omni `apiURL`.
182
- */
183
- authBaseUrl?: string;
184
- /**
185
- * Minimum confidence required to pass. Default: `0.75`
186
- * (`DEFAULT_PERSONHOOD_THRESHOLD`). Exposed so integrators can tighten or
187
- * loosen gates per use case.
188
- */
189
- threshold?: number;
190
- /**
191
- * When true, `/omni/personhood/verify` is bypassed and a canned verdict
192
- * is returned (the local on-device verdict is used as-is). Defaults to
193
- * `false`. Set to `true` in dev environments where the backend is not
194
- * yet available.
195
- */
196
- mockVerify?: boolean;
197
- /**
198
- * Time-to-live (ms) for cached proofs of the same browser session. Not yet
199
- * enforced at phase 0 (documented for forward-compat).
200
- */
201
- cacheTtlMs?: number;
202
- /** Optional: called every time an interesting signal is observed. */
203
- onSignal?: (event: {
204
- type: 'pose' | 'detection' | 'verdict' | 'error';
205
- payload: unknown;
206
- }) => void;
207
- /** Hides the initial tutorial screen. Default: false. */
208
- showTutorial?: boolean;
209
- /**
210
- * When true, the detection flow auto-completes with whatever frame
211
- * is available after a short hard deadline, regardless of why
212
- * WASM's autocapture criteria didn't fire (user too far, bad
213
- * framing, low light, occlusion, etc). The deadline starts ticking
214
- * the moment the camera produces its first frame — not when
215
- * detection begins — so a slow camera cold-start doesn't eat into
216
- * the user's capture window. Once the deadline lands, the
217
- * provider's best frame (or the most recent processed frame if no
218
- * best-shot was recorded) is pushed through to liveness analysis.
219
- *
220
- * The resulting verdict usually has lower confidence — a non-ideal
221
- * frame gives the detector less signal — but at least produces a
222
- * definitive `human: true | false` outcome instead of leaving the
223
- * modal stuck.
224
- *
225
- * If the camera never produces a frame at all (e.g. the user
226
- * blocked permission mid-flow, browser failed to start the stream)
227
- * this flag does nothing — there's literally no frame to capture
228
- * — and the standard error path applies.
229
- *
230
- * Default: `false`.
231
- */
232
- autoComplete?: boolean;
233
- /**
234
- * Enables Deepsight (injection-attack detection) for the session. The flag is
235
- * handed to the WASM utility API, which latches it on: once any call in the
236
- * session sees `true` the IAD challenges keep running. Leaving it unset (or
237
- * `false`) means the challenges are skipped for the whole session, so never
238
- * hardcode `false` here on a Deepsight-enabled organization.
239
- *
240
- * Default: `false`.
241
- */
242
- ds?: boolean;
243
- };
244
- type PersonhoodDependencies = {
245
- storage: IStorageCapability;
246
- getWasmUtil: () => Promise<IWasmUtilCapability>;
247
- };
248
- declare const PERSONHOOD_ERROR_CODES: {
249
- readonly CAMERA_DENIED: "CAMERA_DENIED";
250
- readonly DETECTION_FAILED: "DETECTION_FAILED";
251
- /**
252
- * The OAuth2 token fetch (`POST /omni/oauth2/token`,
253
- * client-credentials) failed — non-2xx, network error, or no
254
- * `access_token` in the response. The flow halts before the user
255
- * opens the camera so a misconfigured `clientId` / `clientSecret`
256
- * surfaces immediately instead of walking them through a capture we
257
- * can't authenticate the verify hop for.
258
- */
259
- readonly AUTH_TOKEN_FAILED: "AUTH_TOKEN_FAILED";
260
- readonly VERIFY_FAILED: "VERIFY_FAILED";
261
- readonly INJECTION_SUSPECTED: "INJECTION_SUSPECTED";
262
- readonly EMULATOR_DETECTED: "EMULATOR_DETECTED";
263
- readonly TIMEOUT: "TIMEOUT";
264
- readonly UNKNOWN: "UNKNOWN";
265
- };
266
- type PersonhoodErrorCode = (typeof PERSONHOOD_ERROR_CODES)[keyof typeof PERSONHOOD_ERROR_CODES];
267
- //#endregion
268
- //#region src/modules/personhood/personhoodStateMachine.d.ts
269
- type PersonhoodInput = {
270
- config: PersonhoodConfig;
271
- dependencies: PersonhoodDependencies;
272
- };
273
- type PersonhoodMachineContext = {
274
- config: PersonhoodConfig;
275
- dependencies: PersonhoodDependencies;
276
- permissionResult: PermissionResult | 'refresh' | undefined;
277
- /**
278
- * Why the server-fallback path was taken, so `requestServerFallback` reports
279
- * the real cause instead of a hardcoded value. `undefined` means
280
- * `permission_denied` (the original/most common cause).
281
- */
282
- fallbackReason: 'no_camera' | 'permission_denied' | 'unsupported_browser' | undefined;
283
- stream: CameraStream | undefined;
284
- provider: FaceDetectionProvider | undefined;
285
- frameCapturer: StreamCanvasCapture | undefined;
286
- deepsightService: DeepsightService | undefined;
287
- detectionStatus: DetectionStatus;
288
- /**
289
- * Yaw + pitch ranges captured during detection (in degrees). Accumulated
290
- * in the detection actor's closure and committed to context once when
291
- * DETECTION_SUCCESS fires — not per-frame. Pose itself never lives in
292
- * context: per-frame samples are consumed inside the detection actor
293
- * (and discarded) so the manager-subscribed UI tree doesn't churn at
294
- * camera frame rate.
295
- */
296
- yawRange: number;
297
- pitchRange: number;
298
- capturedImage: IncodeCanvas | undefined;
299
- livenessOutcome: LivenessOutcome | undefined;
300
- signals: DeviceBehavioralSignals | undefined;
301
- /**
302
- * Personhood session token from `GET /omni/personhood/token`. Lives
303
- * in actor context (not a module-level slot) so two
304
- * `createPersonhoodManager()` instances active concurrently can't
305
- * trample each other's tokens, and so `actor.stop()` cleans it up
306
- * implicitly. Threaded into the `analyzeLiveness` and
307
- * `verifyOnDevice` actor inputs; those actors attach it as an
308
- * `Authorization: Bearer` header explicitly rather than going
309
- * through the shared `api` wrapper's auto-injection (which only
310
- * carries `currentToken` for the main session). `undefined` until
311
- * the parallel-init phase completes.
312
- */
313
- token: string | undefined;
314
- /**
315
- * Verdict computed locally from device signals + on-device
316
- * liveness analysis. Kept separately from `verdict` (the final,
317
- * server-authoritative one) so the verify-on-server step can use
318
- * it as a fallback when the network call fails. Once verify
319
- * succeeds, `verdict` is the server's response and this stays as
320
- * a debug reference; integrators only see `verdict`.
321
- */
322
- localVerdict: PersonhoodVerdict | undefined;
323
- verdict: PersonhoodVerdict | undefined;
324
- error: {
325
- code: PersonhoodErrorCode;
326
- message?: string;
327
- } | undefined;
328
- resetDetection: (() => void) | undefined;
329
- };
330
- type PersonhoodEvent = {
331
- type: 'LOAD';
332
- } | {
333
- type: 'NEXT_STEP';
334
- } | {
335
- type: 'REQUEST_PERMISSION';
336
- } | {
337
- type: 'GO_TO_LEARN_MORE';
338
- } | {
339
- type: 'BACK';
340
- } | {
341
- type: 'QUIT';
342
- } | {
343
- type: 'RESET';
344
- } |
345
- /**
346
- * Triggered from the UI when the user declines camera access but still
347
- * wants a verdict (server fallback). Also dispatched automatically when
348
- * the device has no camera at all.
349
- */
350
- {
351
- type: 'USE_FALLBACK';
352
- } | {
353
- type: 'DETECTION_UPDATE';
354
- status: DetectionStatus;
355
- } | {
356
- type: 'DETECTION_SUCCESS';
357
- canvas?: IncodeCanvas;
358
- /** Final observed head-pose yaw range (max − min) in degrees. */
359
- yawRange: number;
360
- /** Final observed head-pose pitch range (max − min) in degrees. */
361
- pitchRange: number;
362
- } | {
363
- type: 'DETECTION_RESET_READY';
364
- reset: () => void;
365
- };
366
- declare const _personhoodMachine: AnyStateMachine;
367
- type PersonhoodMachine = typeof _personhoodMachine;
368
- /**
369
- * Public machine value. Typed as `AnyStateMachine` for declaration file
370
- * portability — mirrors the convention used by `selfieMachine` and the
371
- * other Core modules. Type safety is enforced by the `setup()` config
372
- * above, not by the exported binding.
373
- */
374
- declare const personhoodMachine: AnyStateMachine;
375
- /**
376
- * Narrow typed machine used by the Actor helpers. The non-context/event/
377
- * input slots are widened to `any` because XState's full generic surface
378
- * isn't worth threading through every module — we only need the slots
379
- * the actor + manager actually consume. Same pattern as `SelfieMachine`.
380
- */
381
- type PersonhoodTypedMachine = StateMachine<PersonhoodMachineContext, PersonhoodEvent, any, any, any, any, any, any, any, PersonhoodInput, any, any, any, any>;
382
- //#endregion
383
- //#region src/modules/personhood/personhoodActor.d.ts
384
- type CreatePersonhoodActorOptions = {
385
- config: PersonhoodConfig;
386
- dependencies?: PersonhoodDependencies;
387
- };
388
- type PersonhoodActor = ActorRefFrom<PersonhoodTypedMachine>;
389
- /**
390
- * Creates and starts a Personhood XState actor. Defaults to the production
391
- * browser storage + WASM providers; passing `dependencies` lets tests and the
392
- * extensibility layer swap them for fakes.
393
- */
394
- declare function createPersonhoodActor(options: CreatePersonhoodActorOptions): PersonhoodActor;
395
- //#endregion
396
- //#region src/modules/personhood/personhoodManager.d.ts
397
- /** Initial state (before `load()` is invoked). */
398
- type PersonhoodIdleState = {
399
- status: 'idle';
400
- };
401
- /** Collecting local device + behavioural signals before any UI is shown. */
402
- type PersonhoodLoadingState = {
403
- status: 'loading';
404
- phase: 'collectingSignals' | 'checkingPermission';
405
- };
406
- /** Optional opt-in tutorial screen. */
407
- type PersonhoodTutorialState = {
408
- status: 'tutorial';
409
- };
410
- /** Camera permission handshake. */
411
- type PersonhoodPermissionsState = {
412
- status: 'permissions';
413
- permissionStatus: PermissionStatus | 'denied';
414
- };
415
- /**
416
- * Live camera + avatar-driving state.
417
- *
418
- * `stream` is the active camera MediaStream. It is **not** displayed to
419
- * the user by default (the whole UX promise is "stylized avatar, not
420
- * raw camera feed"); it's exposed so integrators can render the avatar
421
- * by piping the stream into their own face-tracking pipeline (e.g.
422
- * MediaPipe FaceLandmarker). Head-pose is intentionally **not** on
423
- * this state type — the SDK extracts pose internally for the
424
- * server-side `headMotion` spoof check, but UI consumers should
425
- * compute their own pose off `stream` rather than subscribing to a
426
- * frame-rate channel here (which would re-render on every frame).
427
- */
428
- type PersonhoodCaptureState = {
429
- status: 'capture';
430
- captureStatus: 'initializing' | 'detecting';
431
- detectionStatus: DetectionStatus;
432
- stream: MediaStream | undefined;
433
- };
434
- /** Synthesizing the local on-device verdict. No network call — the primary path. */
435
- type PersonhoodProcessingState = {
436
- status: 'processing';
437
- /**
438
- * Which stage of the local pipeline we're on:
439
- * - 'analyzing' → Deepsight analysis + pose-motion guard (post-capture)
440
- * - 'local' → synthesizing verdict from the collected signals
441
- * - 'fallback' → server-side liveness fallback (no camera / denied)
442
- */
443
- source: 'analyzing' | 'local' | 'fallback';
444
- };
445
- /** Verdict is in. Integrators read `verdict` to obtain `{ human, confidence, evidenceId, signals }`. */
446
- type PersonhoodFinishedState = {
447
- status: 'finished';
448
- verdict: PersonhoodVerdict;
449
- };
450
- type PersonhoodClosedState = {
451
- status: 'closed';
452
- };
453
- type PersonhoodErrorState = {
454
- status: 'error';
455
- error: {
456
- code: PersonhoodErrorCode;
457
- message?: string;
458
- };
459
- };
460
- type PersonhoodState = PersonhoodIdleState | PersonhoodLoadingState | PersonhoodTutorialState | PersonhoodPermissionsState | PersonhoodCaptureState | PersonhoodProcessingState | PersonhoodFinishedState | PersonhoodClosedState | PersonhoodErrorState;
461
- /**
462
- * Manager built from an externally-owned actor (extensibility path).
463
- */
464
- declare function createPersonhoodManagerFromActor(actor: PersonhoodActor): Manager<PersonhoodState> & {
465
- /** Starts the flow (goes to tutorial or capture depending on config). */
466
- load(): void;
467
- /** Advances from tutorial → capture. */
468
- nextStep(): void;
469
- /** Triggers `getUserMedia` when in `permissions.idle`. */
470
- requestPermission(): void;
471
- /** Shows the permission rationale view. */
472
- goToLearnMore(): void;
473
- /** Returns from learn-more → permission prompt. */
474
- back(): void;
475
- /** Dismisses the widget into the terminal `closed` state. */
476
- close(): void;
477
- /** Resets from the (non-final) `error` state back to `idle`. */
478
- reset(): void;
479
- /**
480
- * Skip the on-device path and hit the server fallback. Wired to the
481
- * "Continue without camera" button on the permission-denied screen; also
482
- * dispatched automatically when the device has no camera at all.
483
- */
484
- useFallback(): void;
485
- };
486
- /**
487
- * Creates a Personhood manager for the drop-in widget.
488
- *
489
- * The manager exposes:
490
- * - `state: PersonhoodState` via `getState()` / `subscribe()`
491
- * - Lifecycle controls: `load`, `nextStep`, `requestPermission`,
492
- * `goToLearnMore`, `back`, `close`, `reset`, `useFallback`, `stop`
493
- *
494
- * Head-pose is intentionally **not** exposed as a stream. The SDK
495
- * extracts pose internally for the server-side `headMotion` spoof
496
- * check; UI consumers that need a frame-rate pose signal (avatar
497
- * mirroring, etc.) should run their own face-tracking pipeline
498
- * (e.g. MediaPipe FaceLandmarker) against `state.stream` instead.
499
- *
500
- * @example
501
- * ```ts
502
- * const manager = createPersonhoodManager({
503
- * config: { siteKey: 'demo', mockVerify: true },
504
- * });
505
- * manager.subscribe((state) => {
506
- * if (state.status === 'finished') {
507
- * console.log('human?', state.verdict.human);
508
- * }
509
- * });
510
- * manager.load();
511
- * ```
512
- */
513
- declare function createPersonhoodManager(options: CreatePersonhoodActorOptions): Manager<PersonhoodState> & {
514
- /** Starts the flow (goes to tutorial or capture depending on config). */
515
- load(): void;
516
- /** Advances from tutorial → capture. */
517
- nextStep(): void;
518
- /** Triggers `getUserMedia` when in `permissions.idle`. */
519
- requestPermission(): void;
520
- /** Shows the permission rationale view. */
521
- goToLearnMore(): void;
522
- /** Returns from learn-more → permission prompt. */
523
- back(): void;
524
- /** Dismisses the widget into the terminal `closed` state. */
525
- close(): void;
526
- /** Resets from the (non-final) `error` state back to `idle`. */
527
- reset(): void;
528
- /**
529
- * Skip the on-device path and hit the server fallback. Wired to the
530
- * "Continue without camera" button on the permission-denied screen; also
531
- * dispatched automatically when the device has no camera at all.
532
- */
533
- useFallback(): void;
534
- };
535
- type PersonhoodManager = ReturnType<typeof createPersonhoodManager>;
536
- //#endregion
537
- export { type CreatePersonhoodActorOptions, type DeviceBehavioralSignals, type HeadPose, type LivenessOutcome, PERSONHOOD_ERROR_CODES, type PersonhoodActor, type PersonhoodCaptureState, type PersonhoodClosedState, type PersonhoodConfig, type PersonhoodDependencies, type PersonhoodErrorCode, type PersonhoodErrorState, type PersonhoodEvent, type PersonhoodFinishedState, type PersonhoodIdleState, type PersonhoodInput, type PersonhoodLoadingState, type PersonhoodMachine, type PersonhoodMachineContext, type PersonhoodManager, type PersonhoodPermissionsState, type PersonhoodProcessingState, type PersonhoodState, type PersonhoodTutorialState, type PersonhoodVerdict, type SpoofCheckResult, createPersonhoodActor, createPersonhoodManager, createPersonhoodManagerFromActor, personhoodMachine };