@sailfish-ai/recorder 1.8.13 → 1.8.17

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.
@@ -1,4 +1,4 @@
1
- import { CaptureSettingsResponse, CreateTriageResponse, FunctionSpanTrackingEnabledResponse, GraphQLResponse, StartSessionResponse } from "./types";
1
+ import { CaptureSettingsResponse, CreateTriageResponse, CreateTriageAndIssueFromRecorderResponse, FunctionSpanTrackingEnabledResponse, GetEngineeringTicketPlatformIntegrationsFromApiKeyResponse, GraphQLResponse, StartSessionResponse } from "./types";
2
2
  export declare function sendGraphQLRequest<T>(operationName: string, query: string, variables: object, retries?: number, // Number of retries before giving up
3
3
  initialBackoff?: number, // Initial backoff in milliseconds
4
4
  backoffFactor?: number): Promise<GraphQLResponse<T>>;
@@ -7,3 +7,5 @@ export declare function fetchFunctionSpanTrackingEnabled(apiKey: string, backend
7
7
  export declare function startRecordingSession(apiKey: string, recordingId: string, backendApi: string, serviceIdentifier: string, serviceVersion?: string, mapUuid?: string, gitSha?: string, library?: string, serviceAdditionalMetadata?: Record<string, any>): Promise<GraphQLResponse<StartSessionResponse>>;
8
8
  export declare function sendDomainsToNotPropagateHeaderTo(apiKey: string, domains: string[], backendApi: string): Promise<GraphQLResponse<void>>;
9
9
  export declare function createTriageFromRecorder(apiKey: string, backendApi: string, recordingSessionId: string, timestampStart: string, timestampEnd: string, description?: string): Promise<GraphQLResponse<CreateTriageResponse>>;
10
+ export declare function fetchEngineeringTicketPlatformIntegrations(apiKey: string, backendApi: string): Promise<GraphQLResponse<GetEngineeringTicketPlatformIntegrationsFromApiKeyResponse>>;
11
+ export declare function createTriageAndIssueFromRecorder(apiKey: string, backendApi: string, recordingSessionId: string, timestampStart: string, timestampEnd: string, description: string, issueName: string, issueDescription: string, createEngineeringTicket: boolean, teamId?: string, projectId?: string, priority?: number, labels?: string[], issueType?: string, customFields?: any): Promise<GraphQLResponse<CreateTriageAndIssueFromRecorderResponse>>;
@@ -26,6 +26,7 @@ export declare const ReportIssueContext: {
26
26
  backendApi: string | null;
27
27
  triageBaseUrl: string;
28
28
  deactivateIsolation: () => void;
29
+ integrationData: any;
29
30
  };
30
31
  export declare function setupIssueReporting(options: {
31
32
  apiKey: string;
@@ -33,6 +34,7 @@ export declare function setupIssueReporting(options: {
33
34
  getSessionId: () => string;
34
35
  shortcuts?: Partial<ShortcutsConfig>;
35
36
  customBaseUrl?: string;
37
+ integrationData?: any;
36
38
  }): void;
37
39
  export declare function openReportIssueModal(): void;
38
40
  export {};
@@ -0,0 +1,12 @@
1
+ import { EngineeringTicketIntegration } from "../types";
2
+ import { IssueReportState } from "./types";
3
+ export declare function getIntegrationData(): EngineeringTicketIntegration | null;
4
+ export declare function hasValidIntegration(): boolean;
5
+ export declare function fetchIntegrationData(apiKey: string, backendApi: string): Promise<void>;
6
+ export declare function populateSelectOptions(selectElement: HTMLSelectElement, options: any[], defaultValue?: string): void;
7
+ export declare function populatePriorityOptions(selectElement: HTMLSelectElement, provider: string, defaultPriority?: number): void;
8
+ export declare function updateIssueTypeOptions(selectElement: HTMLSelectElement, projectId: string): void;
9
+ export declare function getFieldsForProject(projectId: string, issueTypeId?: string): any[];
10
+ export declare function getUsers(): any[];
11
+ export declare function getProjectsForTeam(teamId?: string): any[];
12
+ export declare function updateFormWithIntegrationData(currentState: IssueReportState): IssueReportState;
@@ -0,0 +1,18 @@
1
+ import { IssueReportState } from "./types";
2
+ export declare function getInitialState(): IssueReportState;
3
+ export declare let currentState: IssueReportState;
4
+ export declare let recordingStartTime: number | null;
5
+ export declare let recordingEndTime: number | null;
6
+ export declare let timerInterval: ReturnType<typeof setInterval> | null;
7
+ export declare let isRecording: boolean;
8
+ export declare function setCurrentState(state: IssueReportState): void;
9
+ export declare function resetState(): void;
10
+ export declare function setRecordingStartTime(time: number | null): void;
11
+ export declare function setRecordingEndTime(time: number | null): void;
12
+ export declare function setTimerInterval(interval: ReturnType<typeof setInterval> | null): void;
13
+ export declare function setIsRecording(recording: boolean): void;
14
+ export declare function getCurrentState(): IssueReportState;
15
+ export declare function getRecordingStartTime(): number | null;
16
+ export declare function getRecordingEndTime(): number | null;
17
+ export declare function getTimerInterval(): ReturnType<typeof setInterval> | null;
18
+ export declare function getIsRecording(): boolean;
@@ -0,0 +1,40 @@
1
+ export type TimeCaptureMode = "lookback" | "startnow";
2
+ export interface IssueReportState {
3
+ mode: TimeCaptureMode;
4
+ description: string;
5
+ occurredInThisTab: boolean;
6
+ createIssue: boolean;
7
+ issueName: string;
8
+ issueDescription: string;
9
+ createEngTicket: boolean;
10
+ engTicketTeam: string;
11
+ engTicketProject: string;
12
+ engTicketPriority: number;
13
+ engTicketLabels: string[];
14
+ engTicketIssueType: string;
15
+ engTicketCustomFields: Record<string, any>;
16
+ }
17
+ export type ShortcutConfig = {
18
+ key: string;
19
+ requireCmdCtrl?: boolean;
20
+ };
21
+ export type ShortcutsConfig = {
22
+ openReportIssue?: ShortcutConfig;
23
+ openStartNowMode?: ShortcutConfig;
24
+ };
25
+ export declare const STORAGE_KEYS: {
26
+ readonly CREATE_ISSUE: "sf-create-issue-preference";
27
+ readonly CREATE_ENG_TICKET: "sf-create-eng-ticket-preference";
28
+ };
29
+ export declare const DEFAULT_SHORTCUTS: ShortcutsConfig;
30
+ export declare const ReportIssueContext: {
31
+ shortcuts: {
32
+ openReportIssue?: ShortcutConfig;
33
+ openStartNowMode?: ShortcutConfig;
34
+ };
35
+ resolveSessionId: (() => string) | null;
36
+ apiKey: string | null;
37
+ backendApi: string | null;
38
+ triageBaseUrl: string;
39
+ deactivateIsolation: () => void;
40
+ };
@@ -0,0 +1,6 @@
1
+ import { IssueReportState, TimeCaptureMode } from "./types";
2
+ export declare function renderCustomMultiSelect(fieldId: string, fieldName: string, options: any[], selectedValues: string[], isRequired?: boolean): string;
3
+ export declare function getChevronSVG(isExpanded: boolean): string;
4
+ export declare function generateCollapsibleSection(id: string, title: string, content: string, isExpanded?: boolean): string;
5
+ export declare function renderDynamicField(field: any, fieldValue: any, users?: any[]): string | null;
6
+ export declare function generateModalHTML(currentState: IssueReportState, initialMode?: TimeCaptureMode): string;
@@ -59,3 +59,33 @@ export interface CreateTriageResponse {
59
59
  id: string;
60
60
  };
61
61
  }
62
+ export interface EngineeringTicketIntegration {
63
+ pushAutoIdentifiedIssues: boolean;
64
+ provider: string;
65
+ clientId: string;
66
+ defaultPriority?: number;
67
+ defaultProject?: string;
68
+ defaultTeam?: string;
69
+ primaryCloudId?: string;
70
+ installed: boolean;
71
+ projects?: any[];
72
+ teams?: any[];
73
+ workflowStates?: any[];
74
+ webhookState?: string;
75
+ clouds?: any[];
76
+ labels?: any[];
77
+ sprints?: any[];
78
+ users?: any[];
79
+ fieldConfigurations?: any;
80
+ invalidFields?: any[];
81
+ jiraReporterAccountId?: string;
82
+ }
83
+ export interface GetEngineeringTicketPlatformIntegrationsFromApiKeyResponse {
84
+ getEngineeringTicketPlatformIntegrationsFromApiKey: EngineeringTicketIntegration[];
85
+ }
86
+ export interface CreateTriageAndIssueFromRecorderResponse {
87
+ createTriageAndIssueFromRecorder: {
88
+ id: string;
89
+ title: string;
90
+ };
91
+ }
package/dist/websocket.js CHANGED
@@ -10,7 +10,7 @@ const MAX_MESSAGE_SIZE_MB = 50;
10
10
  const MAX_MESSAGE_SIZE_BYTES = MAX_MESSAGE_SIZE_MB * 1024 * 1024;
11
11
  // Function span tracking header constants
12
12
  const FUNCSPAN_HEADER_NAME = "X-Sf3-FunctionSpanCaptureOverride";
13
- const FUNCSPAN_HEADER_VALUE = "1-0-5-5-0-1.0";
13
+ const FUNCSPAN_HEADER_VALUE = "1-1-10-10-1-1.0-1-0-0";
14
14
  // Tracking configuration type constants (must match backend TrackingConfigurationType enum)
15
15
  const TRACKING_CONFIG_GLOBAL = "global";
16
16
  const TRACKING_CONFIG_PER_SESSION = "per_session";
@@ -39,7 +39,7 @@ function saveGlobalFuncSpanState(enabled, expirationTimestampMs) {
39
39
  const state = {
40
40
  enabled,
41
41
  expirationTimestampMs,
42
- savedAt: Date.now()
42
+ savedAt: Date.now(),
43
43
  };
44
44
  localStorage.setItem(FUNCSPAN_STORAGE_KEY, JSON.stringify(state));
45
45
  if (DEBUG) {
@@ -117,7 +117,7 @@ export function clearStaleFuncSpanState() {
117
117
  if (DEBUG) {
118
118
  console.log(`[Sailfish] Module init: Restored global function span tracking from localStorage:`, {
119
119
  enabled: true,
120
- expirationTime: funcSpanExpirationTime
120
+ expirationTime: funcSpanExpirationTime,
121
121
  });
122
122
  }
123
123
  // Check if tracking has already expired
@@ -256,7 +256,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
256
256
  webSocket.addEventListener("open", () => {
257
257
  if (DEBUG) {
258
258
  console.log("[Sailfish] WebSocket connection opened");
259
- console.log(`[Sailfish] Function span tracking state: ${funcSpanTrackingEnabled ? 'ENABLED' : 'DISABLED'}`);
259
+ console.log(`[Sailfish] Function span tracking state: ${funcSpanTrackingEnabled ? "ENABLED" : "DISABLED"}`);
260
260
  }
261
261
  (async () => {
262
262
  try {
@@ -289,7 +289,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
289
289
  console.log(`[Sailfish] Received funcSpanTrackingControl message:`, {
290
290
  enabled: data.enabled,
291
291
  timeoutSeconds: data.timeoutSeconds,
292
- expirationTimestampMs: data.expirationTimestampMs
292
+ expirationTimestampMs: data.expirationTimestampMs,
293
293
  });
294
294
  }
295
295
  // Clear any existing timeout
@@ -301,7 +301,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
301
301
  funcSpanTrackingEnabled = data.enabled;
302
302
  isLocalTrackingMode = false; // Mark as global tracking, not local
303
303
  if (DEBUG) {
304
- console.log(`[Sailfish] Function span tracking ${data.enabled ? 'ENABLED (GLOBAL)' : 'DISABLED (GLOBAL)'}`);
304
+ console.log(`[Sailfish] Function span tracking ${data.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)"}`);
305
305
  }
306
306
  if (data.enabled) {
307
307
  // Use server-provided expiration timestamp for synchronization across all clients/pods
@@ -364,7 +364,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
364
364
  // Fallback: no server timestamp provided, use local calculation (legacy behavior)
365
365
  const timeoutSeconds = data.timeoutSeconds || 3600; // Default 1 hour
366
366
  if (timeoutSeconds > 0) {
367
- funcSpanExpirationTime = Date.now() + (timeoutSeconds * 1000);
367
+ funcSpanExpirationTime = Date.now() + timeoutSeconds * 1000;
368
368
  // Save to localStorage for persistence across page refreshes
369
369
  saveGlobalFuncSpanState(true, funcSpanExpirationTime);
370
370
  funcSpanTimeoutId = window.setTimeout(() => {
@@ -406,7 +406,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
406
406
  type: "funcSpanTrackingSessionReport",
407
407
  sessionId: sessionId,
408
408
  enabled: true,
409
- configurationType: TRACKING_CONFIG_GLOBAL
409
+ configurationType: TRACKING_CONFIG_GLOBAL,
410
410
  }));
411
411
  if (DEBUG) {
412
412
  console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${sessionId}`);
@@ -591,6 +591,6 @@ export function getFuncSpanHeader() {
591
591
  }
592
592
  return {
593
593
  name: FUNCSPAN_HEADER_NAME,
594
- value: FUNCSPAN_HEADER_VALUE
594
+ value: FUNCSPAN_HEADER_VALUE,
595
595
  };
596
596
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailfish-ai/recorder",
3
- "version": "1.8.13",
3
+ "version": "1.8.17",
4
4
  "publishPublicly": true,
5
5
  "type": "module",
6
6
  "main": "dist/recorder.cjs",
@@ -37,7 +37,7 @@
37
37
  "dist"
38
38
  ],
39
39
  "dependencies": {
40
- "@sailfish-ai/sf-map-utils": "0.4.4",
40
+ "@sailfish-ai/sf-map-utils": "0.4.5",
41
41
  "@sailfish-rrweb/rrweb-plugin-console-record": "0.5.2",
42
42
  "@sailfish-rrweb/rrweb-record-only": "0.5.2",
43
43
  "@sailfish-rrweb/types": "0.5.2",
@@ -66,5 +66,10 @@
66
66
  "vite-plugin-compression": "^0.5.1",
67
67
  "vite-tsconfig-paths": "^4.3.2",
68
68
  "vitest": "^3.0.8"
69
+ },
70
+ "overrides": {
71
+ "babel-plugin-istanbul": {
72
+ "test-exclude": "^7.0.1"
73
+ }
69
74
  }
70
75
  }