screenci 0.0.70 → 0.0.72

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 (108) hide show
  1. package/README.md +13 -13
  2. package/dist/cli.d.ts +9 -0
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +184 -5
  5. package/dist/cli.js.map +1 -1
  6. package/dist/docs/manifest.d.ts +34 -34
  7. package/dist/docs/manifest.d.ts.map +1 -1
  8. package/dist/docs/manifest.js +20 -12
  9. package/dist/docs/manifest.js.map +1 -1
  10. package/dist/docs/video-sources/installation.screenci.js +13 -12
  11. package/dist/docs/video-sources/installation.screenci.js.map +1 -1
  12. package/dist/docs/video-sources/landing.screenci.js +16 -9
  13. package/dist/docs/video-sources/landing.screenci.js.map +1 -1
  14. package/dist/docs/video-sources/locator-highlight-animated.screenci.js +14 -26
  15. package/dist/docs/video-sources/locator-highlight-animated.screenci.js.map +1 -1
  16. package/dist/docs/video-sources/locator-highlight-still.screenci.js +5 -10
  17. package/dist/docs/video-sources/locator-highlight-still.screenci.js.map +1 -1
  18. package/dist/docs/video-sources/product-pitch.screenci.js +97 -32
  19. package/dist/docs/video-sources/product-pitch.screenci.js.map +1 -1
  20. package/dist/docs/video-sources/public-urls.screenci.js +16 -9
  21. package/dist/docs/video-sources/public-urls.screenci.js.map +1 -1
  22. package/dist/docs/video-sources/studio.screenci.js +42 -27
  23. package/dist/docs/video-sources/studio.screenci.js.map +1 -1
  24. package/dist/docs/videos.d.ts +4 -15
  25. package/dist/docs/videos.d.ts.map +1 -1
  26. package/dist/docs/videos.js +6 -22
  27. package/dist/docs/videos.js.map +1 -1
  28. package/dist/index.d.ts +7 -5
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -4
  31. package/dist/index.js.map +1 -1
  32. package/dist/src/asset.d.ts +8 -23
  33. package/dist/src/asset.d.ts.map +1 -1
  34. package/dist/src/asset.js +10 -32
  35. package/dist/src/asset.js.map +1 -1
  36. package/dist/src/audio.d.ts +6 -24
  37. package/dist/src/audio.d.ts.map +1 -1
  38. package/dist/src/audio.js +10 -35
  39. package/dist/src/audio.js.map +1 -1
  40. package/dist/src/builder.d.ts +214 -0
  41. package/dist/src/builder.d.ts.map +1 -0
  42. package/dist/src/builder.js +212 -0
  43. package/dist/src/builder.js.map +1 -0
  44. package/dist/src/cue.d.ts +40 -123
  45. package/dist/src/cue.d.ts.map +1 -1
  46. package/dist/src/cue.js +190 -30
  47. package/dist/src/cue.js.map +1 -1
  48. package/dist/src/events.d.ts +80 -15
  49. package/dist/src/events.d.ts.map +1 -1
  50. package/dist/src/events.js +72 -6
  51. package/dist/src/events.js.map +1 -1
  52. package/dist/src/init.d.ts.map +1 -1
  53. package/dist/src/init.js +26 -14
  54. package/dist/src/init.js.map +1 -1
  55. package/dist/src/locales.d.ts +19 -0
  56. package/dist/src/locales.d.ts.map +1 -0
  57. package/dist/src/locales.js +60 -0
  58. package/dist/src/locales.js.map +1 -0
  59. package/dist/src/localize.d.ts +135 -0
  60. package/dist/src/localize.d.ts.map +1 -0
  61. package/dist/src/localize.js +195 -0
  62. package/dist/src/localize.js.map +1 -0
  63. package/dist/src/localizeRuntime.d.ts +53 -0
  64. package/dist/src/localizeRuntime.d.ts.map +1 -0
  65. package/dist/src/localizeRuntime.js +79 -0
  66. package/dist/src/localizeRuntime.js.map +1 -0
  67. package/dist/src/recordingData.d.ts +5 -4
  68. package/dist/src/recordingData.d.ts.map +1 -1
  69. package/dist/src/runtimeContext.d.ts +3 -4
  70. package/dist/src/runtimeContext.d.ts.map +1 -1
  71. package/dist/src/runtimeContext.js.map +1 -1
  72. package/dist/src/runtimeMode.d.ts +47 -0
  73. package/dist/src/runtimeMode.d.ts.map +1 -1
  74. package/dist/src/runtimeMode.js +124 -0
  75. package/dist/src/runtimeMode.js.map +1 -1
  76. package/dist/src/screenshot.d.ts +56 -2
  77. package/dist/src/screenshot.d.ts.map +1 -1
  78. package/dist/src/screenshot.js +47 -10
  79. package/dist/src/screenshot.js.map +1 -1
  80. package/dist/src/stillCapture.d.ts +2 -3
  81. package/dist/src/stillCapture.d.ts.map +1 -1
  82. package/dist/src/stillCapture.js.map +1 -1
  83. package/dist/src/studio.d.ts +55 -22
  84. package/dist/src/studio.d.ts.map +1 -1
  85. package/dist/src/studio.js +38 -12
  86. package/dist/src/studio.js.map +1 -1
  87. package/dist/src/types.d.ts +18 -5
  88. package/dist/src/types.d.ts.map +1 -1
  89. package/dist/src/types.js.map +1 -1
  90. package/dist/src/video.d.ts +149 -13
  91. package/dist/src/video.d.ts.map +1 -1
  92. package/dist/src/video.js +91 -24
  93. package/dist/src/video.js.map +1 -1
  94. package/dist/src/voiceConfig.d.ts +110 -0
  95. package/dist/src/voiceConfig.d.ts.map +1 -0
  96. package/dist/src/voiceConfig.js +2 -0
  97. package/dist/src/voiceConfig.js.map +1 -0
  98. package/dist/src/voices.d.ts +27 -23
  99. package/dist/src/voices.d.ts.map +1 -1
  100. package/dist/src/voices.js +7 -4
  101. package/dist/src/voices.js.map +1 -1
  102. package/dist/tsconfig.tsbuildinfo +1 -1
  103. package/package.json +1 -1
  104. package/skills/screenci/SKILL.md +39 -30
  105. package/dist/docs/video-sources/cli.screenci.d.ts +0 -2
  106. package/dist/docs/video-sources/cli.screenci.d.ts.map +0 -1
  107. package/dist/docs/video-sources/cli.screenci.js +0 -36
  108. package/dist/docs/video-sources/cli.screenci.js.map +0 -1
