@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.mjs CHANGED
@@ -164,6 +164,8 @@ var apiRoutes = {
164
164
  jobs: defineRoute("/jobs"),
165
165
  /** Get/update/delete specific job */
166
166
  job: defineRoute("/jobs/:jobId"),
167
+ /** Cancel a job */
168
+ jobCancel: defineRoute("/jobs/:jobId/cancel"),
167
169
  /** Get job status (for polling) */
168
170
  jobStatus: defineRoute("/jobs/:jobId/status"),
169
171
  /** Get individual job artifact by type */
@@ -282,6 +284,8 @@ var apiRoutes = {
282
284
  githubLink: defineRoute("/github/link"),
283
285
  /** List issues for a repo (by owner/repo) */
284
286
  githubIssuesByRepo: defineRoute("/github/issues/:owner/:repo"),
287
+ /** Get a single issue for a repo (by owner/repo/issueNumber) */
288
+ githubIssueByRepo: defineRoute("/github/issues/:owner/:repo/:issueNumber"),
285
289
  /** List issues (by projectId query param) */
286
290
  githubIssues: defineRoute("/github/issues"),
287
291
  /** Get a single issue */
@@ -436,8 +440,10 @@ var apiRoutes = {
436
440
  organizationJobs: defineRoute("/organizations/:organizationId/jobs"),
437
441
  /** Transfer organization ownership */
438
442
  organizationTransferOwnership: defineRoute("/organizations/:organizationId/transfer-ownership"),
439
- /** Create organization API key */
443
+ /** List/create organization API keys */
440
444
  organizationApiKeys: defineRoute("/organizations/:organizationId/api-keys"),
445
+ /** Get/revoke/delete a specific organization API key */
446
+ organizationApiKey: defineRoute("/organizations/:organizationId/api-keys/:keyId"),
441
447
  /** Get GitHub installations for an organization */
442
448
  organizationGitHubInstallations: defineRoute("/organizations/:organizationId/github/installations"),
443
449
  /** Get/delete specific GitHub installation for an organization */
@@ -546,7 +552,7 @@ var ApiClient = class {
546
552
  return this.get(apiRoutes.telemetrySessionStatus.build({ jobId }));
547
553
  }
548
554
  async resolveShortCode(code) {
549
- const normalized = code.replace(/^RH-/i, "").toUpperCase();
555
+ const normalized = code.toUpperCase().trim();
550
556
  try {
551
557
  return await this.get(
552
558
  apiRoutes.telemetryShortCodeResolve.build({ code: normalized })
@@ -1140,11 +1146,11 @@ var Runhuman = class _Runhuman {
1140
1146
  _Runhuman.instance = null;
1141
1147
  this.log("Destroyed");
1142
1148
  }
1143
- /** Access the session manager (used by <RunhumanOverlay /> for reactive state) */
1149
+ /** Access the session manager (used by <RunhumanProvider /> for reactive state) */
1144
1150
  getSessionManager() {
1145
1151
  return this.sessionManager;
1146
1152
  }
1147
- /** Access the API client (used by <RunhumanOverlay /> for short code resolution) */
1153
+ /** Access the API client (used by <RunhumanProvider /> for short code resolution) */
1148
1154
  getApiClient() {
1149
1155
  return this.apiClient;
1150
1156
  }
@@ -1155,7 +1161,8 @@ var Runhuman = class _Runhuman {
1155
1161
  }
1156
1162
  };
1157
1163
 
1158
- // src/overlay/RunhumanOverlay.tsx
1164
+ // src/overlay/RunhumanProvider.tsx
1165
+ import { useEffect as useEffect2, useRef as useRef3 } from "react";
1159
1166
  import { View as View2, StyleSheet as StyleSheet2 } from "react-native";
1160
1167
 
1161
1168
  // src/overlay/use-sensor-state.ts
@@ -1242,6 +1249,11 @@ var overlayStyles = StyleSheet.create({
1242
1249
  fontWeight: "600",
1243
1250
  marginBottom: 8
1244
1251
  },
1252
+ inputRow: {
1253
+ flexDirection: "row",
1254
+ alignItems: "center",
1255
+ gap: 6
1256
+ },
1245
1257
  input: {
1246
1258
  backgroundColor: "rgba(255, 255, 255, 0.1)",
1247
1259
  borderRadius: 8,
@@ -1255,9 +1267,25 @@ var overlayStyles = StyleSheet.create({
1255
1267
  padding: 10,
1256
1268
  textAlign: "center"
1257
1269
  },
1270
+ inputFlex: {
1271
+ flex: 1
1272
+ },
1258
1273
  inputError: {
1259
1274
  borderColor: BRAND_RED
1260
1275
  },
1276
+ pasteButton: {
1277
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
1278
+ borderRadius: 8,
1279
+ borderWidth: 1,
1280
+ borderColor: OVERLAY_BORDER,
1281
+ paddingVertical: 10,
1282
+ paddingHorizontal: 8
1283
+ },
1284
+ pasteButtonText: {
1285
+ color: "rgba(255, 255, 255, 0.6)",
1286
+ fontSize: 11,
1287
+ fontWeight: "600"
1288
+ },
1261
1289
  submitButton: {
1262
1290
  backgroundColor: BRAND_BLUE,
1263
1291
  borderRadius: 8,
@@ -1324,6 +1352,14 @@ var overlayStyles = StyleSheet.create({
1324
1352
  }
1325
1353
  });
1326
1354
 
1355
+ // src/overlay/clipboard.ts
1356
+ import * as ReactNative from "react-native";
1357
+ var RN = ReactNative;
1358
+ var clipboard = RN["Clipboard"];
1359
+ async function getClipboardText() {
1360
+ return clipboard.getString();
1361
+ }
1362
+
1327
1363
  // src/overlay/CodeEntryPanel.tsx
1328
1364
  import { jsx, jsxs } from "react/jsx-runtime";
1329
1365
  function CodeEntryPanel({ position }) {
@@ -1345,29 +1381,40 @@ function CodeEntryPanel({ position }) {
1345
1381
  setResolving(false);
1346
1382
  }
1347
1383
  };
1384
+ const handlePaste = async () => {
1385
+ const text = await getClipboardText();
1386
+ const trimmed = text.trim().toUpperCase().slice(0, 6);
1387
+ if (trimmed) {
1388
+ setCode(trimmed);
1389
+ setError(null);
1390
+ }
1391
+ };
1348
1392
  if (minimized) {
1349
1393
  return /* @__PURE__ */ jsx(Pressable, { style: [overlayStyles.fab, overlayStyles[position]], onPress: () => setMinimized(false), children: /* @__PURE__ */ jsx(Text, { style: overlayStyles.fabText, children: "RH" }) });
1350
1394
  }
1351
1395
  return /* @__PURE__ */ jsxs(View, { style: [overlayStyles.panel, overlayStyles[position]], children: [
1352
1396
  /* @__PURE__ */ jsx(Pressable, { style: overlayStyles.minimizeButton, onPress: () => setMinimized(true), children: /* @__PURE__ */ jsx(Text, { style: overlayStyles.minimizeText, children: "-" }) }),
1353
1397
  /* @__PURE__ */ jsx(Text, { style: overlayStyles.panelTitle, children: "Runhuman Sensor" }),
1354
- /* @__PURE__ */ jsx(
1355
- TextInput,
1356
- {
1357
- style: error ? { ...overlayStyles.input, ...overlayStyles.inputError } : overlayStyles.input,
1358
- value: code,
1359
- onChangeText: (text) => {
1360
- setCode(text.toUpperCase());
1361
- setError(null);
1362
- },
1363
- placeholder: "RH-XXXX",
1364
- placeholderTextColor: "rgba(255,255,255,0.3)",
1365
- autoCapitalize: "characters",
1366
- maxLength: 10,
1367
- editable: !resolving,
1368
- onSubmitEditing: handleSubmit
1369
- }
1370
- ),
1398
+ /* @__PURE__ */ jsxs(View, { style: overlayStyles.inputRow, children: [
1399
+ /* @__PURE__ */ jsx(
1400
+ TextInput,
1401
+ {
1402
+ style: [error ? { ...overlayStyles.input, ...overlayStyles.inputError } : overlayStyles.input, overlayStyles.inputFlex],
1403
+ value: code,
1404
+ onChangeText: (text) => {
1405
+ setCode(text.toUpperCase());
1406
+ setError(null);
1407
+ },
1408
+ placeholder: "XXXX",
1409
+ placeholderTextColor: "rgba(255,255,255,0.3)",
1410
+ autoCapitalize: "characters",
1411
+ maxLength: 6,
1412
+ editable: !resolving,
1413
+ onSubmitEditing: handleSubmit
1414
+ }
1415
+ ),
1416
+ /* @__PURE__ */ jsx(Pressable, { style: overlayStyles.pasteButton, onPress: handlePaste, disabled: resolving, children: /* @__PURE__ */ jsx(Text, { style: overlayStyles.pasteButtonText, children: "Paste" }) })
1417
+ ] }),
1371
1418
  error ? /* @__PURE__ */ jsx(Text, { style: overlayStyles.errorText, children: error }) : null,
1372
1419
  /* @__PURE__ */ jsx(
1373
1420
  Pressable,
@@ -1410,7 +1457,7 @@ function ActiveIndicator({ state, position }) {
1410
1457
  return /* @__PURE__ */ jsx2(Animated.View, { style: [overlayStyles.indicator, overlayStyles[position], colorStyle, { opacity: pulse }] });
1411
1458
  }
1412
1459
 
1413
- // src/overlay/RunhumanOverlay.tsx
1460
+ // src/overlay/RunhumanProvider.tsx
1414
1461
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1415
1462
  var positionMap = {
1416
1463
  "top-left": "topLeft",
@@ -1418,7 +1465,40 @@ var positionMap = {
1418
1465
  "bottom-left": "bottomLeft",
1419
1466
  "bottom-right": "bottomRight"
1420
1467
  };
1421
- function RunhumanOverlay({ children, position = "bottom-right" }) {
1468
+ function RunhumanProvider({
1469
+ children,
1470
+ apiKey,
1471
+ position = "bottom-right",
1472
+ baseUrl,
1473
+ jobId,
1474
+ platform,
1475
+ flushIntervalMs,
1476
+ pollIntervalMs,
1477
+ maxBufferSize,
1478
+ enableDeepLinks,
1479
+ debug
1480
+ }) {
1481
+ const initializedRef = useRef3(false);
1482
+ useEffect2(() => {
1483
+ if (initializedRef.current) return;
1484
+ initializedRef.current = true;
1485
+ const config = {
1486
+ apiKey,
1487
+ baseUrl,
1488
+ jobId,
1489
+ platform,
1490
+ flushIntervalMs,
1491
+ pollIntervalMs,
1492
+ maxBufferSize,
1493
+ enableDeepLinks,
1494
+ debug
1495
+ };
1496
+ Runhuman.init(config);
1497
+ return () => {
1498
+ initializedRef.current = false;
1499
+ Runhuman.getInstance().destroy();
1500
+ };
1501
+ }, []);
1422
1502
  const { state, activeJobId } = useSensorState();
1423
1503
  const posKey = positionMap[position];
1424
1504
  return /* @__PURE__ */ jsxs2(View2, { style: styles.container, children: [
@@ -1434,7 +1514,7 @@ var styles = StyleSheet2.create({
1434
1514
  });
1435
1515
  export {
1436
1516
  Runhuman,
1437
- RunhumanOverlay,
1517
+ RunhumanProvider,
1438
1518
  useSensorState
1439
1519
  };
1440
1520
  //# sourceMappingURL=index.mjs.map