@runhuman/sensor 0.2.5 → 0.3.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/dist/index.d.mts CHANGED
@@ -168,20 +168,38 @@ declare class Runhuman {
168
168
  * After calling destroy(), you can call init() again.
169
169
  */
170
170
  destroy(): Promise<void>;
171
- /** Access the session manager (used by <RunhumanOverlay /> for reactive state) */
171
+ /** Access the session manager (used by <RunhumanProvider /> for reactive state) */
172
172
  getSessionManager(): SessionManager;
173
- /** Access the API client (used by <RunhumanOverlay /> for short code resolution) */
173
+ /** Access the API client (used by <RunhumanProvider /> for short code resolution) */
174
174
  getApiClient(): ApiClient;
175
175
  private log;
176
176
  }
177
177
 
178
178
  type OverlayPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
179
- interface RunhumanOverlayProps {
179
+ interface RunhumanProviderProps {
180
180
  children: React.ReactNode;
181
+ /** API key for authentication (e.g., 'rh_...') */
182
+ apiKey: string;
181
183
  /** Corner for the overlay UI (default: 'bottom-right') */
182
184
  position?: OverlayPosition;
185
+ /** Base URL of the Runhuman API (defaults to production) */
186
+ baseUrl?: string;
187
+ /** Job ID if known upfront (e.g., from deep link params at app launch) */
188
+ jobId?: string;
189
+ /** Target platform (defaults to 'react-native') */
190
+ platform?: TelemetryPlatform;
191
+ /** How often to flush buffered events in ms (default: 5000) */
192
+ flushIntervalMs?: number;
193
+ /** How often to poll for job status in ms (default: 10000) */
194
+ pollIntervalMs?: number;
195
+ /** Max events in the ring buffer before FIFO eviction (default: 1000) */
196
+ maxBufferSize?: number;
197
+ /** Enable deep link activation (default: true) */
198
+ enableDeepLinks?: boolean;
199
+ /** Log debug info to console (default: false) */
200
+ debug?: boolean;
183
201
  }
184
- declare function RunhumanOverlay({ children, position }: RunhumanOverlayProps): react_jsx_runtime.JSX.Element;
202
+ declare function RunhumanProvider({ children, apiKey, position, baseUrl, jobId, platform, flushIntervalMs, pollIntervalMs, maxBufferSize, enableDeepLinks, debug, }: RunhumanProviderProps): react_jsx_runtime.JSX.Element;
185
203
 
186
204
  /**
187
205
  * React hook for subscribing to sensor state changes.
@@ -199,4 +217,4 @@ interface SensorState {
199
217
  */
200
218
  declare function useSensorState(): SensorState;
201
219
 
202
- export { ApiClient, type OverlayPosition, Runhuman, type RunhumanConfig, RunhumanOverlay, type RunhumanOverlayProps, type SensorState, type SessionState, useSensorState };
220
+ export { ApiClient, type OverlayPosition, Runhuman, type RunhumanConfig, RunhumanProvider, type RunhumanProviderProps, type SensorState, type SessionState, useSensorState };
package/dist/index.d.ts CHANGED
@@ -168,20 +168,38 @@ declare class Runhuman {
168
168
  * After calling destroy(), you can call init() again.
169
169
  */
170
170
  destroy(): Promise<void>;
171
- /** Access the session manager (used by <RunhumanOverlay /> for reactive state) */
171
+ /** Access the session manager (used by <RunhumanProvider /> for reactive state) */
172
172
  getSessionManager(): SessionManager;
173
- /** Access the API client (used by <RunhumanOverlay /> for short code resolution) */
173
+ /** Access the API client (used by <RunhumanProvider /> for short code resolution) */
174
174
  getApiClient(): ApiClient;
175
175
  private log;
176
176
  }
177
177
 
178
178
  type OverlayPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
179
- interface RunhumanOverlayProps {
179
+ interface RunhumanProviderProps {
180
180
  children: React.ReactNode;
181
+ /** API key for authentication (e.g., 'rh_...') */
182
+ apiKey: string;
181
183
  /** Corner for the overlay UI (default: 'bottom-right') */
182
184
  position?: OverlayPosition;
185
+ /** Base URL of the Runhuman API (defaults to production) */
186
+ baseUrl?: string;
187
+ /** Job ID if known upfront (e.g., from deep link params at app launch) */
188
+ jobId?: string;
189
+ /** Target platform (defaults to 'react-native') */
190
+ platform?: TelemetryPlatform;
191
+ /** How often to flush buffered events in ms (default: 5000) */
192
+ flushIntervalMs?: number;
193
+ /** How often to poll for job status in ms (default: 10000) */
194
+ pollIntervalMs?: number;
195
+ /** Max events in the ring buffer before FIFO eviction (default: 1000) */
196
+ maxBufferSize?: number;
197
+ /** Enable deep link activation (default: true) */
198
+ enableDeepLinks?: boolean;
199
+ /** Log debug info to console (default: false) */
200
+ debug?: boolean;
183
201
  }
184
- declare function RunhumanOverlay({ children, position }: RunhumanOverlayProps): react_jsx_runtime.JSX.Element;
202
+ declare function RunhumanProvider({ children, apiKey, position, baseUrl, jobId, platform, flushIntervalMs, pollIntervalMs, maxBufferSize, enableDeepLinks, debug, }: RunhumanProviderProps): react_jsx_runtime.JSX.Element;
185
203
 
186
204
  /**
187
205
  * React hook for subscribing to sensor state changes.
@@ -199,4 +217,4 @@ interface SensorState {
199
217
  */
200
218
  declare function useSensorState(): SensorState;
201
219
 
202
- export { ApiClient, type OverlayPosition, Runhuman, type RunhumanConfig, RunhumanOverlay, type RunhumanOverlayProps, type SensorState, type SessionState, useSensorState };
220
+ export { ApiClient, type OverlayPosition, Runhuman, type RunhumanConfig, RunhumanProvider, type RunhumanProviderProps, type SensorState, type SessionState, useSensorState };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,13 +17,21 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var index_exports = {};
22
32
  __export(index_exports, {
23
33
  Runhuman: () => Runhuman,
24
- RunhumanOverlay: () => RunhumanOverlay,
34
+ RunhumanProvider: () => RunhumanProvider,
25
35
  useSensorState: () => useSensorState
26
36
  });
27
37
  module.exports = __toCommonJS(index_exports);
@@ -185,6 +195,8 @@ var apiRoutes = {
185
195
  jobs: defineRoute("/jobs"),
186
196
  /** Get/update/delete specific job */
187
197
  job: defineRoute("/jobs/:jobId"),
198
+ /** Cancel a job */
199
+ jobCancel: defineRoute("/jobs/:jobId/cancel"),
188
200
  /** Get job status (for polling) */
189
201
  jobStatus: defineRoute("/jobs/:jobId/status"),
190
202
  /** Get individual job artifact by type */
@@ -303,6 +315,8 @@ var apiRoutes = {
303
315
  githubLink: defineRoute("/github/link"),
304
316
  /** List issues for a repo (by owner/repo) */
305
317
  githubIssuesByRepo: defineRoute("/github/issues/:owner/:repo"),
318
+ /** Get a single issue for a repo (by owner/repo/issueNumber) */
319
+ githubIssueByRepo: defineRoute("/github/issues/:owner/:repo/:issueNumber"),
306
320
  /** List issues (by projectId query param) */
307
321
  githubIssues: defineRoute("/github/issues"),
308
322
  /** Get a single issue */
@@ -457,8 +471,10 @@ var apiRoutes = {
457
471
  organizationJobs: defineRoute("/organizations/:organizationId/jobs"),
458
472
  /** Transfer organization ownership */
459
473
  organizationTransferOwnership: defineRoute("/organizations/:organizationId/transfer-ownership"),
460
- /** Create organization API key */
474
+ /** List/create organization API keys */
461
475
  organizationApiKeys: defineRoute("/organizations/:organizationId/api-keys"),
476
+ /** Get/revoke/delete a specific organization API key */
477
+ organizationApiKey: defineRoute("/organizations/:organizationId/api-keys/:keyId"),
462
478
  /** Get GitHub installations for an organization */
463
479
  organizationGitHubInstallations: defineRoute("/organizations/:organizationId/github/installations"),
464
480
  /** Get/delete specific GitHub installation for an organization */
@@ -567,7 +583,7 @@ var ApiClient = class {
567
583
  return this.get(apiRoutes.telemetrySessionStatus.build({ jobId }));
568
584
  }
569
585
  async resolveShortCode(code) {
570
- const normalized = code.replace(/^RH-/i, "").toUpperCase();
586
+ const normalized = code.toUpperCase().trim();
571
587
  try {
572
588
  return await this.get(
573
589
  apiRoutes.telemetryShortCodeResolve.build({ code: normalized })
@@ -1161,11 +1177,11 @@ var Runhuman = class _Runhuman {
1161
1177
  _Runhuman.instance = null;
1162
1178
  this.log("Destroyed");
1163
1179
  }
1164
- /** Access the session manager (used by <RunhumanOverlay /> for reactive state) */
1180
+ /** Access the session manager (used by <RunhumanProvider /> for reactive state) */
1165
1181
  getSessionManager() {
1166
1182
  return this.sessionManager;
1167
1183
  }
1168
- /** Access the API client (used by <RunhumanOverlay /> for short code resolution) */
1184
+ /** Access the API client (used by <RunhumanProvider /> for short code resolution) */
1169
1185
  getApiClient() {
1170
1186
  return this.apiClient;
1171
1187
  }
@@ -1176,7 +1192,8 @@ var Runhuman = class _Runhuman {
1176
1192
  }
1177
1193
  };
1178
1194
 
1179
- // src/overlay/RunhumanOverlay.tsx
1195
+ // src/overlay/RunhumanProvider.tsx
1196
+ var import_react5 = require("react");
1180
1197
  var import_react_native4 = require("react-native");
1181
1198
 
1182
1199
  // src/overlay/use-sensor-state.ts
@@ -1263,6 +1280,11 @@ var overlayStyles = import_react_native.StyleSheet.create({
1263
1280
  fontWeight: "600",
1264
1281
  marginBottom: 8
1265
1282
  },
1283
+ inputRow: {
1284
+ flexDirection: "row",
1285
+ alignItems: "center",
1286
+ gap: 6
1287
+ },
1266
1288
  input: {
1267
1289
  backgroundColor: "rgba(255, 255, 255, 0.1)",
1268
1290
  borderRadius: 8,
@@ -1276,9 +1298,25 @@ var overlayStyles = import_react_native.StyleSheet.create({
1276
1298
  padding: 10,
1277
1299
  textAlign: "center"
1278
1300
  },
1301
+ inputFlex: {
1302
+ flex: 1
1303
+ },
1279
1304
  inputError: {
1280
1305
  borderColor: BRAND_RED
1281
1306
  },
1307
+ pasteButton: {
1308
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
1309
+ borderRadius: 8,
1310
+ borderWidth: 1,
1311
+ borderColor: OVERLAY_BORDER,
1312
+ paddingVertical: 10,
1313
+ paddingHorizontal: 8
1314
+ },
1315
+ pasteButtonText: {
1316
+ color: "rgba(255, 255, 255, 0.6)",
1317
+ fontSize: 11,
1318
+ fontWeight: "600"
1319
+ },
1282
1320
  submitButton: {
1283
1321
  backgroundColor: BRAND_BLUE,
1284
1322
  borderRadius: 8,
@@ -1345,6 +1383,14 @@ var overlayStyles = import_react_native.StyleSheet.create({
1345
1383
  }
1346
1384
  });
1347
1385
 
1386
+ // src/overlay/clipboard.ts
1387
+ var ReactNative = __toESM(require("react-native"));
1388
+ var RN = ReactNative;
1389
+ var clipboard = RN["Clipboard"];
1390
+ async function getClipboardText() {
1391
+ return clipboard.getString();
1392
+ }
1393
+
1348
1394
  // src/overlay/CodeEntryPanel.tsx
1349
1395
  var import_jsx_runtime = require("react/jsx-runtime");
1350
1396
  function CodeEntryPanel({ position }) {
@@ -1366,29 +1412,40 @@ function CodeEntryPanel({ position }) {
1366
1412
  setResolving(false);
1367
1413
  }
1368
1414
  };
1415
+ const handlePaste = async () => {
1416
+ const text = await getClipboardText();
1417
+ const trimmed = text.trim().toUpperCase().slice(0, 6);
1418
+ if (trimmed) {
1419
+ setCode(trimmed);
1420
+ setError(null);
1421
+ }
1422
+ };
1369
1423
  if (minimized) {
1370
1424
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { style: [overlayStyles.fab, overlayStyles[position]], onPress: () => setMinimized(false), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: overlayStyles.fabText, children: "RH" }) });
1371
1425
  }
1372
1426
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: [overlayStyles.panel, overlayStyles[position]], children: [
1373
1427
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { style: overlayStyles.minimizeButton, onPress: () => setMinimized(true), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: overlayStyles.minimizeText, children: "-" }) }),
1374
1428
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: overlayStyles.panelTitle, children: "Runhuman Sensor" }),
1375
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1376
- import_react_native2.TextInput,
1377
- {
1378
- style: error ? { ...overlayStyles.input, ...overlayStyles.inputError } : overlayStyles.input,
1379
- value: code,
1380
- onChangeText: (text) => {
1381
- setCode(text.toUpperCase());
1382
- setError(null);
1383
- },
1384
- placeholder: "RH-XXXX",
1385
- placeholderTextColor: "rgba(255,255,255,0.3)",
1386
- autoCapitalize: "characters",
1387
- maxLength: 10,
1388
- editable: !resolving,
1389
- onSubmitEditing: handleSubmit
1390
- }
1391
- ),
1429
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: overlayStyles.inputRow, children: [
1430
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1431
+ import_react_native2.TextInput,
1432
+ {
1433
+ style: [error ? { ...overlayStyles.input, ...overlayStyles.inputError } : overlayStyles.input, overlayStyles.inputFlex],
1434
+ value: code,
1435
+ onChangeText: (text) => {
1436
+ setCode(text.toUpperCase());
1437
+ setError(null);
1438
+ },
1439
+ placeholder: "XXXX",
1440
+ placeholderTextColor: "rgba(255,255,255,0.3)",
1441
+ autoCapitalize: "characters",
1442
+ maxLength: 6,
1443
+ editable: !resolving,
1444
+ onSubmitEditing: handleSubmit
1445
+ }
1446
+ ),
1447
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Pressable, { style: overlayStyles.pasteButton, onPress: handlePaste, disabled: resolving, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: overlayStyles.pasteButtonText, children: "Paste" }) })
1448
+ ] }),
1392
1449
  error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: overlayStyles.errorText, children: error }) : null,
