@limrun/api 0.48.4 → 0.49.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.
Files changed (170) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/client.d.mts +6 -3
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +6 -3
  5. package/client.d.ts.map +1 -1
  6. package/client.js +4 -4
  7. package/client.js.map +1 -1
  8. package/client.mjs +2 -2
  9. package/client.mjs.map +1 -1
  10. package/destination-tunnel-dialer.d.mts +30 -2
  11. package/destination-tunnel-dialer.d.mts.map +1 -1
  12. package/destination-tunnel-dialer.d.ts +30 -2
  13. package/destination-tunnel-dialer.d.ts.map +1 -1
  14. package/destination-tunnel-dialer.js +349 -65
  15. package/destination-tunnel-dialer.js.map +1 -1
  16. package/destination-tunnel-dialer.mjs +345 -64
  17. package/destination-tunnel-dialer.mjs.map +1 -1
  18. package/destination-tunnel-har.d.mts +23 -0
  19. package/destination-tunnel-har.d.mts.map +1 -0
  20. package/destination-tunnel-har.d.ts +23 -0
  21. package/destination-tunnel-har.d.ts.map +1 -0
  22. package/destination-tunnel-har.js +164 -0
  23. package/destination-tunnel-har.js.map +1 -0
  24. package/destination-tunnel-har.mjs +160 -0
  25. package/destination-tunnel-har.mjs.map +1 -0
  26. package/destination-tunnel-inspection.d.mts +71 -0
  27. package/destination-tunnel-inspection.d.mts.map +1 -0
  28. package/destination-tunnel-inspection.d.ts +71 -0
  29. package/destination-tunnel-inspection.d.ts.map +1 -0
  30. package/destination-tunnel-inspection.js +267 -0
  31. package/destination-tunnel-inspection.js.map +1 -0
  32. package/destination-tunnel-inspection.mjs +261 -0
  33. package/destination-tunnel-inspection.mjs.map +1 -0
  34. package/destination-tunnel.d.mts +119 -14
  35. package/destination-tunnel.d.mts.map +1 -1
  36. package/destination-tunnel.d.ts +119 -14
  37. package/destination-tunnel.d.ts.map +1 -1
  38. package/destination-tunnel.js +407 -98
  39. package/destination-tunnel.js.map +1 -1
  40. package/destination-tunnel.mjs +374 -73
  41. package/destination-tunnel.mjs.map +1 -1
  42. package/index.d.mts +6 -0
  43. package/index.d.mts.map +1 -1
  44. package/index.d.ts +6 -0
  45. package/index.d.ts.map +1 -1
  46. package/index.js +23 -2
  47. package/index.js.map +1 -1
  48. package/index.mjs +5 -0
  49. package/index.mjs.map +1 -1
  50. package/instance-client.d.mts +105 -1
  51. package/instance-client.d.mts.map +1 -1
  52. package/instance-client.d.ts +105 -1
  53. package/instance-client.d.ts.map +1 -1
  54. package/instance-client.js +83 -1
  55. package/instance-client.js.map +1 -1
  56. package/instance-client.mjs +83 -1
  57. package/instance-client.mjs.map +1 -1
  58. package/internal/destination-tunnel-management.d.mts +4 -3
  59. package/internal/destination-tunnel-management.d.mts.map +1 -1
  60. package/internal/destination-tunnel-management.d.ts +4 -3
  61. package/internal/destination-tunnel-management.d.ts.map +1 -1
  62. package/internal/destination-tunnel-management.js +64 -46
  63. package/internal/destination-tunnel-management.js.map +1 -1
  64. package/internal/destination-tunnel-management.mjs +55 -37
  65. package/internal/destination-tunnel-management.mjs.map +1 -1
  66. package/internal/destination-tunnel-url.d.mts +2 -0
  67. package/internal/destination-tunnel-url.d.mts.map +1 -1
  68. package/internal/destination-tunnel-url.d.ts +2 -0
  69. package/internal/destination-tunnel-url.d.ts.map +1 -1
  70. package/internal/destination-tunnel-url.js +45 -5
  71. package/internal/destination-tunnel-url.js.map +1 -1
  72. package/internal/destination-tunnel-url.mjs +44 -5
  73. package/internal/destination-tunnel-url.mjs.map +1 -1
  74. package/internal/destination-tunnel-wire-reader.d.mts +23 -0
  75. package/internal/destination-tunnel-wire-reader.d.mts.map +1 -0
  76. package/internal/destination-tunnel-wire-reader.d.ts +23 -0
  77. package/internal/destination-tunnel-wire-reader.d.ts.map +1 -0
  78. package/internal/destination-tunnel-wire-reader.js +110 -0
  79. package/internal/destination-tunnel-wire-reader.js.map +1 -0
  80. package/internal/destination-tunnel-wire-reader.mjs +93 -0
  81. package/internal/destination-tunnel-wire-reader.mjs.map +1 -0
  82. package/internal/persist-option.d.mts +14 -0
  83. package/internal/persist-option.d.mts.map +1 -0
  84. package/internal/persist-option.d.ts +14 -0
  85. package/internal/persist-option.d.ts.map +1 -0
  86. package/internal/persist-option.js +18 -0
  87. package/internal/persist-option.js.map +1 -0
  88. package/internal/persist-option.mjs +15 -0
  89. package/internal/persist-option.mjs.map +1 -0
  90. package/internal/proxy-transport.d.mts +27 -0
  91. package/internal/proxy-transport.d.mts.map +1 -1
  92. package/internal/proxy-transport.d.ts +27 -0
  93. package/internal/proxy-transport.d.ts.map +1 -1
  94. package/internal/proxy-transport.js +206 -0
  95. package/internal/proxy-transport.js.map +1 -1
  96. package/internal/proxy-transport.mjs +205 -0
  97. package/internal/proxy-transport.mjs.map +1 -1
  98. package/internal/session-stream.d.mts +39 -0
  99. package/internal/session-stream.d.mts.map +1 -0
  100. package/internal/session-stream.d.ts +39 -0
  101. package/internal/session-stream.d.ts.map +1 -0
  102. package/internal/session-stream.js +144 -0
  103. package/internal/session-stream.js.map +1 -0
  104. package/internal/session-stream.mjs +139 -0
  105. package/internal/session-stream.mjs.map +1 -0
  106. package/internal/tslib.js +4 -4
  107. package/ios-client.d.mts +61 -4
  108. package/ios-client.d.mts.map +1 -1
  109. package/ios-client.d.ts +61 -4
  110. package/ios-client.d.ts.map +1 -1
  111. package/ios-client.js +48 -2
  112. package/ios-client.js.map +1 -1
  113. package/ios-client.mjs +48 -2
  114. package/ios-client.mjs.map +1 -1
  115. package/package.json +22 -1
  116. package/resources/android-instances-helpers.d.mts +25 -0
  117. package/resources/android-instances-helpers.d.mts.map +1 -0
  118. package/resources/android-instances-helpers.d.ts +25 -0
  119. package/resources/android-instances-helpers.d.ts.map +1 -0
  120. package/resources/android-instances-helpers.js +37 -0
  121. package/resources/android-instances-helpers.js.map +1 -0
  122. package/resources/android-instances-helpers.mjs +33 -0
  123. package/resources/android-instances-helpers.mjs.map +1 -0
  124. package/resources/index.d.mts +5 -2
  125. package/resources/index.d.mts.map +1 -1
  126. package/resources/index.d.ts +5 -2
  127. package/resources/index.d.ts.map +1 -1
  128. package/resources/index.js +5 -5
  129. package/resources/index.js.map +1 -1
  130. package/resources/index.mjs +2 -2
  131. package/resources/index.mjs.map +1 -1
  132. package/resources/ios-instances-helpers.d.mts +25 -0
  133. package/resources/ios-instances-helpers.d.mts.map +1 -0
  134. package/resources/ios-instances-helpers.d.ts +25 -0
  135. package/resources/ios-instances-helpers.d.ts.map +1 -0
  136. package/resources/ios-instances-helpers.js +37 -0
  137. package/resources/ios-instances-helpers.js.map +1 -0
  138. package/resources/ios-instances-helpers.mjs +33 -0
  139. package/resources/ios-instances-helpers.mjs.map +1 -0
  140. package/resources/session-artifacts.d.mts +70 -0
  141. package/resources/session-artifacts.d.mts.map +1 -0
  142. package/resources/session-artifacts.d.ts +70 -0
  143. package/resources/session-artifacts.d.ts.map +1 -0
  144. package/resources/session-artifacts.js +8 -0
  145. package/resources/session-artifacts.js.map +1 -0
  146. package/resources/session-artifacts.mjs +7 -0
  147. package/resources/session-artifacts.mjs.map +1 -0
  148. package/src/client.ts +4 -2
  149. package/src/destination-tunnel-dialer.ts +403 -64
  150. package/src/destination-tunnel-har.ts +200 -0
  151. package/src/destination-tunnel-inspection.ts +367 -0
  152. package/src/destination-tunnel.ts +510 -88
  153. package/src/index.ts +52 -0
  154. package/src/instance-client.ts +271 -5
  155. package/src/internal/destination-tunnel-management.ts +67 -43
  156. package/src/internal/destination-tunnel-url.ts +61 -5
  157. package/src/internal/destination-tunnel-wire-reader.ts +109 -0
  158. package/src/internal/persist-option.ts +26 -0
  159. package/src/internal/proxy-transport.ts +248 -0
  160. package/src/internal/session-stream.ts +157 -0
  161. package/src/ios-client.ts +127 -8
  162. package/src/resources/android-instances-helpers.ts +45 -0
  163. package/src/resources/index.ts +9 -2
  164. package/src/resources/ios-instances-helpers.ts +45 -0
  165. package/src/resources/session-artifacts.ts +95 -0
  166. package/src/version.ts +1 -1
  167. package/version.d.mts +1 -1
  168. package/version.d.ts +1 -1
  169. package/version.js +1 -1
  170. package/version.mjs +1 -1
