@playdrop/playdrop-cli 0.13.1 → 0.13.2

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,7 +1,7 @@
1
1
  {
2
- "version": "0.13.1",
2
+ "version": "0.13.2",
3
3
  "build": 1,
4
- "runtimeSdkVersion": "0.13.1",
4
+ "runtimeSdkVersion": "0.13.2",
5
5
  "runtimeSdkBuild": 1,
6
6
  "clients": {
7
7
  "all": {
@@ -304,6 +304,15 @@ export declare function parseCodexModelCatalog(output: string): string[];
304
304
  export declare function parseClaudeModelCatalog(output: string): string[];
305
305
  export declare function claudeModelProbeReportsSelection(output: string, expectedDisplayName: string): boolean;
306
306
  export declare function probeWorkerProviderIndependently<T>(probe: () => T, unavailable: T): T;
307
+ type MacChromeAutomationProbeRunner = (command: string, args: string[]) => {
308
+ status: number | null;
309
+ stdout: string;
310
+ stderr: string;
311
+ };
312
+ export declare function probeMacChromeAutomationPermission(options?: {
313
+ platform?: NodeJS.Platform;
314
+ runner?: MacChromeAutomationProbeRunner;
315
+ }): 'granted' | 'not_running' | 'denied' | 'not_applicable';
307
316
  export declare function describeWorkerPreflightReason(reason: string): string;
308
317
  export declare function buildWorkerSetupActions(input: {
309
318
  degradedReasons: string[];
@@ -393,6 +402,17 @@ export declare function enforceInstrumentBrowserHygiene(assignment: WorkerTaskAs
393
402
  remainingTaskTabs: number;
394
403
  blankWindows: number;
395
404
  }>;
405
+ export declare function finalizeInstrumentBrowserHygiene(assignment: WorkerTaskAssignmentV2, options?: {
406
+ platform?: NodeJS.Platform;
407
+ runner?: InstrumentBrowserHygieneRunner;
408
+ }): Promise<{
409
+ ok: true;
410
+ remainingTaskTabs: number;
411
+ blankWindows: number;
412
+ } | {
413
+ ok: false;
414
+ error: string;
415
+ }>;
396
416
  export declare function assignmentRequiresRegisteredBundle(assignment: WorkerTaskAssignmentV2): boolean;
397
417
  export declare function startWorker(options?: WorkerStartOptions): Promise<void>;
398
418
  export declare function reportTask(options: TaskReportOptions): Promise<void>;
@@ -56,6 +56,7 @@ exports.parseCodexModelCatalog = parseCodexModelCatalog;
56
56
  exports.parseClaudeModelCatalog = parseClaudeModelCatalog;
57
57
  exports.claudeModelProbeReportsSelection = claudeModelProbeReportsSelection;
58
58
  exports.probeWorkerProviderIndependently = probeWorkerProviderIndependently;
59
+ exports.probeMacChromeAutomationPermission = probeMacChromeAutomationPermission;
59
60
  exports.describeWorkerPreflightReason = describeWorkerPreflightReason;
60
61
  exports.buildWorkerSetupActions = buildWorkerSetupActions;
61
62
  exports.resolveWorkerStateDir = resolveWorkerStateDir;
@@ -78,6 +79,7 @@ exports.showWorkerStatus = showWorkerStatus;
78
79
  exports.setupWorker = setupWorker;
79
80
  exports.instrumentTaskChromeTitleMatchers = instrumentTaskChromeTitleMatchers;
80
81
  exports.enforceInstrumentBrowserHygiene = enforceInstrumentBrowserHygiene;
82
+ exports.finalizeInstrumentBrowserHygiene = finalizeInstrumentBrowserHygiene;
81
83
  exports.assignmentRequiresRegisteredBundle = assignmentRequiresRegisteredBundle;
82
84
  exports.startWorker = startWorker;
83
85
  exports.reportTask = reportTask;
@@ -2850,6 +2852,37 @@ function resolveInstalledChromeExecutable() {
2850
2852
  }
2851
2853
  return workerCommandExists('google-chrome') ? 'google-chrome' : null;
2852
2854
  }
2855
+ const MAC_CHROME_AUTOMATION_PREFLIGHT_APPLESCRIPT = `
2856
+ if application "Google Chrome" is not running then
2857
+ return "not_running"
2858
+ end if
2859
+ tell application "Google Chrome"
2860
+ count of windows
2861
+ end tell
2862
+ return "granted"
2863
+ `;
2864
+ function probeMacChromeAutomationPermission(options = {}) {
2865
+ if ((options.platform ?? node_process_1.default.platform) !== 'darwin') {
2866
+ return 'not_applicable';
2867
+ }
2868
+ const runner = options.runner ?? ((command, args) => {
2869
+ const result = (0, node_child_process_1.spawnSync)(command, args, { encoding: 'utf8', timeout: 10000 });
2870
+ return {
2871
+ status: result.status,
2872
+ stdout: result.stdout ?? '',
2873
+ stderr: result.stderr ?? '',
2874
+ };
2875
+ });
2876
+ const result = runner('osascript', ['-e', MAC_CHROME_AUTOMATION_PREFLIGHT_APPLESCRIPT]);
2877
+ const output = result.stdout.trim();
2878
+ if (result.status === 0 && output === 'granted') {
2879
+ return 'granted';
2880
+ }
2881
+ if (result.status === 0 && output === 'not_running') {
2882
+ return 'not_running';
2883
+ }
2884
+ return 'denied';
2885
+ }
2853
2886
  function collectWorkerInfrastructureFailures() {
2854
2887
  const failures = [];
2855
2888
  if (!resolveInstalledChromeExecutable()) {
@@ -2878,6 +2911,9 @@ function collectWorkerInfrastructureFailures() {
2878
2911
  if (guiSession.exitCode !== 0) {
2879
2912
  failures.push('worker_preflight_gui_session_missing');
2880
2913
  }
2914
+ if (probeMacChromeAutomationPermission() === 'denied') {
2915
+ failures.push('worker_preflight_chrome_automation_permission_missing');
2916
+ }
2881
2917
  const recorderPath = (0, recorderRelease_1.resolveMacWorkerRecorderPath)();
2882
2918
  if (!(0, node_fs_1.existsSync)(recorderPath)) {
2883
2919
  failures.push('worker_preflight_recorder_missing');
@@ -2915,6 +2951,7 @@ function describeWorkerPreflightReason(reason) {
2915
2951
  worker_preflight_ffmpeg_missing: 'ffmpeg is missing from PATH.',
2916
2952
  worker_preflight_ffprobe_missing: 'ffprobe is missing from PATH.',
2917
2953
  worker_preflight_gui_session_missing: 'No active macOS GUI session is available.',
2954
+ worker_preflight_chrome_automation_permission_missing: 'Google Chrome Automation permission is missing. In System Settings > Privacy & Security > Automation, allow the PlayDrop worker process to control Google Chrome, then restart the worker.',
2918
2955
  worker_preflight_recorder_architecture_unsupported: 'The native recorder is currently available only for Apple silicon Macs.',
2919
2956
  worker_preflight_recorder_missing: 'The PlayDrop macOS recorder is missing.',
2920
2957
  worker_preflight_recorder_not_executable: 'The PlayDrop macOS recorder is not executable.',
@@ -3083,6 +3120,7 @@ function buildWorkerSetupActions(input) {
3083
3120
  addManualAction('worker_preflight_ffmpeg_missing', 'Install ffmpeg');
3084
3121
  addManualAction('worker_preflight_ffprobe_missing', 'Install ffprobe');
3085
3122
  addManualAction('worker_preflight_gui_session_missing', 'Sign in to the Mac desktop');
3123
+ addManualAction('worker_preflight_chrome_automation_permission_missing', 'Grant Google Chrome Automation permission');
3086
3124
  addManualAction('worker_preflight_recorder_architecture_unsupported', 'Use an Apple silicon Mac');
3087
3125
  addManualAction('worker_preflight_recorder_missing', 'Restart the worker to download the recorder');
3088
3126
  addManualAction('worker_preflight_recorder_not_executable', 'Restart the worker to repair the recorder');
@@ -3706,13 +3744,30 @@ TARGET_CLI_VERSION="$(read_policy_value targetCliVersion)"
3706
3744
  MINIMUM_CLI_VERSION="$(read_policy_value minimumCliVersion)"
3707
3745
 
3708
3746
  if [ -n "$TARGET_CLI_VERSION" ]; then
3709
- if npm install -g --no-audit --no-fund "@playdrop/playdrop-cli@$TARGET_CLI_VERSION"; then
3710
- CURRENT_CLI_VERSION="$(current_cli_version)" || CURRENT_CLI_VERSION=""
3711
- if [ "$CURRENT_CLI_VERSION" != "$TARGET_CLI_VERSION" ]; then
3712
- record_target_failure "worker_update_cli_version_mismatch"
3747
+ CURRENT_CLI_VERSION="$(current_cli_version)" || CURRENT_CLI_VERSION=""
3748
+ if [ "$CURRENT_CLI_VERSION" != "$TARGET_CLI_VERSION" ]; then
3749
+ GLOBAL_NPM_ROOT="$(npm root -g)" || GLOBAL_NPM_ROOT=""
3750
+ BROKEN_FSEVENTS_PATH="$GLOBAL_NPM_ROOT/@playdrop/playdrop-cli/node_modules/fsevents"
3751
+ if [ -n "$GLOBAL_NPM_ROOT" ] && [ -f "$BROKEN_FSEVENTS_PATH/package.json" ]; then
3752
+ node - "$BROKEN_FSEVENTS_PATH" <<'NODE' || record_target_failure "worker_update_fsevents_cleanup_failed"
3753
+ const fs = require("fs");
3754
+ const path = process.argv[2];
3755
+ const packageJson = JSON.parse(fs.readFileSync(path + "/package.json", "utf8"));
3756
+ if (packageJson.version === "2.3.2") {
3757
+ fs.rmSync(path, { recursive: true, force: true });
3758
+ }
3759
+ NODE
3760
+ fi
3761
+ if [ "$TARGET_UPDATE_FAILED" -eq 0 ]; then
3762
+ if npm install -g --no-audit --no-fund "@playdrop/playdrop-cli@$TARGET_CLI_VERSION"; then
3763
+ CURRENT_CLI_VERSION="$(current_cli_version)" || CURRENT_CLI_VERSION=""
3764
+ if [ "$CURRENT_CLI_VERSION" != "$TARGET_CLI_VERSION" ]; then
3765
+ record_target_failure "worker_update_cli_version_mismatch"
3766
+ fi
3767
+ else
3768
+ record_target_failure "worker_update_cli_install_failed"
3769
+ fi
3713
3770
  fi
3714
- else
3715
- record_target_failure "worker_update_cli_install_failed"
3716
3771
  fi
3717
3772
  fi
3718
3773
 
@@ -4148,6 +4203,15 @@ async function enforceInstrumentBrowserHygiene(assignment, options = {}) {
4148
4203
  instrumentBrowserHygieneTail = result.then(() => undefined, () => undefined);
4149
4204
  return result;
4150
4205
  }
4206
+ async function finalizeInstrumentBrowserHygiene(assignment, options = {}) {
4207
+ try {
4208
+ const result = await enforceInstrumentBrowserHygiene(assignment, options);
4209
+ return { ok: true, ...result };
4210
+ }
4211
+ catch (error) {
4212
+ return { ok: false, error: errorMessage(error) };
4213
+ }
4214
+ }
4151
4215
  function assignmentRequiresRegisteredBundle(assignment) {
4152
4216
  const playdropMetadata = assignment.task.metadata.playdrop;
4153
4217
  return Boolean(playdropMetadata
@@ -5093,15 +5157,13 @@ async function startWorker(options = {}) {
5093
5157
  }
5094
5158
  if (agentStartedAt
5095
5159
  && assignment.agent.browser !== 'NONE') {
5096
- try {
5097
- const hygiene = await enforceInstrumentBrowserHygiene(assignment);
5160
+ const hygiene = await finalizeInstrumentBrowserHygiene(assignment);
5161
+ if (hygiene.ok) {
5098
5162
  console.log(`Agent task ${task.id} browser hygiene passed: ${hygiene.remainingTaskTabs} task tabs, ${hygiene.blankWindows} blank window(s).`);
5099
5163
  }
5100
- catch (hygieneError) {
5101
- const error = hygieneError instanceof Error ? hygieneError : new Error(String(hygieneError));
5102
- console.error(`Agent task ${task.id} browser hygiene failed: ${error.message}`);
5164
+ else {
5165
+ console.error(`Agent task ${task.id} browser hygiene failed; worker continuing: ${hygiene.error}`);
5103
5166
  retainWorkspace = true;
5104
- recordFatalTaskError(error);
5105
5167
  }
5106
5168
  }
5107
5169
  activeTerminators.delete(task.id);
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "0.13.1",
2
+ "version": "0.13.2",
3
3
  "build": 1,
4
- "runtimeSdkVersion": "0.13.1",
4
+ "runtimeSdkVersion": "0.13.2",
5
5
  "runtimeSdkBuild": 1,
6
6
  "clients": {
7
7
  "all": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playdrop/playdrop-cli",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "Official Playdrop CLI for publishing browser games, creator apps, and AI-generated game assets on playdrop.ai",
5
5
  "homepage": "https://www.playdrop.ai",
6
6
  "repository": {