@playdrop/playdrop-cli 0.10.2 → 0.10.4

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,5 +1,5 @@
1
1
  {
2
- "version": "0.10.2",
2
+ "version": "0.10.4",
3
3
  "build": 1,
4
4
  "runtimeSdkVersion": "0.10.0",
5
5
  "clients": {
@@ -3,7 +3,6 @@ type CaptureOptions = {
3
3
  appName?: string;
4
4
  logLevel?: string;
5
5
  screenshotPath?: string;
6
- port?: string | number;
7
6
  surfaceTarget?: string;
8
7
  devAuth?: string;
9
8
  player?: string | number;
@@ -121,7 +121,7 @@ function resolveCaptureDevOptions(options) {
121
121
  async function capture(targetArg, options = {}) {
122
122
  const timeoutSeconds = (0, captureRuntime_1.validateCaptureTimeout)(options.timeoutSeconds);
123
123
  const timeoutMs = Math.round(timeoutSeconds * 1000);
124
- const devRouterPort = (0, dev_2.resolveDevRouterPort)(options.port ?? process.env.PLAYDROP_DEV_ROUTER_PORT);
124
+ const devRouterPort = (0, dev_2.resolveCliDevRouterPort)();
125
125
  let minimumLogLevel;
126
126
  let loginOverride;
127
127
  let devOptions;
@@ -2,8 +2,9 @@ export declare function formatDevRuntimeAssetManifestFailure(error: unknown): {
2
2
  message: string;
3
3
  suggestions: string[];
4
4
  };
5
- export declare function dev(targetArg: string | undefined, port?: number | string, appOption?: string, devOptions?: {
5
+ export declare function dev(targetArg: string | undefined, appOption?: string, devOptions?: {
6
6
  devAuth?: string;
7
7
  player?: string | number;
8
8
  }): Promise<void>;
9
9
  export declare function resolveDevRouterPort(value: number | string | null | undefined): number;
10
+ export declare function resolveCliDevRouterPort(env?: NodeJS.ProcessEnv): number;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.formatDevRuntimeAssetManifestFailure = formatDevRuntimeAssetManifestFailure;
4
4
  exports.dev = dev;
5
5
  exports.resolveDevRouterPort = resolveDevRouterPort;
6
+ exports.resolveCliDevRouterPort = resolveCliDevRouterPort;
6
7
  const node_fs_1 = require("node:fs");
7
8
  const node_path_1 = require("node:path");
8
9
  const types_1 = require("@playdrop/types");
@@ -134,8 +135,8 @@ function formatDevRuntimeAssetManifestFailure(error) {
134
135
  ],
135
136
  };
136
137
  }
137
- async function dev(targetArg, port, appOption, devOptions = {}) {
138
- const devRouterPort = resolveDevRouterPort(port ?? process.env.PLAYDROP_DEV_ROUTER_PORT);
138
+ async function dev(targetArg, appOption, devOptions = {}) {
139
+ const devRouterPort = resolveCliDevRouterPort();
139
140
  let resolvedTarget;
140
141
  try {
141
142
  resolvedTarget = (0, devShared_1.resolveDevTarget)(targetArg, appOption);
@@ -453,3 +454,35 @@ function resolveDevRouterPort(value) {
453
454
  }
454
455
  return parsed;
455
456
  }
457
+ function resolveRequiredWorkerDevRouterPort(env) {
458
+ const raw = env.PLAYDROP_WORKER_TASK_DEV_PORT;
459
+ if (!raw?.trim()) {
460
+ throw new Error('worker_task_dev_port_missing');
461
+ }
462
+ try {
463
+ return resolveDevRouterPort(raw);
464
+ }
465
+ catch {
466
+ throw new Error(`worker_task_dev_port_invalid:${raw}`);
467
+ }
468
+ }
469
+ function resolveCliDevRouterPort(env = process.env) {
470
+ if (env.PLAYDROP_WORKER_CONTEXT !== '1') {
471
+ return devServer_1.DEV_ROUTER_PORT;
472
+ }
473
+ const workerPort = resolveRequiredWorkerDevRouterPort(env);
474
+ const envPortRaw = env.PLAYDROP_DEV_ROUTER_PORT;
475
+ if (envPortRaw?.trim()) {
476
+ let envPort;
477
+ try {
478
+ envPort = resolveDevRouterPort(envPortRaw);
479
+ }
480
+ catch {
481
+ throw new Error(`worker_task_dev_port_env_invalid:${envPortRaw}`);
482
+ }
483
+ if (envPort !== workerPort) {
484
+ throw new Error(`worker_task_dev_port_mismatch:env=${envPort}:worker=${workerPort}`);
485
+ }
486
+ }
487
+ return workerPort;
488
+ }
@@ -57,9 +57,37 @@ function readTaskScopedDevRouterPort(workspacePath) {
57
57
  }
58
58
  return { file: metadataPath, port };
59
59
  }
60
+ function readWorkerTaskDevRouterPort() {
61
+ if (process.env.PLAYDROP_WORKER_CONTEXT !== '1') {
62
+ return null;
63
+ }
64
+ const workerPortRaw = process.env.PLAYDROP_WORKER_TASK_DEV_PORT;
65
+ if (!workerPortRaw?.trim()) {
66
+ throw new Error('project_validate_worker_dev_port_missing');
67
+ }
68
+ const workerPort = normalizePositivePort(workerPortRaw);
69
+ if (!workerPort) {
70
+ throw new Error(`project_validate_worker_dev_port_invalid:${workerPortRaw}`);
71
+ }
72
+ const devRouterPortRaw = process.env.PLAYDROP_DEV_ROUTER_PORT;
73
+ if (devRouterPortRaw?.trim()) {
74
+ const devRouterPort = normalizePositivePort(devRouterPortRaw);
75
+ if (!devRouterPort) {
76
+ throw new Error(`project_validate_env_dev_port_invalid:${devRouterPortRaw}`);
77
+ }
78
+ if (devRouterPort !== workerPort) {
79
+ throw new Error(`project_validate_worker_dev_port_mismatch:env=${devRouterPort}:worker=${workerPort}`);
80
+ }
81
+ }
82
+ return workerPort;
83
+ }
60
84
  function resolveValidationDevRouterPort(workspacePath, taskScoped) {
61
85
  if (!taskScoped) {
62
- return (0, dev_1.resolveDevRouterPort)(process.env.PLAYDROP_DEV_ROUTER_PORT);
86
+ return (0, dev_1.resolveCliDevRouterPort)();
87
+ }
88
+ const workerPort = readWorkerTaskDevRouterPort();
89
+ if (workerPort !== null) {
90
+ return workerPort;
63
91
  }
64
92
  const taskPort = readTaskScopedDevRouterPort(workspacePath);
65
93
  const envPortRaw = process.env.PLAYDROP_DEV_ROUTER_PORT;
@@ -144,6 +144,12 @@ export declare function assertWorkerProjectVersionBumped(input: {
144
144
  }): void;
145
145
  export declare function buildAgentFailureCode(agent: AgentRuntime, result: LoggedProcessResult): string;
146
146
  export declare function describeAgentFailureForEvent(errorCode: string): string;
147
+ export declare function createLocalPlaydropShim(input: {
148
+ workspaceDir: string;
149
+ taskId: number;
150
+ attempt: number;
151
+ devPort: number;
152
+ }): Promise<string>;
147
153
  export declare function startWorker(options?: WorkerStartOptions): Promise<void>;
148
154
  export declare function reportTask(options: TaskReportOptions): Promise<void>;
149
155
  export declare function reportCatalogueTask(options: TaskCatalogueReportOptions): Promise<void>;
@@ -34,6 +34,7 @@ exports.buildCataloguePreviewPayload = buildCataloguePreviewPayload;
34
34
  exports.assertWorkerProjectVersionBumped = assertWorkerProjectVersionBumped;
35
35
  exports.buildAgentFailureCode = buildAgentFailureCode;
36
36
  exports.describeAgentFailureForEvent = describeAgentFailureForEvent;
37
+ exports.createLocalPlaydropShim = createLocalPlaydropShim;
37
38
  exports.startWorker = startWorker;
38
39
  exports.reportTask = reportTask;
39
40
  exports.reportCatalogueTask = reportCatalogueTask;
@@ -1598,12 +1599,30 @@ function normalizeWorkerFailureErrorCode(message) {
1598
1599
  const match = /^([a-z0-9_]+)(?::|\b)/.exec(trimmed);
1599
1600
  return match?.[1] ?? trimmed;
1600
1601
  }
1601
- async function createLocalPlaydropShim(workspaceDir) {
1602
- const binDir = node_path_1.default.join(workspaceDir, 'bin');
1602
+ async function createLocalPlaydropShim(input) {
1603
+ if (!Number.isInteger(input.taskId) || input.taskId <= 0) {
1604
+ throw new Error('invalid_worker_task_id');
1605
+ }
1606
+ if (!Number.isInteger(input.attempt) || input.attempt <= 0) {
1607
+ throw new Error('invalid_worker_task_attempt');
1608
+ }
1609
+ if (!Number.isInteger(input.devPort) || input.devPort <= 0 || input.devPort > 65535) {
1610
+ throw new Error('invalid_worker_task_dev_port');
1611
+ }
1612
+ const binDir = node_path_1.default.join(input.workspaceDir, 'bin');
1603
1613
  await (0, promises_1.mkdir)(binDir, { recursive: true });
1604
1614
  const cliEntrypoint = node_path_1.default.resolve(node_process_1.default.argv[1] ?? node_path_1.default.join(__dirname, '..', 'index.js'));
1605
1615
  const shimPath = node_path_1.default.join(binDir, 'playdrop');
1606
- await (0, promises_1.writeFile)(shimPath, `#!/bin/sh\nexec ${JSON.stringify(node_process_1.default.execPath)} ${JSON.stringify(cliEntrypoint)} "$@"\n`, 'utf8');
1616
+ await (0, promises_1.writeFile)(shimPath, [
1617
+ '#!/bin/sh',
1618
+ 'export PLAYDROP_WORKER_CONTEXT=1',
1619
+ `export PLAYDROP_WORKER_TASK_ID=${JSON.stringify(String(input.taskId))}`,
1620
+ `export PLAYDROP_WORKER_TASK_ATTEMPT=${JSON.stringify(String(input.attempt))}`,
1621
+ `export PLAYDROP_WORKER_TASK_DEV_PORT=${JSON.stringify(String(input.devPort))}`,
1622
+ `export PLAYDROP_DEV_ROUTER_PORT=${JSON.stringify(String(input.devPort))}`,
1623
+ `exec ${JSON.stringify(node_process_1.default.execPath)} ${JSON.stringify(cliEntrypoint)} "$@"`,
1624
+ '',
1625
+ ].join('\n'), 'utf8');
1607
1626
  await (0, promises_1.chmod)(shimPath, 0o755);
1608
1627
  return binDir;
1609
1628
  }
@@ -1854,13 +1873,18 @@ async function startWorker(options = {}) {
1854
1873
  await (0, promises_1.mkdir)(workspaceDir, { recursive: true });
1855
1874
  const eventDir = node_path_1.default.join(workspaceDir, '.playdrop-task-events');
1856
1875
  await (0, promises_1.mkdir)(eventDir, { recursive: true });
1857
- const binDir = await createLocalPlaydropShim(workspaceDir);
1858
1876
  await stageWorkerTaskContext({
1859
1877
  workspaceDir,
1860
1878
  env,
1861
1879
  devPort,
1862
1880
  taskContext,
1863
1881
  });
1882
+ const binDir = await createLocalPlaydropShim({
1883
+ workspaceDir,
1884
+ taskId: taskContext.taskId,
1885
+ attempt: taskContext.attempt,
1886
+ devPort,
1887
+ });
1864
1888
  const handleEventDrainFailure = (error) => {
1865
1889
  const classification = classifyWorkerEventDrainError(error);
1866
1890
  if (classification === 'session_expired') {
package/dist/index.js CHANGED
@@ -911,11 +911,10 @@ project
911
911
  .command('dev [target]')
912
912
  .description('Run an app locally')
913
913
  .option('--app <name>', 'App name when the target is a workspace')
914
- .option('--port <number>', 'Local dev router port')
915
914
  .option('--dev-auth <mode>', 'prompt, anonymous, viewer, or player')
916
915
  .option('--player <slot>', '1, 2, 3, or 4 when --dev-auth player is selected')
917
916
  .action(async (target, opts = {}) => {
918
- await (0, dev_1.dev)(target, opts.port, opts.app, {
917
+ await (0, dev_1.dev)(target, opts.app, {
919
918
  devAuth: opts.devAuth,
920
919
  player: opts.player,
921
920
  });
@@ -937,7 +936,6 @@ const projectCapture = project.command('capture').description('Run a Playwright
937
936
  projectCapture
938
937
  .argument('[target]')
939
938
  .option('--app <name>', 'App name when the target is a workspace')
940
- .option('--port <number>', 'Local dev router port')
941
939
  .option('--timeout <seconds>', 'Capture timeout in seconds')
942
940
  .option('--log-level <level>', 'debug, info, warn, or error')
943
941
  .option('--screenshot <path>', 'Screenshot output path')
@@ -952,7 +950,6 @@ projectCapture
952
950
  await (0, capture_1.capture)(target, {
953
951
  timeoutSeconds,
954
952
  appName: opts.app,
955
- port: opts.port,
956
953
  logLevel: opts.logLevel,
957
954
  screenshotPath: opts.screenshot,
958
955
  surfaceTarget: opts.surface,
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.10.2",
2
+ "version": "0.10.4",
3
3
  "build": 1,
4
4
  "runtimeSdkVersion": "0.10.0",
5
5
  "clients": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playdrop/playdrop-cli",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
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": {