package/README.md CHANGED
@@ -31,7 +31,7 @@ npx screenci record # render and upload the final video
31
31
  Full docs:
32
32
 
33
33
  - [Getting started](https://screenci.com/docs)
34
- - [Writing scripts](https://screenci.com/docs/write-video-scripts)
34
+ - [Writing scripts](https://screenci.com/docs/video-script-basics)
35
35
  - [CLI reference](https://screenci.com/docs/reference/cli)
36
36
 
37
37
  ## Write a video
@@ -71,18 +71,18 @@ but remap its rendered duration.
71
71
 
72
72
  ## Authoring helpers
73
73
 
74
- | Export | What it does |
75
- | ----------------- | -------------------------------------------------------- |
76
- | `defineConfig` | Wraps Playwright config with ScreenCI defaults |
77
- | `video` | Declares a video recording test |
78
- | `createNarration` | Creates typed narration controllers |
79
- | `hide` | Cuts setup or cleanup out of the visible recording |
80
- | `autoZoom` | Smooth camera follow for an interaction block |
81
- | `zoomTo` | Manual camera framing for a locator or point |
82
- | `resetZoom` | Returns from manual framing to the full viewport |
83
- | `createOverlays` | Inserts timed media overlays into the recording timeline |
84
- | `voices` | Available voice constants such as `voices.Ava` |
85
- | `modelTypes` | Narration model constants |
74
+ | Export | What it does |
75
+ | ---------------- | ------------------------------------------------------------ |
76
+ | `defineConfig` | Wraps Playwright config with ScreenCI defaults |
77
+ | `video` | Declares a video recording test |
78
+ | `video.localize` | Declares localized narration / text and records per language |
79
+ | `hide` | Cuts setup or cleanup out of the visible recording |
80
+ | `autoZoom` | Smooth camera follow for an interaction block |
81
+ | `zoomTo` | Manual camera framing for a locator or point |
82
+ | `resetZoom` | Returns from manual framing to the full viewport |
83
+ | `createOverlays` | Inserts timed media overlays into the recording timeline |
84
+ | `voices` | Available voice constants such as `voices.Ava` |
85
+ | `modelTypes` | Narration model constants |
86
86
 
87
87
  See the [docs](https://screenci.com/docs) for configuration, narration,
88
88
  camera, and CI setup.
package/dist/cli.d.ts CHANGED
@@ -69,10 +69,19 @@ export declare function extractConfigStringLiteral(configSource: string, propert
69
69
  export declare function extractRecordUploadPolicyLiteral(configSource: string): RecordUploadPolicy | undefined;
70
70
  export declare function extractMockRecordLiteral(configSource: string): boolean | undefined;
71
71
  export declare function getConfigModuleSpecifier(resolvedConfigPath: string): string;
72
+ export declare function extractGrep(args: string[]): string | undefined;
72
73
  export declare function ensureScreenciSecret(resolvedConfigPath?: string, opts?: {
73
74
  interactive?: boolean;
74
75
  pollAuth?: boolean;
75
76
  }): Promise<string | undefined>;
76
77
  export declare function main(): Promise<void>;
78
+ export declare function parseRecordCliArgs(args: string[]): {
79
+ configPath: string | undefined;
80
+ verbose: boolean;
81
+ pollAuth: boolean;
82
+ remote: boolean;
83
+ languages: string | undefined;
84
+ otherArgs: string[];
85
+ };
77
86
  export declare function logCliError(error: unknown): void;
78
87
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EAEd,MAAM,iBAAiB,CAAA;AAMxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,gBAAgB,CAAA;AAKxE,OAAO,EAGL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EAOlB,MAAM,sBAAsB,CAAA;AAQ7B,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAA;AAqBvE,KAAK,yBAAyB,GAAG;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,yBAAyB,EAAE,CAAA;CACrC,CAAA;AAUD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,MAAM,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAmB,EAC5C,KAAK,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAkB,GACzC,OAAO,CAIT;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,yBAAyB,EAAE,GAC3C,MAAM,EAAE,CAiBV;AAiND,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AASD,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAAA;AAEjE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,gBAAgB,CAAA;CACzB,CAAA;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED,KAAK,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAA;AAkE9C,wBAAsB,eAAe,CAAC,CAAC,EACrC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,WAAW,SAAI,GACd,OAAO,CAAC,CAAC,CAAC,CAWZ;AAoTD,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,GAAG,KAAK,GAAG,OAAO,CAAC,EACtD,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,GACxC,MAAM,IAAI,CAiBZ;AAkaD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAiGhC;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,QAAQ,GAAG,uBAAuB,GACxC,QAAQ,GAAG,uBAAuB,CAKpC;AAED,wBAAgB,oCAAoC,CAClD,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,mBAAmB,EAAE,GAC5B,aAAa,CAqEf;AAQD,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,MAAM,CAeR;AAKD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CASR;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,IAAI,CAcN;AA8GD,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,UAAQ,GACd,OAAO,CAAC;IACT,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,mBAAmB,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClE,aAAa,EAAE,kBAAkB,EAAE,CAAA;IACnC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CACrB,CAAC,CA8GD;AA8LD,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,aAAa,GAAG,SAAS,GAClC,MAAM,GAAG,SAAS,CAepB;AAED,wBAAgB,gCAAgC,CAC9C,YAAY,EAAE,MAAM,GACnB,kBAAkB,GAAG,SAAS,CAmBhC;AAED,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,GACnB,OAAO,GAAG,SAAS,CAQrB;AAkCD,wBAAgB,wBAAwB,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAS3E;AA0QD,wBAAsB,oBAAoB,CACxC,kBAAkB,CAAC,EAAE,MAAM,EAC3B,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACvD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA8I7B;AAED,wBAAsB,IAAI,kBAuWzB;AA8ND,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAchD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import { Command, CommanderError } from 'commander';
10
10
  import pc from 'picocolors';
11
11
  import { logger } from './src/logger.js';
12
12
  import { determinePackageManager, parsePackageManager, runInit, } from './src/init.js';
13
- import { SCREENCI_DISABLE_RECORDING_TIMINGS_ENV, SCREENCI_MOCK_RECORD_ENV, } from './src/runtimeMode.js';
13
+ import { SCREENCI_DISABLE_RECORDING_TIMINGS_ENV, SCREENCI_MOCK_RECORD_ENV, SCREENCI_LANGUAGES_ENV, SCREENCI_TEXT_OVERRIDES_ENV, SCREENCI_RECORD_OPTIONS_ENV, } from './src/runtimeMode.js';
14
14
  import { DEFAULT_RECORD_UPLOAD_POLICY } from './src/defaults.js';
15
15
  import { findDuplicateTitles, formatDuplicateTitlesMessage, } from './src/titleValidation.js';
16
16
  import { createLinkSessionSpec, deletePersistedLinkSessionSpec, getCliLinkSessionApiUrl, getDevBackendUrl, getDevFrontendUrl, getLinkSessionFilePath, getScreenCIEnvironment, isStoredLinkSessionReusable, readPersistedLinkSessionSpec, SCREENCI_LINK_SESSION_FILE, writePersistedLinkSessionSpec, } from './src/linkSession.js';
@@ -1004,7 +1004,7 @@ export function formatFailedVideoMessage(videoName, message) {
1004
1004
  if (message.startsWith(EXPRESSIVE_TIER_ERROR_PREFIX)) {
1005
1005
  return [
1006
1006
  `${videoName}: ${message}`,
1007
- "If you want to keep using the current tier, remove `voice.style` or `modelType: 'expressive'` from `createNarration()`.",
1007
+ "If you want to keep using the current tier, remove `voice.style` or `modelType: 'expressive'` from the localize `voice`.",
1008
1008
  ].join('\n');
1009
1009
  }
1010
1010
  return `${videoName}: ${message}`;
@@ -1425,6 +1425,54 @@ async function updateVideoVisibility(videoId, isPublic, configPath) {
1425
1425
  }
1426
1426
  logger.info(`${isPublic ? 'Made public' : 'Made private'}: ${videoId}`);
1427
1427
  }
1428
+ // Extract a `--grep <value>` / `--grep=<value>` from the pass-through args so a
1429
+ // remote trigger can forward it as a filter (records only matching videos).
1430
+ export function extractGrep(args) {
1431
+ for (let i = 0; i < args.length; i++) {
1432
+ const arg = args[i];
1433
+ if (arg === undefined)
1434
+ continue;
1435
+ if (arg === '--grep' || arg === '-g') {
1436
+ return args[i + 1];
1437
+ }
1438
+ if (arg.startsWith('--grep=')) {
1439
+ return arg.slice('--grep='.length);
1440
+ }
1441
+ }
1442
+ return undefined;
1443
+ }
1444
+ // `screenci record --remote` triggers the project's GitHub Actions recording
1445
+ // workflow instead of recording locally. The project is resolved from the
1446
+ // existing SCREENCI_SECRET + config `projectName`, exactly like the other
1447
+ // authenticated commands; the backend dispatches the workflow using the GitHub
1448
+ // token stored for the project. An optional `--grep` records only matching
1449
+ // videos/screenshots.
1450
+ async function triggerRemoteRun(configPath, grep, languages) {
1451
+ const { screenciConfig, secret, apiUrl } = await requireScreenCISecret(configPath, { interactive: detectInteractiveSession() });
1452
+ const res = await fetch(`${apiUrl}/cli/trigger-run`, {
1453
+ method: 'POST',
1454
+ headers: {
1455
+ 'X-ScreenCI-Secret': secret,
1456
+ 'Content-Type': 'application/json',
1457
+ },
1458
+ body: JSON.stringify({
1459
+ projectName: screenciConfig.projectName,
1460
+ ...(grep ? { grep } : {}),
1461
+ ...(languages ? { languages } : {}),
1462
+ }),
1463
+ });
1464
+ if (!res.ok) {
1465
+ const text = await res.text();
1466
+ throw new Error(`Failed to trigger remote run: ${res.status} ${text}${hint401(res.status, secret)}`);
1467
+ }
1468
+ const filters = [
1469
+ ...(grep ? [`filter: ${grep}`] : []),
1470
+ ...(languages ? [`languages: ${languages}`] : []),
1471
+ ];
1472
+ logger.info(filters.length > 0
1473
+ ? `Triggered the remote recording workflow for "${screenciConfig.projectName}" (${filters.join(', ')}).`
1474
+ : `Triggered the remote recording workflow for "${screenciConfig.projectName}".`);
1475
+ }
1428
1476
  function getLastRecordFilePath(screenciDir) {
1429
1477
  return resolve(screenciDir, SCREENCI_LAST_RECORD_FILE);
1430
1478
  }
@@ -1677,12 +1725,22 @@ export async function main() {
1677
1725
  .description('Record videos using Playwright')
1678
1726
  .option('-v, --verbose', 'verbose output')
1679
1727
  .option('--poll-auth', 'wait for sign-in to complete (polling every 5s, up to 5 minutes) instead of exiting, then continue recording')
1728
+ .option('--remote', 'trigger the GitHub Actions recording workflow for this project remotely instead of recording locally')
1729
+ .option('--languages <langs>', 'record/render only these languages (comma-separated, e.g. fi,en)')
1680
1730
  .allowUnknownOption(true)
1681
1731
  .action(async () => {
1682
1732
  const parsed = parseRecordCliArgs(getSubcommandArgv('record'));
1733
+ // `--remote` is a pure dispatch: it fires the project's GitHub Actions
1734
+ // recording workflow and exits, so there is no local Playwright run. A
1735
+ // pass-through `--grep` becomes the remote recording filter, and
1736
+ // `--languages` limits which language versions are recorded.
1737
+ if (parsed.remote) {
1738
+ await triggerRemoteRun(parsed.configPath, extractGrep(parsed.otherArgs), parsed.languages);
1739
+ return;
1740
+ }
1683
1741
  let playwrightFailure = null;
1684
1742
  try {
1685
- await run('record', parsed.otherArgs, parsed.configPath, parsed.verbose, false, parsed.pollAuth);
1743
+ await run('record', parsed.otherArgs, parsed.configPath, parsed.verbose, false, parsed.pollAuth, parsed.languages);
1686
1744
  }
1687
1745
  catch (error) {
1688
1746
  if (!(error instanceof Error))
@@ -1915,10 +1973,12 @@ function getSubcommandArgv(command) {
1915
1973
  const commandIndex = argv.indexOf(command);
1916
1974
  return commandIndex === -1 ? [] : argv.slice(commandIndex + 1);
1917
1975
  }
1918
- function parseRecordCliArgs(args) {
1976
+ export function parseRecordCliArgs(args) {
1919
1977
  let configPath;
1920
1978
  let verbose = false;
1921
1979
  let pollAuth = false;
1980
+ let remote = false;
1981
+ let languages;
1922
1982
  const otherArgs = [];
1923
1983
  for (let i = 0; i < args.length; i++) {
1924
1984
  const arg = args[i];
@@ -1933,12 +1993,29 @@ function parseRecordCliArgs(args) {
1933
1993
  configPath = nextArg;
1934
1994
  i++;
1935
1995
  }
1996
+ else if (arg === '--languages' || arg === '--language') {
1997
+ // screenci-only flag: parsed out so it is not forwarded to Playwright.
1998
+ const nextArg = args[i + 1];
1999
+ if (nextArg === undefined) {
2000
+ logger.error('Error: --languages requires a comma-separated value');
2001
+ process.exit(1);
2002
+ }
2003
+ languages = nextArg;
2004
+ i++;
2005
+ }
2006
+ else if (arg.startsWith('--languages=') ||
2007
+ arg.startsWith('--language=')) {
2008
+ languages = arg.slice(arg.indexOf('=') + 1);
2009
+ }
1936
2010
  else if (arg === '--verbose' || arg === '-v') {
1937
2011
  verbose = true;
1938
2012
  }
1939
2013
  else if (arg === '--poll-auth') {
1940
2014
  pollAuth = true;
1941
2015
  }
2016
+ else if (arg === '--remote') {
2017
+ remote = true;
2018
+ }
1942
2019
  else {
1943
2020
  otherArgs.push(arg);
1944
2021
  }
@@ -1947,6 +2024,8 @@ function parseRecordCliArgs(args) {
1947
2024
  configPath,
1948
2025
  verbose,
1949
2026
  pollAuth,
2027
+ remote,
2028
+ languages,
1950
2029
  otherArgs,
1951
2030
  };
1952
2031
  }
@@ -1997,7 +2076,85 @@ function validateArgs(args) {
1997
2076
  }
1998
2077
  }
1999
2078
  }
2000
- async function run(command, additionalArgs, customConfigPath, verbose = false, mockRecord = false, pollAuth = false) {
2079
+ /**
2080
+ * Fetch the project's current Studio text-field overrides so they can be
2081
+ * injected as SCREENCI_TEXT_OVERRIDES before a recording. On-screen `text`
2082
+ * fields render during the recording (they cannot be patched at render time),
2083
+ * so any Studio edits must be present here; code-declared seeds are the
2084
+ * fallback. Best-effort: any failure returns an empty env so the SDK uses the
2085
+ * code seeds, and a recording is never blocked by this fetch.
2086
+ */
2087
+ async function fetchTextOverridesEnv(configPath, languages, verbose) {
2088
+ try {
2089
+ const { screenciConfig, secret, apiUrl } = await requireScreenCISecret(configPath, { interactive: false });
2090
+ const params = new URLSearchParams({
2091
+ projectName: screenciConfig.projectName,
2092
+ });
2093
+ if (languages)
2094
+ params.set('languages', languages);
2095
+ const res = await fetch(`${apiUrl}/cli/text-overrides?${params.toString()}`, { headers: { 'X-ScreenCI-Secret': secret } });
2096
+ if (!res.ok) {
2097
+ if (verbose) {
2098
+ logger.warn(`Could not fetch Studio text overrides (${res.status}); using code-declared values.`);
2099
+ }
2100
+ return {};
2101
+ }
2102
+ const body = (await res.json());
2103
+ const overrides = body.overrides;
2104
+ if (overrides === undefined ||
2105
+ overrides === null ||
2106
+ typeof overrides !== 'object' ||
2107
+ Object.keys(overrides).length === 0) {
2108
+ return {};
2109
+ }
2110
+ return { [SCREENCI_TEXT_OVERRIDES_ENV]: JSON.stringify(overrides) };
2111
+ }
2112
+ catch (error) {
2113
+ if (verbose) {
2114
+ logger.warn(`Could not fetch Studio text overrides; using code-declared values.${error instanceof Error ? ` (${error.message})` : ''}`);
2115
+ }
2116
+ return {};
2117
+ }
2118
+ }
2119
+ /**
2120
+ * Fetch the project's current Studio record-option overrides so they can be
2121
+ * injected as SCREENCI_RECORD_OPTIONS before a recording. Record options (aspect
2122
+ * ratio, quality, fps) change the captured viewport/encode, so any Studio edits
2123
+ * must be present here; code-declared values are the fallback. Best-effort: any
2124
+ * failure returns an empty env so the SDK uses the code values, and a recording
2125
+ * is never blocked by this fetch.
2126
+ */
2127
+ async function fetchRecordOptionsEnv(configPath, verbose) {
2128
+ try {
2129
+ const { screenciConfig, secret, apiUrl } = await requireScreenCISecret(configPath, { interactive: false });
2130
+ const params = new URLSearchParams({
2131
+ projectName: screenciConfig.projectName,
2132
+ });
2133
+ const res = await fetch(`${apiUrl}/cli/record-options?${params.toString()}`, { headers: { 'X-ScreenCI-Secret': secret } });
2134
+ if (!res.ok) {
2135
+ if (verbose) {
2136
+ logger.warn(`Could not fetch Studio record options (${res.status}); using code-declared values.`);
2137
+ }
2138
+ return {};
2139
+ }
2140
+ const body = (await res.json());
2141
+ const recordOptions = body.recordOptions;
2142
+ if (recordOptions === undefined ||
2143
+ recordOptions === null ||
2144
+ typeof recordOptions !== 'object' ||
2145
+ Object.keys(recordOptions).length === 0) {
2146
+ return {};
2147
+ }
2148
+ return { [SCREENCI_RECORD_OPTIONS_ENV]: JSON.stringify(recordOptions) };
2149
+ }
2150
+ catch (error) {
2151
+ if (verbose) {
2152
+ logger.warn(`Could not fetch Studio record options; using code-declared values.${error instanceof Error ? ` (${error.message})` : ''}`);
2153
+ }
2154
+ return {};
2155
+ }
2156
+ }
2157
+ async function run(command, additionalArgs, customConfigPath, verbose = false, mockRecord = false, pollAuth = false, languages) {
2001
2158
  const configPath = resolveScreenCIConfigPathOrExit(customConfigPath);
2002
2159
  if (command === 'test' || process.env.SCREENCI_RECORDING !== 'true') {
2003
2160
  await loadEnvFileFromConfigSource(configPath, false);
@@ -2014,11 +2171,25 @@ async function run(command, additionalArgs, customConfigPath, verbose = false, m
2014
2171
  const screenciDir = resolve(dirname(configPath), '.screenci');
2015
2172
  clearRecordingDirectories(screenciDir);
2016
2173
  }
2174
+ // Studio text-field overrides are injected for the record command only: they
2175
+ // resolve in the SDK's `text` fixture before the recording runs. `test` (the
2176
+ // preview run) keeps code-declared values.
2177
+ const textOverridesEnv = command === 'record'
2178
+ ? await fetchTextOverridesEnv(configPath, languages, verbose)
2179
+ : {};
2180
+ // Studio record-option overrides are likewise injected for record only: they
2181
+ // resolve in the SDK's `recordOptions` fixture before the capture runs.
2182
+ const recordOptionsEnv = command === 'record' ? await fetchRecordOptionsEnv(configPath, verbose) : {};
2017
2183
  const envForChild = { ...process.env };
2018
2184
  await validateUniqueDiscoveredTestTitles(configPath, additionalArgs, {
2019
2185
  ...envForChild,
2020
2186
  SCREENCI_CONFIG_DIR: dirname(configPath),
2021
2187
  ...(command === 'record' ? { SCREENCI_RECORDING: 'true' } : {}),
2188
+ ...(command === 'record' && languages
2189
+ ? { [SCREENCI_LANGUAGES_ENV]: languages }
2190
+ : {}),
2191
+ ...textOverridesEnv,
2192
+ ...recordOptionsEnv,
2022
2193
  ...(command === 'test' && !mockRecord
2023
2194
  ? { [SCREENCI_DISABLE_RECORDING_TIMINGS_ENV]: 'true' }
2024
2195
  : {}),
@@ -2045,6 +2216,14 @@ async function run(command, additionalArgs, customConfigPath, verbose = false, m
2045
2216
  SCREENCI_CONFIG_DIR: dirname(configPath),
2046
2217
  // Enable recording only for record command
2047
2218
  ...(command === 'record' ? { SCREENCI_RECORDING: 'true' } : {}),
2219
+ // Per-language filter: the builder records only these languages.
2220
+ ...(command === 'record' && languages
2221
+ ? { [SCREENCI_LANGUAGES_ENV]: languages }
2222
+ : {}),
2223
+ // Studio text-field overrides resolved from the backend (record only).
2224
+ ...textOverridesEnv,
2225
+ // Studio record-option overrides resolved from the backend (record only).
2226
+ ...recordOptionsEnv,
2048
2227
  ...(command === 'test' && !mockRecord
2049
2228
  ? { [SCREENCI_DISABLE_RECORDING_TIMINGS_ENV]: 'true' }
2050
2229
  : {}),