@runhuman/sensor 0.3.0 → 0.3.1
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 +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +46 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -52,6 +52,7 @@ interface SessionManagerConfig {
|
|
|
52
52
|
}
|
|
53
53
|
declare class SessionManager {
|
|
54
54
|
private state;
|
|
55
|
+
private _disabled;
|
|
55
56
|
private sessionId;
|
|
56
57
|
private activeJobId;
|
|
57
58
|
private pollTimer;
|
|
@@ -66,6 +67,8 @@ declare class SessionManager {
|
|
|
66
67
|
getSnapshot(): SessionState;
|
|
67
68
|
getSessionId(): string | null;
|
|
68
69
|
getActiveJobId(): string | null;
|
|
70
|
+
/** True when the API rejected the session (e.g. subscription tier). Hides the overlay. */
|
|
71
|
+
isDisabled(): boolean;
|
|
69
72
|
/**
|
|
70
73
|
* Subscribe to state changes. Returns an unsubscribe function.
|
|
71
74
|
* Compatible with React's useSyncExternalStore.
|
|
@@ -180,6 +183,8 @@ interface RunhumanProviderProps {
|
|
|
180
183
|
children: React.ReactNode;
|
|
181
184
|
/** API key for authentication (e.g., 'rh_...') */
|
|
182
185
|
apiKey: string;
|
|
186
|
+
/** Set to false to disable the sensor entirely (e.g., in production). Default: true */
|
|
187
|
+
enabled?: boolean;
|
|
183
188
|
/** Corner for the overlay UI (default: 'bottom-right') */
|
|
184
189
|
position?: OverlayPosition;
|
|
185
190
|
/** Base URL of the Runhuman API (defaults to production) */
|
|
@@ -199,7 +204,7 @@ interface RunhumanProviderProps {
|
|
|
199
204
|
/** Log debug info to console (default: false) */
|
|
200
205
|
debug?: boolean;
|
|
201
206
|
}
|
|
202
|
-
declare function RunhumanProvider({ children, apiKey, position, baseUrl, jobId, platform, flushIntervalMs, pollIntervalMs, maxBufferSize, enableDeepLinks, debug, }: RunhumanProviderProps): react_jsx_runtime.JSX.Element;
|
|
207
|
+
declare function RunhumanProvider({ children, apiKey, enabled, position, baseUrl, jobId, platform, flushIntervalMs, pollIntervalMs, maxBufferSize, enableDeepLinks, debug, }: RunhumanProviderProps): react_jsx_runtime.JSX.Element;
|
|
203
208
|
|
|
204
209
|
/**
|
|
205
210
|
* React hook for subscribing to sensor state changes.
|
|
@@ -210,6 +215,7 @@ interface SensorState {
|
|
|
210
215
|
state: SessionState;
|
|
211
216
|
activeJobId: string | null;
|
|
212
217
|
sessionId: string | null;
|
|
218
|
+
disabled: boolean;
|
|
213
219
|
}
|
|
214
220
|
/**
|
|
215
221
|
* Subscribe to the sensor's session state.
|
package/dist/index.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ interface SessionManagerConfig {
|
|
|
52
52
|
}
|
|
53
53
|
declare class SessionManager {
|
|
54
54
|
private state;
|
|
55
|
+
private _disabled;
|
|
55
56
|
private sessionId;
|
|
56
57
|
private activeJobId;
|
|
57
58
|
private pollTimer;
|
|
@@ -66,6 +67,8 @@ declare class SessionManager {
|
|
|
66
67
|
getSnapshot(): SessionState;
|
|
67
68
|
getSessionId(): string | null;
|
|
68
69
|
getActiveJobId(): string | null;
|
|
70
|
+
/** True when the API rejected the session (e.g. subscription tier). Hides the overlay. */
|
|
71
|
+
isDisabled(): boolean;
|
|
69
72
|
/**
|
|
70
73
|
* Subscribe to state changes. Returns an unsubscribe function.
|
|
71
74
|
* Compatible with React's useSyncExternalStore.
|
|
@@ -180,6 +183,8 @@ interface RunhumanProviderProps {
|
|
|
180
183
|
children: React.ReactNode;
|
|
181
184
|
/** API key for authentication (e.g., 'rh_...') */
|
|
182
185
|
apiKey: string;
|
|
186
|
+
/** Set to false to disable the sensor entirely (e.g., in production). Default: true */
|
|
187
|
+
enabled?: boolean;
|
|
183
188
|
/** Corner for the overlay UI (default: 'bottom-right') */
|
|
184
189
|
position?: OverlayPosition;
|
|
185
190
|
/** Base URL of the Runhuman API (defaults to production) */
|
|
@@ -199,7 +204,7 @@ interface RunhumanProviderProps {
|
|
|
199
204
|
/** Log debug info to console (default: false) */
|
|
200
205
|
debug?: boolean;
|
|
201
206
|
}
|
|
202
|
-
declare function RunhumanProvider({ children, apiKey, position, baseUrl, jobId, platform, flushIntervalMs, pollIntervalMs, maxBufferSize, enableDeepLinks, debug, }: RunhumanProviderProps): react_jsx_runtime.JSX.Element;
|
|
207
|
+
declare function RunhumanProvider({ children, apiKey, enabled, position, baseUrl, jobId, platform, flushIntervalMs, pollIntervalMs, maxBufferSize, enableDeepLinks, debug, }: RunhumanProviderProps): react_jsx_runtime.JSX.Element;
|
|
203
208
|
|
|
204
209
|
/**
|
|
205
210
|
* React hook for subscribing to sensor state changes.
|
|
@@ -210,6 +215,7 @@ interface SensorState {
|
|
|
210
215
|
state: SessionState;
|
|
211
216
|
activeJobId: string | null;
|
|
212
217
|
sessionId: string | null;
|
|
218
|
+
disabled: boolean;
|
|
213
219
|
}
|
|
214
220
|
/**
|
|
215
221
|
* Subscribe to the sensor's session state.
|
package/dist/index.js
CHANGED
|
@@ -197,6 +197,8 @@ var apiRoutes = {
|
|
|
197
197
|
job: defineRoute("/jobs/:jobId"),
|
|
198
198
|
/** Cancel a job */
|
|
199
199
|
jobCancel: defineRoute("/jobs/:jobId/cancel"),
|
|
200
|
+
/** Create a GitHub issue from an extracted finding (user-initiated) */
|
|
201
|
+
jobCreateIssue: defineRoute("/jobs/:jobId/create-issue"),
|
|
200
202
|
/** Get job status (for polling) */
|
|
201
203
|
jobStatus: defineRoute("/jobs/:jobId/status"),
|
|
202
204
|
/** Get individual job artifact by type */
|
|
@@ -858,6 +860,7 @@ var InterceptorManager = class {
|
|
|
858
860
|
var SessionManager = class {
|
|
859
861
|
constructor(config) {
|
|
860
862
|
this.state = "idle";
|
|
863
|
+
this._disabled = false;
|
|
861
864
|
this.sessionId = null;
|
|
862
865
|
this.activeJobId = null;
|
|
863
866
|
this.pollTimer = null;
|
|
@@ -880,6 +883,10 @@ var SessionManager = class {
|
|
|
880
883
|
getActiveJobId() {
|
|
881
884
|
return this.activeJobId;
|
|
882
885
|
}
|
|
886
|
+
/** True when the API rejected the session (e.g. subscription tier). Hides the overlay. */
|
|
887
|
+
isDisabled() {
|
|
888
|
+
return this._disabled;
|
|
889
|
+
}
|
|
883
890
|
/**
|
|
884
891
|
* Subscribe to state changes. Returns an unsubscribe function.
|
|
885
892
|
* Compatible with React's useSyncExternalStore.
|
|
@@ -964,12 +971,22 @@ var SessionManager = class {
|
|
|
964
971
|
async startSession() {
|
|
965
972
|
this.setState("active");
|
|
966
973
|
const now = /* @__PURE__ */ new Date();
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
974
|
+
let response;
|
|
975
|
+
try {
|
|
976
|
+
response = await this.config.apiClient.createSession({
|
|
977
|
+
jobId: this.activeJobId,
|
|
978
|
+
platform: this.config.platform,
|
|
979
|
+
sdkVersion: this.config.sdkVersion,
|
|
980
|
+
clientStartTime: now.toISOString()
|
|
981
|
+
});
|
|
982
|
+
} catch (error) {
|
|
983
|
+
const is403 = error instanceof Error && error.message.includes("403");
|
|
984
|
+
this.log(is403 ? "Subscription not eligible \u2014 disabling sensor" : "Session creation failed", { error });
|
|
985
|
+
if (is403) this._disabled = true;
|
|
986
|
+
this.activeJobId = null;
|
|
987
|
+
this.setState("idle");
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
973
990
|
this.sessionId = response.sessionId;
|
|
974
991
|
const sessionStartTime = now.getTime();
|
|
975
992
|
this.log("Session started", {
|
|
@@ -1199,7 +1216,7 @@ var import_react_native4 = require("react-native");
|
|
|
1199
1216
|
// src/overlay/use-sensor-state.ts
|
|
1200
1217
|
var import_react = require("react");
|
|
1201
1218
|
var import_react2 = require("react");
|
|
1202
|
-
var IDLE_STATE = { state: "idle", activeJobId: null, sessionId: null };
|
|
1219
|
+
var IDLE_STATE = { state: "idle", activeJobId: null, sessionId: null, disabled: false };
|
|
1203
1220
|
function tryGetInstance() {
|
|
1204
1221
|
try {
|
|
1205
1222
|
return Runhuman.getInstance();
|
|
@@ -1235,11 +1252,12 @@ function useSensorState() {
|
|
|
1235
1252
|
const state = sm.getSnapshot();
|
|
1236
1253
|
const activeJobId = sm.getActiveJobId();
|
|
1237
1254
|
const sessionId = sm.getSessionId();
|
|
1255
|
+
const disabled = sm.isDisabled();
|
|
1238
1256
|
const prev = cached.current;
|
|
1239
|
-
if (prev.state === state && prev.activeJobId === activeJobId && prev.sessionId === sessionId) {
|
|
1257
|
+
if (prev.state === state && prev.activeJobId === activeJobId && prev.sessionId === sessionId && prev.disabled === disabled) {
|
|
1240
1258
|
return prev;
|
|
1241
1259
|
}
|
|
1242
|
-
cached.current = { state, activeJobId, sessionId };
|
|
1260
|
+
cached.current = { state, activeJobId, sessionId, disabled };
|
|
1243
1261
|
return cached.current;
|
|
1244
1262
|
}, []);
|
|
1245
1263
|
return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
@@ -1403,12 +1421,18 @@ function CodeEntryPanel({ position }) {
|
|
|
1403
1421
|
if (!trimmed) return;
|
|
1404
1422
|
setResolving(true);
|
|
1405
1423
|
setError(null);
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1424
|
+
try {
|
|
1425
|
+
const instance = Runhuman.getInstance();
|
|
1426
|
+
const result = await instance.getApiClient().resolveShortCode(trimmed);
|
|
1427
|
+
if (result) {
|
|
1428
|
+
await instance.activate(result.jobId);
|
|
1429
|
+
} else {
|
|
1430
|
+
setError("Invalid or expired code");
|
|
1431
|
+
setResolving(false);
|
|
1432
|
+
}
|
|
1433
|
+
} catch (err) {
|
|
1434
|
+
const message = err instanceof Error ? err.message : "Activation failed";
|
|
1435
|
+
setError(message);
|
|
1412
1436
|
setResolving(false);
|
|
1413
1437
|
}
|
|
1414
1438
|
};
|
|
@@ -1499,6 +1523,7 @@ var positionMap = {
|
|
|
1499
1523
|
function RunhumanProvider({
|
|
1500
1524
|
children,
|
|
1501
1525
|
apiKey,
|
|
1526
|
+
enabled = true,
|
|
1502
1527
|
position = "bottom-right",
|
|
1503
1528
|
baseUrl,
|
|
1504
1529
|
jobId,
|
|
@@ -1511,7 +1536,7 @@ function RunhumanProvider({
|
|
|
1511
1536
|
}) {
|
|
1512
1537
|
const initializedRef = (0, import_react5.useRef)(false);
|
|
1513
1538
|
(0, import_react5.useEffect)(() => {
|
|
1514
|
-
if (initializedRef.current) return;
|
|
1539
|
+
if (!enabled || initializedRef.current) return;
|
|
1515
1540
|
initializedRef.current = true;
|
|
1516
1541
|
const config = {
|
|
1517
1542
|
apiKey,
|
|
@@ -1529,13 +1554,14 @@ function RunhumanProvider({
|
|
|
1529
1554
|
initializedRef.current = false;
|
|
1530
1555
|
Runhuman.getInstance().destroy();
|
|
1531
1556
|
};
|
|
1532
|
-
}, []);
|
|
1533
|
-
const { state, activeJobId } = useSensorState();
|
|
1557
|
+
}, [enabled]);
|
|
1558
|
+
const { state, activeJobId, disabled } = useSensorState();
|
|
1559
|
+
const showOverlay = enabled && !disabled;
|
|
1534
1560
|
const posKey = positionMap[position];
|
|
1535
1561
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles.container, children: [
|
|
1536
1562
|
children,
|
|
1537
|
-
state === "idle" && !activeJobId ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CodeEntryPanel, { position: posKey }) : null,
|
|
1538
|
-
state !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ActiveIndicator, { state, position: posKey }) : null
|
|
1563
|
+
showOverlay && state === "idle" && !activeJobId ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CodeEntryPanel, { position: posKey }) : null,
|
|
1564
|
+
showOverlay && state !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ActiveIndicator, { state, position: posKey }) : null
|
|
1539
1565
|
] });
|
|
1540
1566
|
}
|
|
1541
1567
|
var styles = import_react_native4.StyleSheet.create({
|