@stim-cli/core 1.9.0 → 1.10.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.
@@ -0,0 +1,507 @@
1
+ //#region state/config-types.d.ts
2
+ type SettingsObject = Record<string, unknown>;
3
+ interface SupervisorRecord {
4
+ processToken?: string;
5
+ pid?: number;
6
+ port?: number;
7
+ startedAt?: string;
8
+ serverPid?: number;
9
+ mode?: string;
10
+ [key: string]: unknown;
11
+ }
12
+ interface IosDeviceRecord {
13
+ deviceUdid?: string;
14
+ deviceName?: string | null;
15
+ owned?: boolean;
16
+ serial?: string;
17
+ simslimManaged?: boolean;
18
+ [key: string]: unknown;
19
+ }
20
+ interface AndroidDeviceRecord {
21
+ avdName?: string;
22
+ consolePort?: number;
23
+ serial?: string;
24
+ kind?: string;
25
+ deviceName?: string | null;
26
+ owned?: boolean;
27
+ setupIncomplete?: boolean;
28
+ [key: string]: unknown;
29
+ }
30
+ type DeviceRecord = IosDeviceRecord | AndroidDeviceRecord;
31
+ interface PlatformRecords {
32
+ ios?: IosDeviceRecord;
33
+ android?: AndroidDeviceRecord;
34
+ [platform: string]: DeviceRecord | undefined;
35
+ }
36
+ interface ProjectRecord {
37
+ ports?: Record<string, number>;
38
+ metroPort?: number | null;
39
+ platforms?: PlatformRecords;
40
+ deviceSlots?: Record<string, PlatformRecords>;
41
+ supervisor?: SupervisorRecord;
42
+ settings?: SettingsObject;
43
+ worktreeRoot?: boolean;
44
+ worktreeBranch?: string;
45
+ worktreeBranchOwned?: boolean;
46
+ worktreeMainRoot?: string;
47
+ worktreeRemovalComplete?: boolean;
48
+ worktreePendingBranchSha?: string;
49
+ label?: string;
50
+ bundleId?: string;
51
+ androidPackage?: string;
52
+ isExpo?: boolean;
53
+ lastBuild?: Record<string, unknown>;
54
+ doctorRuns?: Partial<Record<"ios" | "android", DoctorRunRecord>>;
55
+ [key: string]: unknown;
56
+ }
57
+ interface DoctorRunRecord {
58
+ at: string;
59
+ version: string;
60
+ }
61
+ interface RepoRecord {
62
+ settings?: SettingsObject;
63
+ [key: string]: unknown;
64
+ }
65
+ interface ConcurrencyLimits {
66
+ maxBuilds: number;
67
+ maxDevices: number;
68
+ }
69
+ interface StimConfig {
70
+ version?: number;
71
+ projects: Record<string, ProjectRecord>;
72
+ repos: Record<string, RepoRecord>;
73
+ tempDir?: unknown;
74
+ iosSimulatorApp?: unknown;
75
+ optimizations?: unknown;
76
+ concurrency?: {
77
+ maxBuilds?: unknown;
78
+ maxDevices?: unknown;
79
+ };
80
+ pool?: {
81
+ iosParkedMax?: unknown;
82
+ androidParkedMax?: unknown;
83
+ };
84
+ parked?: {
85
+ ios?: unknown;
86
+ android?: unknown;
87
+ };
88
+ caches?: {
89
+ buildCache?: unknown;
90
+ metroCache?: unknown;
91
+ };
92
+ [key: string]: unknown;
93
+ }
94
+ type Config = StimConfig;
95
+ //#endregion
96
+ //#region state/config.d.ts
97
+ declare function withConfigLock<T>(fn: () => T): T;
98
+ declare function configCorruptRepair(path?: string): string;
99
+ declare function loadConfig(): Config | null;
100
+ declare function getProject(projectPath: string): ProjectRecord | null;
101
+ declare function getConcurrencyLimits({ env }?: {
102
+ env?: NodeJS.ProcessEnv;
103
+ }): ConcurrencyLimits;
104
+ declare function getProjectSettings(projectPath: string): Record<string, unknown>;
105
+ declare function getProjectSetting(projectPath: string, dottedKey: string): unknown;
106
+ declare function getRepoSettings(gitCommonDir: string): Record<string, unknown>;
107
+ declare function isPathPrefix(prefix: string, path: string): boolean;
108
+ declare function findEnclosingWorktreeRoot(projectPath: string): string | null;
109
+ declare function allMetroPorts(): number[];
110
+ declare function findProjectByMetroPort(port: number): string | null;
111
+ //#endregion
112
+ //#region state/json-file.d.ts
113
+ declare function readJsonFile(path: string): unknown;
114
+ declare function isJsonObject(value: unknown): value is Record<string, unknown>;
115
+ declare function readJsonObject(path: string): Record<string, unknown> | null;
116
+ //#endregion
117
+ //#region state/ledgers.d.ts
118
+ type CreatedDevicePlatform = "ios" | "android";
119
+ interface CreatedDevices {
120
+ ios: ReadonlySet<string>;
121
+ android: ReadonlySet<string>;
122
+ }
123
+ declare function readCreatedDevices(): CreatedDevices;
124
+ interface EasSessionClaim {
125
+ sessionId: string;
126
+ name: string;
127
+ platform: "ios" | "android";
128
+ workspaceRoot: string;
129
+ workspaceHome: string;
130
+ stateFile: string;
131
+ }
132
+ interface EasSessionLedgerRead {
133
+ claims: Map<string, EasSessionClaim>;
134
+ notice: string | null;
135
+ safe: boolean;
136
+ }
137
+ /** Returns the claim normalized to canonical paths, or null when it is not a valid claim for `id`. */
138
+ declare function validEasSessionClaim(id: string, value: unknown): EasSessionClaim | null;
139
+ declare function readEasSessionLedger(root?: string): EasSessionLedgerRead;
140
+ //#endregion
141
+ //#region state/ndjson.d.ts
142
+ interface NdjsonRecord {
143
+ ts?: number;
144
+ src?: string;
145
+ level?: string;
146
+ msg?: string;
147
+ [key: string]: unknown;
148
+ }
149
+ declare const LEVELS: string[];
150
+ declare const SOURCES: string[];
151
+ declare function levelRank(level?: string): number;
152
+ declare function parseNdjsonLine(line: unknown): NdjsonRecord | null;
153
+ declare function parseNdjsonText(text: unknown): NdjsonRecord[];
154
+ declare function readNdjsonGenerations(file: string): NdjsonRecord[];
155
+ //#endregion
156
+ //#region state/logs-query.d.ts
157
+ interface SinceResult {
158
+ ms?: number;
159
+ error?: string;
160
+ }
161
+ interface GrepResult {
162
+ re?: RegExp;
163
+ error?: string;
164
+ }
165
+ interface MarkerWindow {
166
+ launchTs: number | null;
167
+ bundleTs: number | null;
168
+ }
169
+ interface QueryCriteria {
170
+ slot?: string;
171
+ includeNativeCrashes?: boolean;
172
+ sources?: string[];
173
+ minLevel?: string;
174
+ grep?: RegExp;
175
+ sinceTs?: number;
176
+ errorsOnly?: boolean;
177
+ markerTs?: number;
178
+ bundleMarkerTs?: number;
179
+ }
180
+ interface TailState {
181
+ offset: number;
182
+ partial: string;
183
+ }
184
+ declare function parseSince(text: unknown): SinceResult;
185
+ declare function compileGrep(pattern: unknown): GrepResult;
186
+ declare const ERROR_SOURCES: string[];
187
+ declare function markerWindow(records: NdjsonRecord[]): MarkerWindow;
188
+ declare function recordMatches(record: NdjsonRecord | null | undefined, criteria?: QueryCriteria): boolean;
189
+ declare function buildCriteria({ slot, sources, minLevel, since, grep, errorsOnly, markerTs, bundleMarkerTs, now }?: {
190
+ slot?: string;
191
+ sources?: string[];
192
+ minLevel?: string;
193
+ since?: string | null;
194
+ grep?: string | RegExp | null;
195
+ errorsOnly?: boolean;
196
+ markerTs?: number;
197
+ bundleMarkerTs?: number;
198
+ now?: number;
199
+ }): QueryCriteria;
200
+ declare function logFiles(dir: string): string[];
201
+ declare function fileSizes(dir: string): Record<string, number>;
202
+ declare function readLogRecords(dir: string, include?: (name: string) => boolean): NdjsonRecord[];
203
+ declare function attachExpoErrorContext(all: NdjsonRecord[], matched: NdjsonRecord[]): NdjsonRecord[];
204
+ declare function queryLogs({ slot, dir, records, sources, minLevel, since, grep, tail, errorsOnly, errorContext, now }?: {
205
+ slot?: string;
206
+ dir?: string;
207
+ records?: NdjsonRecord[];
208
+ sources?: string[];
209
+ minLevel?: string;
210
+ since?: string;
211
+ grep?: string | RegExp;
212
+ tail?: number;
213
+ errorsOnly?: boolean;
214
+ errorContext?: boolean;
215
+ now?: number;
216
+ }): NdjsonRecord[];
217
+ declare function tailRead(prev: TailState | null | undefined, size: number): {
218
+ start: number;
219
+ prev: TailState;
220
+ };
221
+ declare function advanceTail(prev: TailState | null | undefined, chunk: string | null | undefined, size: number): {
222
+ state: TailState;
223
+ records: NdjsonRecord[];
224
+ };
225
+ declare function followLogs({ dir, onRecord, criteria, intervalMs, offsets }: {
226
+ dir: string;
227
+ onRecord: (record: NdjsonRecord) => void;
228
+ criteria?: QueryCriteria;
229
+ intervalMs?: number;
230
+ offsets?: Record<string, number> | null;
231
+ }): () => void;
232
+ declare function sortByTs(records: NdjsonRecord[]): NdjsonRecord[];
233
+ //#endregion
234
+ //#region state/paths.d.ts
235
+ declare function getConfigPath(): string;
236
+ declare function configLockPath(): string;
237
+ declare function workspaceMetadataFile(projectRoot: string): string;
238
+ declare function workspaceLogsDir(projectRoot: string): string;
239
+ declare function workspaceLogErrorIndex(projectRoot: string): string;
240
+ declare function workspaceDerivedData(projectRoot: string): string;
241
+ declare function workspaceGradleBuild(projectRoot: string): string;
242
+ declare function supervisorPidFile(projectRoot: string): string;
243
+ declare function workspaceStateFile(projectRoot: string): string;
244
+ declare function workspaceStateLock(projectRoot: string): string;
245
+ declare function supervisorLogFile(projectRoot: string): string;
246
+ declare function emulatorLogFile(projectRoot: string): string;
247
+ declare function sharedCompilationCache(): string;
248
+ declare function sharedCcache(): string;
249
+ declare function sharedGradle(): string;
250
+ declare function sharedPods(): string;
251
+ declare function createdDevicesFile(): string;
252
+ declare function createdDevicesLock(): string;
253
+ /** The EAS session ledger lives under the real home directory, never under STIM_HOME. */
254
+ declare function easMachineStateRoot(): string;
255
+ declare function easSessionLedgerFile(root?: string): string;
256
+ declare function easSessionLedgerLock(root?: string): string;
257
+ //#endregion
258
+ //#region state/settings-registry.d.ts
259
+ declare const ANDROID_COMPILER_CACHE_CHOICES: readonly ["auto", "ccache", "cas", "none"];
260
+ declare const ANDROID_PCH_CHOICES: readonly ["auto", "on", "off"];
261
+ type TunnelMode = "auto" | "off" | "expo" | "cloudflared" | "ngrok";
262
+ declare const TUNNEL_MODES: readonly TunnelMode[];
263
+ type RemoteDeviceBackend = "proxy" | "eas";
264
+ type SettingScope = "machine" | "workspace" | "repo" | "committed";
265
+ declare const SETTING_SCOPES: readonly SettingScope[];
266
+ type SettingType = {
267
+ kind: "string";
268
+ pattern?: string;
269
+ patternHelp?: string;
270
+ } | {
271
+ kind: "path";
272
+ absolute?: boolean;
273
+ relative?: boolean;
274
+ } | {
275
+ kind: "strings";
276
+ } | {
277
+ kind: "number";
278
+ integer?: boolean;
279
+ minimum?: number;
280
+ maximum?: number;
281
+ } | {
282
+ kind: "boolean";
283
+ } | {
284
+ kind: "choice";
285
+ choices: readonly string[];
286
+ } | {
287
+ kind: "object";
288
+ } | {
289
+ kind: "bundle-url";
290
+ };
291
+ /**
292
+ * One setting Stim reads. `scopes` are the layers the setting may be written to;
293
+ * `committedAt: 'repository'` reads the committed layer from the repository root's
294
+ * `.stim.json` instead of the app's. A `sensitive` value is never printed and is
295
+ * written to `.stim.json` only as an `env:` or `file:` reference. `scopedHomeValue`
296
+ * replaces every layer and the default while STIM_HOME is set and `env` is not.
297
+ */
298
+ interface SettingDefinition {
299
+ key: string;
300
+ type: SettingType;
301
+ scopes: readonly SettingScope[];
302
+ description: string;
303
+ default?: string | number | boolean;
304
+ env?: string;
305
+ sensitive?: boolean;
306
+ committedAt?: "repository";
307
+ scopedHomeValue?: number;
308
+ }
309
+ interface SettingEntry {
310
+ key: string;
311
+ value: unknown;
312
+ origin: SettingScope | "env" | "default" | null;
313
+ layers: Partial<Record<SettingScope, unknown>>;
314
+ env?: {
315
+ name: string;
316
+ value: string;
317
+ };
318
+ sensitive?: true;
319
+ }
320
+ /** The payload `stim settings --json` prints. */
321
+ interface SettingsPayload {
322
+ project: string | null;
323
+ files: Partial<Record<SettingScope, string>>;
324
+ settings: SettingEntry[];
325
+ unknown: Array<{
326
+ key: string;
327
+ scope: SettingScope;
328
+ file: string;
329
+ value: unknown;
330
+ }>;
331
+ }
332
+ declare const REMOTE_DEVICE_BACKENDS: readonly RemoteDeviceBackend[];
333
+ declare const IOS_SIMULATOR_APPS: readonly ["xcode", "siniulator", "stim-desktop"];
334
+ declare const SETTINGS: readonly SettingDefinition[];
335
+ declare function settingDefinition(key: string): SettingDefinition | null;
336
+ declare function isLayeredSetting(setting: SettingDefinition): boolean;
337
+ declare const SETTING_GROUPS: readonly string[];
338
+ declare function expectedShape(type: SettingType): string;
339
+ declare function acceptsShape(setting: SettingDefinition, value: unknown): boolean;
340
+ declare function settingValueError(setting: SettingDefinition, value: unknown): string | null;
341
+ declare function isSensitiveReference(value: unknown): boolean;
342
+ /**
343
+ * Coerces raw text (a CLI argument or an environment variable) through a setting's
344
+ * registry type, the same way for both sources. Types whose values are not written
345
+ * as bare text (boolean, number, strings, object) are read as JSON; a value that
346
+ * fails to parse is left as the original string so `settingValueError` reports it.
347
+ */
348
+ declare function coerceSettingText(setting: SettingDefinition, raw: string): unknown;
349
+ //#endregion
350
+ //#region state/settings-schema.d.ts
351
+ declare const SETTINGS_SCHEMA_FILE = "settings.schema.json";
352
+ declare const SETTINGS_SCHEMA_URL: string;
353
+ type JsonSchema = Record<string, unknown>;
354
+ /**
355
+ * The published settings schema. The root describes a committed `.stim.json`;
356
+ * `$defs.machine` describes the settings keys of `$STIM_HOME/config.json`.
357
+ * Every leaf carries `x-stim` with its dotted key, kind, writable scopes,
358
+ * environment override, and sensitivity.
359
+ */
360
+ declare function settingsJsonSchema(): JsonSchema;
361
+ //#endregion
362
+ //#region state/workspace-state.d.ts
363
+ interface WorkspaceState {
364
+ supervisor?: Record<string, unknown>;
365
+ collectors?: Record<string, unknown>;
366
+ lastBuild?: Record<string, unknown>;
367
+ launches?: Record<string, unknown>;
368
+ remoteDevice?: Record<string, unknown>;
369
+ metroTunnel?: Record<string, unknown>;
370
+ [key: string]: unknown;
371
+ }
372
+ declare const IDLE_STOP_KEY = "devServerStop";
373
+ /** Why the supervisor last stopped the dev server on its own: `metro.idleStopMinutes` with no use. */
374
+ interface IdleStopRecord {
375
+ reason: "idle";
376
+ at: string;
377
+ idleMinutes: number;
378
+ }
379
+ declare function readIdleStop(state: WorkspaceState | null | undefined): IdleStopRecord | null;
380
+ declare function readWorkspaceState(root: string): WorkspaceState | null;
381
+ declare function lastUseFrom(state: WorkspaceState | null, logMtimes: readonly number[]): number;
382
+ declare function workspaceLastUsed(root: string): number;
383
+ //#endregion
384
+ //#region state/status.d.ts
385
+ type StatsPlatform = "ios" | "android";
386
+ type RunOutcomeKind = "hit" | "cold";
387
+ declare const BUILD_PHASES: readonly ["prepare", "cache-lookup", "wait", "prebuild", "pods", "compile", "install", "launch"];
388
+ type BuildPhase = (typeof BUILD_PHASES)[number];
389
+ type ActiveBuildState = "running" | "stale" | "unknown";
390
+ interface BuildReport {
391
+ platform: StatsPlatform;
392
+ slot: string;
393
+ state: ActiveBuildState;
394
+ phase: BuildPhase;
395
+ startedAt: string;
396
+ phaseStartedAt: string;
397
+ outcome: RunOutcomeKind | null;
398
+ expectedMs: number | null;
399
+ expectedPhaseMs: number | null;
400
+ basis: number;
401
+ }
402
+ type ActivityState = "driven" | "active" | "idle" | "unknown";
403
+ interface ActivityDriver {
404
+ tool: string;
405
+ pid: number | null;
406
+ since: string | null;
407
+ }
408
+ interface DeviceActivity {
409
+ state: ActivityState;
410
+ driver?: ActivityDriver;
411
+ lastActivityAt?: string;
412
+ basis: string[];
413
+ }
414
+ interface WorktreeFacts {
415
+ path: string;
416
+ branch?: string;
417
+ repository?: string;
418
+ }
419
+ interface AndroidRuntimeFacts {
420
+ serial: string | null;
421
+ state: "detected" | "not-detected" | "missing" | "unknown";
422
+ error?: string;
423
+ }
424
+ interface RemoteDeviceState {
425
+ platform: "ios" | "android" | null;
426
+ backend: "eas";
427
+ sessionId: string;
428
+ state: "claimed" | "unclaimed" | "unknown";
429
+ startedAt: string | null;
430
+ webPreviewUrl: string | null;
431
+ }
432
+ interface EnvironmentState {
433
+ slots?: {
434
+ slot: string;
435
+ ios: EnvironmentState["ios"];
436
+ android: EnvironmentState["android"];
437
+ }[];
438
+ path: string;
439
+ live: boolean;
440
+ memoryMb: number;
441
+ warnings: string[];
442
+ ios?: {
443
+ name: string | null;
444
+ udid: string;
445
+ owned: boolean;
446
+ state: string;
447
+ activity?: DeviceActivity;
448
+ } | null;
449
+ android?: {
450
+ name: string | undefined;
451
+ owned: boolean;
452
+ physical: boolean;
453
+ serial?: string | null;
454
+ state?: AndroidRuntimeFacts["state"];
455
+ activity?: DeviceActivity;
456
+ } | null;
457
+ metro?: {
458
+ port: number;
459
+ running: boolean;
460
+ pid: number | null;
461
+ idleStop?: IdleStopRecord;
462
+ } | null;
463
+ supervisor?: {
464
+ pid: number | null;
465
+ mode: string | null;
466
+ startedAt: string | null;
467
+ healthy: boolean;
468
+ } | null;
469
+ logs?: {
470
+ dir: string;
471
+ errorsSinceMarker: number;
472
+ } | null;
473
+ worktree?: WorktreeFacts | null;
474
+ remoteDevices?: RemoteDeviceState[];
475
+ build?: BuildReport | null;
476
+ }
477
+ interface StatusCapacity {
478
+ liveCount: number;
479
+ committedMb: number;
480
+ totalMemoryMb: number;
481
+ overCapacity: boolean;
482
+ }
483
+ interface DeviceLeaseState {
484
+ slot?: string;
485
+ path: string;
486
+ platform: string;
487
+ id: string | null;
488
+ deviceName: string | null;
489
+ holder: string | null;
490
+ grantedAt: string | null;
491
+ expiresAt: string | null;
492
+ mine: boolean;
493
+ expired: boolean;
494
+ parsed: boolean;
495
+ }
496
+ /** The payload `stim status --json` prints, and `status --watch --json` prints on each change. */
497
+ interface StatusPayload {
498
+ environments: (EnvironmentState & {
499
+ labelOnly?: true;
500
+ })[];
501
+ capacity: StatusCapacity;
502
+ deviceLeases: DeviceLeaseState[];
503
+ unprovisionedWorktrees: WorktreeFacts[];
504
+ simctlAvailable: boolean;
505
+ }
506
+ //#endregion
507
+ export { ANDROID_COMPILER_CACHE_CHOICES, ANDROID_PCH_CHOICES, ActiveBuildState, ActivityDriver, AndroidRuntimeFacts, BUILD_PHASES, BuildPhase, BuildReport, ConcurrencyLimits, Config, CreatedDevicePlatform, CreatedDevices, DeviceActivity, DeviceLeaseState, DeviceRecord, DoctorRunRecord, ERROR_SOURCES, EasSessionClaim, EasSessionLedgerRead, EnvironmentState, IDLE_STOP_KEY, IOS_SIMULATOR_APPS, IdleStopRecord, LEVELS, NdjsonRecord, PlatformRecords, ProjectRecord, QueryCriteria, REMOTE_DEVICE_BACKENDS, RemoteDeviceBackend, RemoteDeviceState, RepoRecord, RunOutcomeKind, SETTINGS, SETTINGS_SCHEMA_FILE, SETTINGS_SCHEMA_URL, SETTING_GROUPS, SETTING_SCOPES, SOURCES, SettingDefinition, SettingEntry, SettingScope, SettingType, SettingsObject, SettingsPayload, StatsPlatform, StatusCapacity, StatusPayload, StimConfig, SupervisorRecord, TUNNEL_MODES, TunnelMode, WorkspaceState, WorktreeFacts, acceptsShape, advanceTail, allMetroPorts, attachExpoErrorContext, buildCriteria, coerceSettingText, compileGrep, configCorruptRepair, configLockPath, createdDevicesFile, createdDevicesLock, easMachineStateRoot, easSessionLedgerFile, easSessionLedgerLock, emulatorLogFile, expectedShape, fileSizes, findEnclosingWorktreeRoot, findProjectByMetroPort, followLogs, getConcurrencyLimits, getConfigPath, getProject, getProjectSetting, getProjectSettings, getRepoSettings, isJsonObject, isLayeredSetting, isPathPrefix, isSensitiveReference, lastUseFrom, levelRank, loadConfig, logFiles, markerWindow, parseNdjsonLine, parseNdjsonText, parseSince, queryLogs, readCreatedDevices, readEasSessionLedger, readIdleStop, readJsonFile, readJsonObject, readLogRecords, readNdjsonGenerations, readWorkspaceState, recordMatches, settingDefinition, settingValueError, settingsJsonSchema, sharedCcache, sharedCompilationCache, sharedGradle, sharedPods, sortByTs, supervisorLogFile, supervisorPidFile, tailRead, validEasSessionClaim, withConfigLock, workspaceDerivedData, workspaceGradleBuild, workspaceLastUsed, workspaceLogErrorIndex, workspaceLogsDir, workspaceMetadataFile, workspaceStateFile, workspaceStateLock };