1393
1450
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1394
1451
  import_react_native2.Pressable,
@@ -1431,7 +1488,7 @@ function ActiveIndicator({ state, position }) {
1431
1488
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Animated.View, { style: [overlayStyles.indicator, overlayStyles[position], colorStyle, { opacity: pulse }] });
1432
1489
  }
1433
1490
 
1434
- // src/overlay/RunhumanOverlay.tsx
1491
+ // src/overlay/RunhumanProvider.tsx
1435
1492
  var import_jsx_runtime3 = require("react/jsx-runtime");
1436
1493
  var positionMap = {
1437
1494
  "top-left": "topLeft",
@@ -1439,7 +1496,40 @@ var positionMap = {
1439
1496
  "bottom-left": "bottomLeft",
1440
1497
  "bottom-right": "bottomRight"
1441
1498
  };
1442
- function RunhumanOverlay({ children, position = "bottom-right" }) {
1499
+ function RunhumanProvider({
1500
+ children,
1501
+ apiKey,
1502
+ position = "bottom-right",
1503
+ baseUrl,
1504
+ jobId,
1505
+ platform,
1506
+ flushIntervalMs,
1507
+ pollIntervalMs,
1508
+ maxBufferSize,
1509
+ enableDeepLinks,
1510
+ debug
1511
+ }) {
1512
+ const initializedRef = (0, import_react5.useRef)(false);
1513
+ (0, import_react5.useEffect)(() => {
1514
+ if (initializedRef.current) return;
1515
+ initializedRef.current = true;
1516
+ const config = {
1517
+ apiKey,
1518
+ baseUrl,
1519
+ jobId,
1520
+ platform,
1521
+ flushIntervalMs,
1522
+ pollIntervalMs,
1523
+ maxBufferSize,
1524
+ enableDeepLinks,
1525
+ debug
1526
+ };
1527
+ Runhuman.init(config);
1528
+ return () => {
1529
+ initializedRef.current = false;
1530
+ Runhuman.getInstance().destroy();
1531
+ };
1532
+ }, []);
1443
1533
  const { state, activeJobId } = useSensorState();
1444
1534
  const posKey = positionMap[position];
1445
1535
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles.container, children: [
@@ -1456,7 +1546,7 @@ var styles = import_react_native4.StyleSheet.create({
1456
1546
  // Annotate the CommonJS export names for ESM import in node:
1457
1547
  0 && (module.exports = {
1458
1548
  Runhuman,
1459
- RunhumanOverlay,
1549
+ RunhumanProvider,
1460
1550
  useSensorState
1461
1551
  });
1462
1552
  //# sourceMappingURL=index.js.map