package/src/ios-client.ts CHANGED
@@ -6,7 +6,7 @@ import { WebSocket, Data } from 'ws';
6
6
  import { EventEmitter } from 'events';
7
7
  import { assertPort, isNonRetryableError, startReverseTcpTunnel, type ReverseTunnel } from './tunnel';
8
8
  import { startDestinationTcpTunnel, type DestinationTcpTunnel } from './destination-tunnel-dialer';
9
- import type { DestinationTunnelRoute } from './destination-tunnel';
9
+ import { disabledDestinationTunnelInspection, type DestinationTunnelSelectors } from './destination-tunnel';
10
10
  import { type SyncFolderResult, type FolderSyncOptions, syncFolder } from './folder-sync';
11
11
  import { createIgnoreFn } from './folder-sync-ignore';
12
12
  import { prepareAppBundlePath, watchAppArchive } from './app-archive';
@@ -25,6 +25,11 @@ import {
25
25
  type StartForwardHttpProxyOptions,
26
26
  } from './http-proxy';
27
27
  import { startXcrunShim as startClientXcrunShim } from './ios-shim';
28
+ import { persistFields, type PersistOption } from './internal/persist-option';
29
+ import { streamSessionEntries } from './internal/session-stream';
30
+ import type { SessionLogLine, SessionEvent } from './resources/session-artifacts';
31
+
32
+ export { type PersistOption } from './internal/persist-option';
28
33
 
29
34
  /**
30
35
  * Connection state of the instance client
@@ -65,8 +70,8 @@ export function deriveReverseTunnelUrl(apiUrl: string, remotePort: number): stri
65
70
  export type { ReverseTunnel } from './tunnel';
66
71
  export type Tunnel = DestinationTcpTunnel;
67
72
  export type TunnelOptions = {
68
- /** Exact localhost or literal-IP TCP destinations that the server may ask this client to dial. */
69
- routes: DestinationTunnelRoute[];
73
+ /** Exact endpoint selector values that the server may ask this client to dial. */
74
+ selectors: DestinationTunnelSelectors;
70
75
  /** Controls tunnel logging verbosity. Defaults to the instance client's log level. */
71
76
  logLevel?: LogLevel;
72
77
  };
@@ -236,6 +241,8 @@ export type InstalledApp = {
236
241
  bundleId: string;
237
242
  name: string;
238
243
  installType: string;
244
+ /** App icon as a base64-encoded 64px PNG; absent when the runtime could not extract one. */
245
+ icon?: string;
239
246
  };
240
247
 
241
248
  export type LsofEntry = {
@@ -677,7 +684,8 @@ export type InstanceClient = {
677
684
 
678
685
  /**
679
686
  * List installed apps on the simulator
680
- * @returns Array of installed apps with bundleId, name, and installType
687
+ * @returns Array of installed apps with bundleId, name, installType, and,
688
+ * when available, a small base64 PNG icon
681
689
  */
682
690
  listApps: () => Promise<InstalledApp[]>;
683
691
 
@@ -758,8 +766,11 @@ export type InstanceClient = {
758
766
  * Start recording simulator video. Use stopRecording() to stop the recording.
759
767
  * When provided, `quality` must be one of `5`, `6`, `7`, `8`, `9`, or `10`.
760
768
  * The server default is `5`.
769
+ * With `persist`, the completed recording is uploaded to Limrun's bucket
770
+ * when the recording stops or the instance terminates; list it with
771
+ * `iosInstances.listRecordings`.
761
772
  */
762
- startRecording: (options?: { quality?: RecordingQuality }) => Promise<void>;
773
+ startRecording: (options?: { quality?: RecordingQuality; persist?: PersistOption }) => Promise<void>;
763
774
 
764
775
  /**
765
776
  * Stop the active server-side recording.
@@ -771,6 +782,54 @@ export type InstanceClient = {
771
782
  */
772
783
  stopRecording: (saveTo: { presignedUrl?: string; localPath?: string }) => Promise<string>;
773
784
 
785
+ /**
786
+ * Start capturing an app's logs (one JSONL object per line) for the given
787
+ * bundle id. One app log capture runs at a time; the server rejects a
788
+ * second start. With `persist`, the capture is uploaded to Limrun's bucket
789
+ * when it stops or the instance terminates; list it with
790
+ * `iosInstances.listAppLogs`.
791
+ */
792
+ startAppLogCapture: (options: { bundleId: string; persist?: PersistOption }) => Promise<void>;
793
+
794
+ /** Stop the active app log capture. */
795
+ stopAppLogCapture: () => Promise<void>;
796
+
797
+ /**
798
+ * Start capturing the coalesced event log of user and agent actions (one
799
+ * JSONL object per line). One event capture runs at a time; the server
800
+ * rejects a second start. With `persist`, the capture is uploaded to
801
+ * Limrun's bucket when it stops or the instance terminates; list it with
802
+ * `iosInstances.listEvents`.
803
+ */
804
+ startEventCapture: (options?: { persist?: PersistOption }) => Promise<void>;
805
+
806
+ /** Stop the active event capture. */
807
+ stopEventCapture: () => Promise<void>;
808
+
809
+ /**
810
+ * Tail the live app log stream fed by {@link startAppLogCapture}. On
811
+ * connect the instance replays its recent buffer (up to 1000 lines), then
812
+ * delivers lines as they are captured; a dropped connection reconnects
813
+ * and resumes exactly where it left off, so every line is delivered once.
814
+ * The stream is independent of this client's websocket and survives
815
+ * {@link disconnect}; `onError` fires at most once, after the stream has
816
+ * kept failing for several minutes (e.g. the instance was deleted), and
817
+ * the stream is closed. Returns a function that closes the stream.
818
+ */
819
+ streamAppLogCapture: (handlers: {
820
+ onLine: (line: SessionLogLine) => void;
821
+ onError?: (error: Error) => void;
822
+ }) => () => void;
823
+
824
+ /**
825
+ * Tail the live coalesced event log fed by {@link startEventCapture}.
826
+ * Same delivery and lifecycle semantics as {@link streamAppLogCapture}.
827
+ */
828
+ streamEventCapture: (handlers: {
829
+ onEvent: (event: SessionEvent) => void;
830
+ onError?: (error: Error) => void;
831
+ }) => () => void;
832
+
774
833
  /**
775
834
  * Play an audio file as the simulator's microphone input. Stage the file on
776
835
  * the instance first with `pushFile` (no bundle ID); `path` is the same
@@ -1861,6 +1920,10 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
1861
1920
  }),
1862
1921
  startVideoRecordingResult: () => undefined,
1863
1922
  stopVideoRecordingResult: () => undefined,
1923
+ startAppLogCaptureResult: () => undefined,
1924
+ stopAppLogCaptureResult: () => undefined,
1925
+ startEventCaptureResult: () => undefined,
1926
+ stopEventCaptureResult: () => undefined,
1864
1927
  cameraControlResult: () => undefined,
1865
1928
  playOnMicrophoneResult: (msg): IosPlayOnMicrophoneResult => ({
1866
1929
  duration: msg.duration ?? 0,
@@ -2055,6 +2118,12 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
2055
2118
  performActions,
2056
2119
  startRecording,
2057
2120
  stopRecording,
2121
+ startAppLogCapture,
2122
+ stopAppLogCapture,
2123
+ startEventCapture,
2124
+ stopEventCapture,
2125
+ streamAppLogCapture,
2126
+ streamEventCapture,
2058
2127
  playOnMicrophone,
2059
2128
  stopMicrophonePlayback,
2060
2129
  microphoneStatus,
@@ -2390,8 +2459,13 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
2390
2459
  return sendRequest<PerformActionsResult>('performActions', { actions }, undefined, timeoutMs);
2391
2460
  };
2392
2461
 
2393
- const startRecording = async (opts?: { quality?: RecordingQuality }): Promise<void> => {
2394
- const request: { quality?: RecordingQuality } = {};
2462
+ const startRecording = async (opts?: {
2463
+ quality?: RecordingQuality;
2464
+ persist?: PersistOption;
2465
+ }): Promise<void> => {
2466
+ const request: { quality?: RecordingQuality; persist?: boolean; ttlSeconds?: number } = {
2467
+ ...persistFields(opts?.persist),
2468
+ };
2395
2469
  if (opts?.quality !== undefined) {
2396
2470
  if (!Number.isInteger(opts.quality) || opts.quality < 5 || opts.quality > 10) {
2397
2471
  throw new Error('quality must be one of: 5, 6, 7, 8, 9, 10');
@@ -2401,6 +2475,50 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
2401
2475
  await sendRequest<void>('startVideoRecording', request);
2402
2476
  };
2403
2477
 
2478
+ const startAppLogCapture = async (opts: { bundleId: string; persist?: PersistOption }): Promise<void> => {
2479
+ if (!opts.bundleId) {
2480
+ throw new Error('bundleId must be a non-empty string');
2481
+ }
2482
+ await sendRequest<void>('startAppLogCapture', {
2483
+ bundleId: opts.bundleId,
2484
+ ...persistFields(opts.persist),
2485
+ });
2486
+ };
2487
+
2488
+ const stopAppLogCapture = async (): Promise<void> => {
2489
+ await sendRequest<void>('stopAppLogCapture');
2490
+ };
2491
+
2492
+ const startEventCapture = async (opts?: { persist?: PersistOption }): Promise<void> => {
2493
+ await sendRequest<void>('startEventCapture', { ...persistFields(opts?.persist) });
2494
+ };
2495
+
2496
+ const stopEventCapture = async (): Promise<void> => {
2497
+ await sendRequest<void>('stopEventCapture');
2498
+ };
2499
+
2500
+ const streamAppLogCapture = (handlers: {
2501
+ onLine: (line: SessionLogLine) => void;
2502
+ onError?: (error: Error) => void;
2503
+ }): (() => void) =>
2504
+ streamSessionEntries<SessionLogLine>({
2505
+ url: `${options.apiUrl}/session/applogs/events`,
2506
+ token: options.token,
2507
+ onEntry: handlers.onLine,
2508
+ onError: handlers.onError,
2509
+ });
2510
+
2511
+ const streamEventCapture = (handlers: {
2512
+ onEvent: (event: SessionEvent) => void;
2513
+ onError?: (error: Error) => void;
2514
+ }): (() => void) =>
2515
+ streamSessionEntries<SessionEvent>({
2516
+ url: `${options.apiUrl}/session/events/events`,
2517
+ token: options.token,
2518
+ onEntry: handlers.onEvent,
2519
+ onError: handlers.onError,
2520
+ });
2521
+
2404
2522
  const stopRecording = async (saveTo: { presignedUrl?: string; localPath?: string }): Promise<string> => {
2405
2523
  await sendRequest<void>('stopVideoRecording', {
2406
2524
  upload: saveTo.presignedUrl ? { presignedUrl: saveTo.presignedUrl } : undefined,
@@ -2858,7 +2976,8 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
2858
2976
 
2859
2977
  const startTunnel = async (tunnelOptions: TunnelOptions): Promise<Tunnel> => {
2860
2978
  return startDestinationTcpTunnel(deriveDestinationTunnelURL(options.apiUrl), options.token, {
2861
- routes: tunnelOptions.routes,
2979
+ selectors: tunnelOptions.selectors,
2980
+ inspection: disabledDestinationTunnelInspection(),
2862
2981
  logLevel: tunnelOptions.logLevel ?? logLevel,
2863
2982
  });
2864
2983
  };
@@ -0,0 +1,45 @@
1
+ import { AndroidInstances as GeneratedAndroidInstances } from './android-instances';
2
+ import { type SessionArtifact, type SessionArtifactKind } from './session-artifacts';
3
+ import { APIPromise } from '../core/api-promise';
4
+ import { RequestOptions } from '../internal/request-options';
5
+ import { path } from '../internal/utils/path';
6
+
7
+ export type { SessionArtifact, SessionArtifactKind } from './session-artifacts';
8
+
9
+ export class AndroidInstances extends GeneratedAndroidInstances {
10
+ /**
11
+ * List the instance's persisted session artifacts, optionally narrowed to
12
+ * one kind.
13
+ */
14
+ listSessionArtifacts(
15
+ id: string,
16
+ kind?: SessionArtifactKind,
17
+ options?: RequestOptions,
18
+ ): APIPromise<SessionArtifact[]> {
19
+ return this._client.get(path`/v1/android_instances/${id}/session_artifacts`, {
20
+ query: kind ? { kind } : undefined,
21
+ ...options,
22
+ });
23
+ }
24
+
25
+ /**
26
+ * List the instance's persisted session recordings.
27
+ */
28
+ listRecordings(id: string, options?: RequestOptions): APIPromise<SessionArtifact[]> {
29
+ return this.listSessionArtifacts(id, 'recording', options);
30
+ }
31
+
32
+ /**
33
+ * List the instance's persisted app log captures.
34
+ */
35
+ listAppLogs(id: string, options?: RequestOptions): APIPromise<SessionArtifact[]> {
36
+ return this.listSessionArtifacts(id, 'appLog', options);
37
+ }
38
+
39
+ /**
40
+ * List the instance's persisted event log captures.
41
+ */
42
+ listEvents(id: string, options?: RequestOptions): APIPromise<SessionArtifact[]> {
43
+ return this.listSessionArtifacts(id, 'eventLog', options);
44
+ }
45
+ }
@@ -8,7 +8,6 @@ export {
8
8
  type AnalyticsGetInstancesParams,
9
9
  } from './analytics';
10
10
  export {
11
- AndroidInstances,
12
11
  type AndroidInstance,
13
12
  type AndroidInstanceCreateParams,
14
13
  type AndroidInstanceListParams,
@@ -32,7 +31,6 @@ export {
32
31
  type GradleInstancesItems,
33
32
  } from './gradle-instances';
34
33
  export {
35
- IosInstances,
36
34
  type IosInstance,
37
35
  type IosInstanceCreateParams,
38
36
  type IosInstanceListParams,
@@ -46,6 +44,15 @@ export {
46
44
  type XcodeInstancesItems,
47
45
  } from './xcode-instances';
48
46
  export { Assets, AssetGetOrUploadParams, AssetGetOrUploadResponse } from './assets-helpers';
47
+ export { IosInstances } from './ios-instances-helpers';
48
+ export { AndroidInstances } from './android-instances-helpers';
49
+ export {
50
+ type SessionArtifact,
51
+ type SessionArtifactKind,
52
+ type SessionLogLine,
53
+ type SessionEvent,
54
+ type SessionEventType,
55
+ } from './session-artifacts';
49
56
  export {
50
57
  XcodeInstances,
51
58
  RbeUnsupportedError,
@@ -0,0 +1,45 @@
1
+ import { IosInstances as GeneratedIosInstances } from './ios-instances';
2
+ import { type SessionArtifact, type SessionArtifactKind } from './session-artifacts';
3
+ import { APIPromise } from '../core/api-promise';
4
+ import { RequestOptions } from '../internal/request-options';
5
+ import { path } from '../internal/utils/path';
6
+
7
+ export type { SessionArtifact, SessionArtifactKind } from './session-artifacts';
8
+
9
+ export class IosInstances extends GeneratedIosInstances {
10
+ /**
11
+ * List the instance's persisted session artifacts, optionally narrowed to
12
+ * one kind.
13
+ */
14
+ listSessionArtifacts(
15
+ id: string,
16
+ kind?: SessionArtifactKind,
17
+ options?: RequestOptions,
18
+ ): APIPromise<SessionArtifact[]> {
19
+ return this._client.get(path`/v1/ios_instances/${id}/session_artifacts`, {
20
+ query: kind ? { kind } : undefined,
21
+ ...options,
22
+ });
23
+ }
24
+
25
+ /**
26
+ * List the instance's persisted session recordings.
27
+ */
28
+ listRecordings(id: string, options?: RequestOptions): APIPromise<SessionArtifact[]> {
29
+ return this.listSessionArtifacts(id, 'recording', options);
30
+ }
31
+
32
+ /**
33
+ * List the instance's persisted app log captures.
34
+ */
35
+ listAppLogs(id: string, options?: RequestOptions): APIPromise<SessionArtifact[]> {
36
+ return this.listSessionArtifacts(id, 'appLog', options);
37
+ }
38
+
39
+ /**
40
+ * List the instance's persisted event log captures.
41
+ */
42
+ listEvents(id: string, options?: RequestOptions): APIPromise<SessionArtifact[]> {
43
+ return this.listSessionArtifacts(id, 'eventLog', options);
44
+ }
45
+ }
@@ -0,0 +1,95 @@
1
+ // Hand-written: the session-artifact list endpoint is not in the generated
2
+ // OpenAPI surface yet. Shared by the iOS and Android instance helpers.
3
+ // SessionLogLine and SessionEvent mirror pkg/artifacts/contract.go in the
4
+ // limrun repo; the runtimes emit the same JSON over live SSE and into the
5
+ // persisted JSONL artifacts.
6
+
7
+ /** The kind of a persisted session capture. */
8
+ export type SessionArtifactKind = 'recording' | 'appLog' | 'eventLog' | 'networkLog';
9
+
10
+ /**
11
+ * One persisted session capture of an instance: a video recording, an app log
12
+ * capture, a coalesced event log, or a HAR network log. Returned by the
13
+ * director's GET /v1/{ios,android}_instances/{id}/session_artifacts endpoint,
14
+ * optionally narrowed with its kind query parameter.
15
+ */
16
+ export interface SessionArtifact {
17
+ id: string;
18
+
19
+ kind: SessionArtifactKind;
20
+
21
+ /** Bundle id (iOS) or package name (Android) for app log captures. */
22
+ bundleId?: string;
23
+
24
+ /** Destination tunnel that produced a networkLog artifact. */
25
+ tunnelId?: string;
26
+
27
+ /** Canonical selectors captured by a networkLog artifact. */
28
+ selectors?: string[];
29
+
30
+ startedAt?: string;
31
+
32
+ stoppedAt?: string;
33
+
34
+ /** When the artifact is deleted from storage. */
35
+ expiresAt?: string;
36
+
37
+ sizeBytes?: number;
38
+
39
+ /**
40
+ * Short-lived presigned GET URL for the raw artifact: MP4 for recordings,
41
+ * JSONL for app logs and event logs, HAR for network logs.
42
+ */
43
+ downloadUrl: string;
44
+ }
45
+
46
+ /**
47
+ * One captured app log line, delivered live by `streamAppLogCapture` and stored
48
+ * one-per-line in `appLog` artifacts.
49
+ */
50
+ export interface SessionLogLine {
51
+ /**
52
+ * Epoch milliseconds: logcat's own timestamp on Android, receipt time on
53
+ * iOS. Shares the clock of the recording artifact's `startedAt`, so lines
54
+ * can be aligned with video playback offsets.
55
+ */
56
+ ts: number;
57
+
58
+ line: string;
59
+ }
60
+
61
+ export type SessionEventType = 'tap' | 'drag' | 'scroll' | 'key' | 'text' | 'command';
62
+
63
+ /**
64
+ * One coalesced user or agent action, delivered live by `streamEventCapture` and
65
+ * stored one-per-line in `eventLog` artifacts. The runtime logs semantic
66
+ * actions, never raw HID frames: a pointer sequence becomes one tap or drag,
67
+ * scroll and keystroke bursts merge into one event, and typed text is never
68
+ * included.
69
+ */
70
+ export interface SessionEvent {
71
+ /** The action's start in epoch milliseconds, same clock as SessionLogLine. */
72
+ ts: number;
73
+
74
+ type: SessionEventType;
75
+
76
+ /** Touch point for tap, start point for drag, anchor for scroll. */
77
+ x?: number;
78
+ y?: number;
79
+
80
+ /** Drag end point; for scroll they carry the burst's summed deltas instead. */
81
+ toX?: number;
82
+ toY?: number;
83
+
84
+ /** Duration of the whole gesture or burst. */
85
+ durationMs?: number;
86
+
87
+ /** Number of merged actions in a scroll or text burst. */
88
+ count?: number;
89
+
90
+ /**
91
+ * Short human-readable label, e.g. "launchApp com.example". Never carries
92
+ * typed text or request payloads.
93
+ */
94
+ summary?: string;
95
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.48.4'; // x-release-please-version
1
+ export const VERSION = '0.49.0'; // x-release-please-version
package/version.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.48.4";
1
+ export declare const VERSION = "0.49.0";
2
2
  //# sourceMappingURL=version.d.mts.map
package/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.48.4";
1
+ export declare const VERSION = "0.49.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
- exports.VERSION = '0.48.4'; // x-release-please-version
4
+ exports.VERSION = '0.49.0'; // x-release-please-version
5
5
  //# sourceMappingURL=version.js.map
package/version.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.48.4'; // x-release-please-version
1
+ export const VERSION = '0.49.0'; // x-release-please-version
2
2
  //# sourceMappingURL=version.mjs.map