@playdrop/playdrop-cli 0.3.4-build.1 → 0.3.5-build.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.
Files changed (141) hide show
  1. package/README.md +60 -23
  2. package/config/client-meta.json +5 -5
  3. package/dist/apps/upload.js +5 -3
  4. package/dist/assets/model-artifacts.js +1 -1
  5. package/dist/catalogue.d.ts +6 -0
  6. package/dist/catalogue.js +38 -1
  7. package/dist/commandContext.d.ts +1 -0
  8. package/dist/commandContext.js +45 -15
  9. package/dist/commands/browse.d.ts +16 -0
  10. package/dist/commands/browse.js +370 -0
  11. package/dist/commands/build.js +4 -9
  12. package/dist/commands/capture.js +24 -24
  13. package/dist/commands/captureRemote.d.ts +11 -0
  14. package/dist/commands/captureRemote.js +90 -0
  15. package/dist/commands/comments.d.ts +14 -0
  16. package/dist/commands/comments.js +189 -0
  17. package/dist/commands/create.js +112 -72
  18. package/dist/commands/creations.d.ts +49 -0
  19. package/dist/commands/creations.js +657 -0
  20. package/dist/commands/credits.d.ts +10 -0
  21. package/dist/commands/credits.js +91 -0
  22. package/dist/commands/detail.d.ts +2 -2
  23. package/dist/commands/detail.js +148 -290
  24. package/dist/commands/dev.js +24 -24
  25. package/dist/commands/devShared.js +2 -2
  26. package/dist/commands/documentation.d.ts +4 -1
  27. package/dist/commands/documentation.js +79 -104
  28. package/dist/commands/feedback.d.ts +12 -9
  29. package/dist/commands/feedback.js +125 -257
  30. package/dist/commands/format.js +6 -13
  31. package/dist/commands/generation.d.ts +11 -0
  32. package/dist/commands/generation.js +204 -42
  33. package/dist/commands/gettingStarted.d.ts +1 -0
  34. package/dist/commands/gettingStarted.js +26 -0
  35. package/dist/commands/init.js +26 -24
  36. package/dist/commands/login.js +9 -8
  37. package/dist/commands/logout.js +2 -1
  38. package/dist/commands/notifications.d.ts +14 -0
  39. package/dist/commands/notifications.js +179 -0
  40. package/dist/commands/search.d.ts +13 -0
  41. package/dist/commands/search.js +198 -0
  42. package/dist/commands/upload.js +20 -17
  43. package/dist/commands/validate.js +15 -1
  44. package/dist/commands/versionsBrowse.d.ts +7 -0
  45. package/dist/commands/versionsBrowse.js +209 -0
  46. package/dist/commands/whoami.js +9 -8
  47. package/dist/errors.d.ts +9 -0
  48. package/dist/errors.js +52 -0
  49. package/dist/externalAssetPackValidation.d.ts +2 -0
  50. package/dist/externalAssetPackValidation.js +115 -0
  51. package/dist/http.js +1 -1
  52. package/dist/index.js +570 -630
  53. package/dist/messages.js +11 -11
  54. package/dist/output.d.ts +5 -0
  55. package/dist/output.js +45 -0
  56. package/dist/playwright.js +1 -1
  57. package/dist/refs.d.ts +18 -0
  58. package/dist/refs.js +105 -0
  59. package/node_modules/@playdrop/ai-client/dist/index.d.ts +42 -15
  60. package/node_modules/@playdrop/ai-client/dist/index.d.ts.map +1 -1
  61. package/node_modules/@playdrop/ai-client/package.json +1 -0
  62. package/node_modules/@playdrop/api-client/dist/client.d.ts +39 -27
  63. package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
  64. package/node_modules/@playdrop/api-client/dist/client.js +280 -1669
  65. package/node_modules/@playdrop/api-client/dist/core/errors.d.ts +9 -0
  66. package/node_modules/@playdrop/api-client/dist/core/errors.d.ts.map +1 -0
  67. package/node_modules/@playdrop/api-client/dist/core/errors.js +46 -0
  68. package/node_modules/@playdrop/api-client/dist/core/request.d.ts +27 -0
  69. package/node_modules/@playdrop/api-client/dist/core/request.d.ts.map +1 -0
  70. package/node_modules/@playdrop/api-client/dist/core/request.js +122 -0
  71. package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts +75 -0
  72. package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts.map +1 -0
  73. package/node_modules/@playdrop/api-client/dist/domains/admin.js +282 -0
  74. package/node_modules/@playdrop/api-client/dist/domains/ai.d.ts +22 -0
  75. package/node_modules/@playdrop/api-client/dist/domains/ai.d.ts.map +1 -0
  76. package/node_modules/@playdrop/api-client/dist/domains/ai.js +15 -0
  77. package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts +60 -0
  78. package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts.map +1 -0
  79. package/node_modules/@playdrop/api-client/dist/domains/apps.js +301 -0
  80. package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts +59 -0
  81. package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts.map +1 -0
  82. package/node_modules/@playdrop/api-client/dist/domains/asset-packs.js +297 -0
  83. package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts +62 -0
  84. package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts.map +1 -0
  85. package/node_modules/@playdrop/api-client/dist/domains/assets.js +297 -0
  86. package/node_modules/@playdrop/api-client/dist/domains/auth.d.ts +28 -0
  87. package/node_modules/@playdrop/api-client/dist/domains/auth.d.ts.map +1 -0
  88. package/node_modules/@playdrop/api-client/dist/domains/auth.js +78 -0
  89. package/node_modules/@playdrop/api-client/dist/domains/comments.d.ts +29 -0
  90. package/node_modules/@playdrop/api-client/dist/domains/comments.d.ts.map +1 -0
  91. package/node_modules/@playdrop/api-client/dist/domains/comments.js +65 -0
  92. package/node_modules/@playdrop/api-client/dist/domains/me.d.ts +24 -0
  93. package/node_modules/@playdrop/api-client/dist/domains/me.d.ts.map +1 -0
  94. package/node_modules/@playdrop/api-client/dist/domains/me.js +35 -0
  95. package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts +37 -0
  96. package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts.map +1 -0
  97. package/node_modules/@playdrop/api-client/dist/domains/payments.js +148 -0
  98. package/node_modules/@playdrop/api-client/dist/domains/search.d.ts +27 -0
  99. package/node_modules/@playdrop/api-client/dist/domains/search.d.ts.map +1 -0
  100. package/node_modules/@playdrop/api-client/dist/domains/search.js +65 -0
  101. package/node_modules/@playdrop/api-client/dist/index.d.ts +33 -56
  102. package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
  103. package/node_modules/@playdrop/api-client/dist/index.js +103 -44
  104. package/node_modules/@playdrop/api-client/package.json +3 -2
  105. package/node_modules/@playdrop/boxel-core/package.json +1 -1
  106. package/node_modules/@playdrop/boxel-three/dist/test/glb-skinned.test.js +1 -1
  107. package/node_modules/@playdrop/boxel-three/dist/test/instantiate.test.js +1 -1
  108. package/node_modules/@playdrop/boxel-three/dist/test/skinned-mesh.test.js +1 -1
  109. package/node_modules/@playdrop/boxel-three/package.json +2 -1
  110. package/node_modules/@playdrop/config/client-meta.json +5 -5
  111. package/node_modules/@playdrop/config/dist/src/constants.d.ts +5 -0
  112. package/node_modules/@playdrop/config/dist/src/constants.d.ts.map +1 -1
  113. package/node_modules/@playdrop/config/dist/src/constants.js +5 -1
  114. package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
  115. package/node_modules/@playdrop/config/package.json +1 -1
  116. package/node_modules/@playdrop/types/dist/api.d.ts +178 -17
  117. package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
  118. package/node_modules/@playdrop/types/dist/api.js +30 -1
  119. package/node_modules/@playdrop/types/dist/app.d.ts +0 -14
  120. package/node_modules/@playdrop/types/dist/app.d.ts.map +1 -1
  121. package/node_modules/@playdrop/types/dist/app.js +0 -10
  122. package/node_modules/@playdrop/types/dist/asset-pack.d.ts +11 -1
  123. package/node_modules/@playdrop/types/dist/asset-pack.d.ts.map +1 -1
  124. package/node_modules/@playdrop/types/dist/asset.d.ts +65 -0
  125. package/node_modules/@playdrop/types/dist/asset.d.ts.map +1 -1
  126. package/node_modules/@playdrop/types/dist/realtime.d.ts +26 -26
  127. package/node_modules/@playdrop/types/dist/realtime.d.ts.map +1 -1
  128. package/node_modules/@playdrop/types/dist/version.d.ts +5 -0
  129. package/node_modules/@playdrop/types/dist/version.d.ts.map +1 -1
  130. package/package.json +2 -3
  131. package/bin/playdrop-cli +0 -2
  132. package/dist/commands/asset-packs.d.ts +0 -27
  133. package/dist/commands/asset-packs.js +0 -508
  134. package/dist/commands/assets.d.ts +0 -35
  135. package/dist/commands/assets.js +0 -668
  136. package/dist/commands/list.d.ts +0 -7
  137. package/dist/commands/list.js +0 -347
  138. package/dist/commands/migrateCatalogueV2.d.ts +0 -1
  139. package/dist/commands/migrateCatalogueV2.js +0 -142
  140. package/dist/commands/versions.d.ts +0 -17
  141. package/dist/commands/versions.js +0 -384
@@ -1,12 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generate = generate;
4
+ exports.browseGenerationJobs = browseGenerationJobs;
5
+ exports.showGenerationJob = showGenerationJob;
4
6
  exports.generations = generations;
5
7
  const types_1 = require("@playdrop/types");
6
8
  const node_fs_1 = require("node:fs");
7
9
  const node_path_1 = require("node:path");
8
10
  const commandContext_1 = require("../commandContext");
11
+ const errors_1 = require("../errors");
9
12
  const messages_1 = require("../messages");
13
+ const output_1 = require("../output");
10
14
  const IMAGE_ASPECT_RATIO_SET = new Set(['1:1', '3:4', '9:16', '4:3', '16:9']);
11
15
  const VIDEO_ASPECT_RATIO_SET = new Set(['16:9', '9:16']);
12
16
  const DEFAULT_SUBCATEGORY_BY_MODALITY = {
@@ -434,8 +438,7 @@ function printGenerateResult(modality, payload) {
434
438
  if (subcategory) {
435
439
  console.log(`Generated Subcategory: ${subcategory}`);
436
440
  }
437
- console.log(`Download File Command: playdrop-cli assets download-file ${ref}`);
438
- console.log(`Download Source Command: playdrop-cli assets download-source ${ref}`);
441
+ console.log(`Next: run "playdrop detail ${ref}" to inspect the generated asset.`);
439
442
  }
440
443
  else {
441
444
  console.log('Generated Asset: none');
@@ -458,71 +461,71 @@ async function generate(typeInput, promptInput, options = {}) {
458
461
  catch (error) {
459
462
  const message = typeof error?.message === 'string' ? error.message : 'invalid_input';
460
463
  if (message === 'missing_type') {
461
- (0, messages_1.printErrorWithHelp)('A generation type is required.', ['Use one of: image, music, sfx, video, model_3d.'], { command: 'generate' });
464
+ (0, messages_1.printErrorWithHelp)('A generation type is required.', ['Use one of: image, music, sfx, video, model_3d.'], { command: 'ai create' });
462
465
  process.exitCode = 1;
463
466
  return;
464
467
  }
465
468
  if (message === 'missing_prompt') {
466
- (0, messages_1.printErrorWithHelp)('A prompt is required.', ['Example: playdrop-cli generate image "A pixel art hero portrait"'], { command: 'generate' });
469
+ (0, messages_1.printErrorWithHelp)('A prompt is required.', ['Example: playdrop ai create image "A pixel art hero portrait"'], { command: 'ai create' });
467
470
  process.exitCode = 1;
468
471
  return;
469
472
  }
470
473
  if (message === 'invalid_type') {
471
- (0, messages_1.printErrorWithHelp)('The generation type is invalid.', ['Use one of: image, music, sfx, video, model_3d.'], { command: 'generate' });
474
+ (0, messages_1.printErrorWithHelp)('The generation type is invalid.', ['Use one of: image, music, sfx, video, model_3d.'], { command: 'ai create' });
472
475
  process.exitCode = 1;
473
476
  return;
474
477
  }
475
478
  if (message === 'invalid_duration') {
476
- (0, messages_1.printErrorWithHelp)('The --duration value is invalid.', ['Use a positive value like 20000, 20s, or 20000ms.'], { command: 'generate' });
479
+ (0, messages_1.printErrorWithHelp)('The --duration value is invalid.', ['Use a positive value like 20000, 20s, or 20000ms.'], { command: 'ai create' });
477
480
  process.exitCode = 1;
478
481
  return;
479
482
  }
480
483
  if (message === 'invalid_video_duration') {
481
- (0, messages_1.printErrorWithHelp)('The --duration value for video is invalid.', ['Use 4s or 8s for video generation.'], { command: 'generate' });
484
+ (0, messages_1.printErrorWithHelp)('The --duration value for video is invalid.', ['Use 4s or 8s for video generation.'], { command: 'ai create' });
482
485
  process.exitCode = 1;
483
486
  return;
484
487
  }
485
488
  if (message === 'invalid_aspect_ratio') {
486
- (0, messages_1.printErrorWithHelp)('The --ratio value is invalid.', ['Image: 1:1, 3:4, 9:16, 4:3, 16:9. Video: 16:9, 9:16.'], { command: 'generate' });
489
+ (0, messages_1.printErrorWithHelp)('The --ratio value is invalid.', ['Image: 1:1, 3:4, 9:16, 4:3, 16:9. Video: 16:9, 9:16.'], { command: 'ai create' });
487
490
  process.exitCode = 1;
488
491
  return;
489
492
  }
490
493
  if (message === 'missing_model3d_images') {
491
- (0, messages_1.printErrorWithHelp)('Model 3D IMAGE source mode requires at least one reference image.', ['Provide --image1 <url> or --image2 <url>, or switch to --source-mode TEXT.'], { command: 'generate' });
494
+ (0, messages_1.printErrorWithHelp)('Model 3D IMAGE source mode requires at least one reference image.', ['Provide --image1 <url> or --image2 <url>, or switch to --source-mode TEXT.'], { command: 'ai create' });
492
495
  process.exitCode = 1;
493
496
  return;
494
497
  }
495
498
  if (message === 'model3d_text_mode_disallows_images') {
496
- (0, messages_1.printErrorWithHelp)('Model 3D TEXT source mode cannot include reference images.', ['Remove --image1/--image2 or switch to --source-mode IMAGE.'], { command: 'generate' });
499
+ (0, messages_1.printErrorWithHelp)('Model 3D TEXT source mode cannot include reference images.', ['Remove --image1/--image2 or switch to --source-mode IMAGE.'], { command: 'ai create' });
497
500
  process.exitCode = 1;
498
501
  return;
499
502
  }
500
503
  if (message === 'invalid_asset_subcategory') {
501
- (0, messages_1.printErrorWithHelp)('The --subcategory value is invalid.', ['Use a lowercase slug such as generic, music, sfx, or avatar.'], { command: 'generate' });
504
+ (0, messages_1.printErrorWithHelp)('The --subcategory value is invalid.', ['Use a lowercase slug such as generic, music, sfx, or avatar.'], { command: 'ai create' });
502
505
  process.exitCode = 1;
503
506
  return;
504
507
  }
505
508
  if (message.startsWith('image_ref_not_found:')) {
506
509
  const [, optionName, path] = message.split(':');
507
- (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference file was not found.`, [path ? `Missing file: ${path}` : 'Provide a valid local file path or HTTPS URL.'], { command: 'generate' });
510
+ (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference file was not found.`, [path ? `Missing file: ${path}` : 'Provide a valid local file path or HTTPS URL.'], { command: 'ai create' });
508
511
  process.exitCode = 1;
509
512
  return;
510
513
  }
511
514
  if (message.startsWith('image_ref_not_file:')) {
512
515
  const [, optionName, path] = message.split(':');
513
- (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference is not a file.`, [path ? `Path must point to a file: ${path}` : 'Provide a valid local file path.'], { command: 'generate' });
516
+ (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference is not a file.`, [path ? `Path must point to a file: ${path}` : 'Provide a valid local file path.'], { command: 'ai create' });
514
517
  process.exitCode = 1;
515
518
  return;
516
519
  }
517
520
  if (message.startsWith('image_ref_invalid_scheme:')) {
518
521
  const [, optionName, scheme] = message.split(':');
519
- (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference URL uses an unsupported scheme.`, [`Use an HTTPS URL or a local file path. Received: ${scheme || 'unknown'}`], { command: 'generate' });
522
+ (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference URL uses an unsupported scheme.`, [`Use an HTTPS URL or a local file path. Received: ${scheme || 'unknown'}`], { command: 'ai create' });
520
523
  process.exitCode = 1;
521
524
  return;
522
525
  }
523
526
  if (message.startsWith('image_ref_signature_mismatch:')) {
524
527
  const [, optionName, path] = message.split(':');
525
- (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference file extension does not match its image signature.`, [path ? `Fix file type mismatch for: ${path}` : 'Ensure extension and file signature match (.png, .jpg, .jpeg, .webp).'], { command: 'generate' });
528
+ (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference file extension does not match its image signature.`, [path ? `Fix file type mismatch for: ${path}` : 'Ensure extension and file signature match (.png, .jpg, .jpeg, .webp).'], { command: 'ai create' });
526
529
  process.exitCode = 1;
527
530
  return;
528
531
  }
@@ -531,44 +534,203 @@ async function generate(typeInput, promptInput, options = {}) {
531
534
  (0, messages_1.printErrorWithHelp)(`The ${optionName || 'image'} reference file type is unsupported.`, [
532
535
  path ? `Unsupported file: ${path}` : 'Provide a supported local file.',
533
536
  'Supported local image types: .png, .jpg, .jpeg, .webp.',
534
- ], { command: 'generate' });
537
+ ], { command: 'ai create' });
535
538
  process.exitCode = 1;
536
539
  return;
537
540
  }
538
- (0, messages_1.printErrorWithHelp)(`Invalid generate input: ${message}.`, ['Run "playdrop-cli generate --help" for valid options.'], {
539
- command: 'generate',
541
+ (0, messages_1.printErrorWithHelp)(`Invalid AI create input: ${message}.`, ['Run "playdrop help ai create" for valid options.'], {
542
+ command: 'ai create',
540
543
  });
541
544
  process.exitCode = 1;
542
545
  return;
543
546
  }
544
- await (0, commandContext_1.withEnvironment)('generate', 'Generating AI assets', async ({ aiClient }) => {
545
- const created = await aiClient.createGenerationJob(parsed.request);
546
- let job = created.job;
547
- const jobId = String(job.id || '').trim();
548
- if (!jobId) {
549
- throw new Error('ai_generation_job_missing_id');
550
- }
551
- console.log(`Job ID: ${jobId}`);
552
- console.log(`Status: ${formatJobStatus(job)}`);
553
- const deadlineMs = Date.now() + parsed.timeoutSeconds * 1000;
554
- while (job.status === 'PENDING' || job.status === 'RUNNING') {
555
- if (Date.now() >= deadlineMs) {
556
- throw new Error(`ai_generation_job_timeout: Timed out waiting for job ${jobId}`);
547
+ await (0, commandContext_1.withEnvironment)('ai create', 'Generating AI assets', async ({ aiClient }) => {
548
+ try {
549
+ const created = await aiClient.createGenerationJob(parsed.request);
550
+ let job = created.job;
551
+ const jobId = String(job.id || '').trim();
552
+ if (!jobId) {
553
+ throw new Error('ai_generation_job_missing_id');
557
554
  }
558
- await sleep(parsed.pollIntervalMs);
559
- const latest = await aiClient.getGenerationJob(jobId);
560
- job = latest.job;
555
+ if (!options.json) {
556
+ console.log(`Job ID: ${jobId}`);
557
+ console.log(`Status: ${formatJobStatus(job)}`);
558
+ }
559
+ const deadlineMs = Date.now() + parsed.timeoutSeconds * 1000;
560
+ while (job.status === 'PENDING' || job.status === 'RUNNING') {
561
+ if (Date.now() >= deadlineMs) {
562
+ throw new Error(`ai_generation_job_timeout: Timed out waiting for job ${jobId}`);
563
+ }
564
+ await sleep(parsed.pollIntervalMs);
565
+ const latest = await aiClient.getGenerationJob(jobId);
566
+ job = latest.job;
567
+ if (!options.json) {
568
+ console.log(`Status: ${formatJobStatus(job)}`);
569
+ }
570
+ }
571
+ if (job.status !== 'SUCCESS') {
572
+ const errorCode = typeof job.errorCode === 'string' && job.errorCode.length > 0 ? job.errorCode : 'ai_generation_failed';
573
+ const errorMessage = typeof job.errorMessage === 'string' && job.errorMessage.length > 0
574
+ ? job.errorMessage
575
+ : 'Generation failed.';
576
+ throw new Error(`${errorCode}: ${errorMessage}`);
577
+ }
578
+ const payload = (job.resultData && typeof job.resultData === 'object') ? job.resultData : {};
579
+ if (options.json) {
580
+ (0, output_1.printJson)({ job, result: payload });
581
+ return;
582
+ }
583
+ printGenerateResult(parsed.modality, payload);
584
+ }
585
+ catch (error) {
586
+ if (!handleAiFailure(error, 'ai create', 'AI create')) {
587
+ throw error;
588
+ }
589
+ }
590
+ });
591
+ }
592
+ function parseJobModality(raw) {
593
+ if (!raw || raw.trim().length === 0 || raw.trim().toLowerCase() === 'all') {
594
+ return undefined;
595
+ }
596
+ return normalizeModality(raw);
597
+ }
598
+ function handleAiFailure(error, command, context) {
599
+ const handled = (0, errors_1.handleCommandFailure)(error, command, context, {
600
+ networkMessage: 'Could not reach the Playdrop AI API.',
601
+ apiMessage: (apiError) => {
602
+ if (apiError.status === 401 || apiError.status === 403) {
603
+ return {
604
+ problem: `${context} requires you to be logged in.`,
605
+ suggestions: ['Run "playdrop auth login" and retry.'],
606
+ };
607
+ }
608
+ return {
609
+ problem: `${context} failed with status ${apiError.status}.`,
610
+ suggestions: ['Retry in a moment.'],
611
+ };
612
+ },
613
+ });
614
+ if (handled) {
615
+ return true;
616
+ }
617
+ const status = typeof error?.status === 'number' ? Number(error.status) : null;
618
+ if (status !== null) {
619
+ if (status === 401 || status === 403) {
620
+ (0, messages_1.printErrorWithHelp)(`${context} requires you to be logged in.`, ['Run "playdrop auth login" and retry.'], { command });
621
+ }
622
+ else {
623
+ (0, messages_1.printErrorWithHelp)(`${context} failed with status ${status}.`, ['Retry in a moment.'], { command });
624
+ }
625
+ process.exitCode = 1;
626
+ return true;
627
+ }
628
+ const message = error instanceof Error ? error.message : String(error);
629
+ if (message === 'ai_generation_job_missing_id') {
630
+ (0, messages_1.printErrorWithHelp)('AI create failed because the server did not return a job id.', ['Retry the command. If the problem persists, contact Playdrop support.'], { command });
631
+ process.exitCode = 1;
632
+ return true;
633
+ }
634
+ if (message.startsWith('ai_generation_job_timeout:')) {
635
+ const detail = message.split(':').slice(1).join(':').trim();
636
+ (0, messages_1.printErrorWithHelp)(detail || 'AI create timed out while waiting for the job to finish.', ['Retry the command with a higher --timeout value if the job normally takes longer.'], { command });
637
+ process.exitCode = 1;
638
+ return true;
639
+ }
640
+ if (message.includes(':')) {
641
+ const [errorCode, ...rest] = message.split(':');
642
+ const detail = rest.join(':').trim();
643
+ if (errorCode && detail) {
644
+ (0, messages_1.printErrorWithHelp)(`AI create failed: ${detail}`, [`Error code: ${errorCode.trim()}`], { command });
645
+ process.exitCode = 1;
646
+ return true;
647
+ }
648
+ }
649
+ return false;
650
+ }
651
+ async function browseGenerationJobs(options = {}) {
652
+ const modality = parseJobModality(options.type);
653
+ if (options.type !== undefined && modality === null) {
654
+ (0, messages_1.printErrorWithHelp)('The --type value is invalid.', ['Use one of: image, music, sfx, video, model_3d, all.'], { command: 'ai jobs browse' });
655
+ process.exitCode = 1;
656
+ return;
657
+ }
658
+ let limit;
659
+ let offset;
660
+ try {
661
+ limit = parseOptionalPositiveInt(options.limit, 'limit');
662
+ offset = parseOptionalNonNegativeInt(options.offset, 'offset');
663
+ }
664
+ catch (error) {
665
+ const message = typeof error?.message === 'string' ? error.message : 'invalid_pagination';
666
+ (0, messages_1.printErrorWithHelp)(`Invalid ai jobs input: ${message}.`, ['Use positive integers for --limit and --offset.'], {
667
+ command: 'ai jobs browse',
668
+ });
669
+ process.exitCode = 1;
670
+ return;
671
+ }
672
+ await (0, commandContext_1.withEnvironment)('ai jobs browse', 'Browsing AI jobs', async ({ aiClient }) => {
673
+ try {
674
+ const response = await aiClient.listGenerationJobs({
675
+ modality: modality ?? undefined,
676
+ limit,
677
+ offset,
678
+ });
679
+ if (options.json) {
680
+ (0, output_1.printJson)({ items: response.jobs, pagination: response.pagination });
681
+ return;
682
+ }
683
+ if (!Array.isArray(response.jobs) || response.jobs.length === 0) {
684
+ console.log('No AI jobs found.');
685
+ console.log('Next: run "playdrop ai create <type> <prompt>" to start a new job.');
686
+ return;
687
+ }
688
+ console.log('AI jobs:\n');
689
+ for (const job of response.jobs) {
690
+ console.log(`${job.id} | ${job.modality.toLowerCase()} | ${formatJobStatus(job)} | ${job.createdAt}`);
691
+ }
692
+ console.log('\nNext: run "playdrop ai jobs detail <id>" to inspect one job.');
693
+ }
694
+ catch (error) {
695
+ if (!handleAiFailure(error, 'ai jobs browse', 'AI job lookup')) {
696
+ throw error;
697
+ }
698
+ }
699
+ });
700
+ }
701
+ async function showGenerationJob(id, options = {}) {
702
+ const jobId = typeof id === 'string' ? id.trim() : '';
703
+ if (!jobId) {
704
+ (0, messages_1.printErrorWithHelp)('A job id is required.', ['Example: playdrop ai jobs detail job_123'], { command: 'ai jobs detail' });
705
+ process.exitCode = 1;
706
+ return;
707
+ }
708
+ await (0, commandContext_1.withEnvironment)('ai jobs detail', 'Inspecting an AI job', async ({ aiClient }) => {
709
+ try {
710
+ const response = await aiClient.getGenerationJob(jobId);
711
+ if (options.json) {
712
+ (0, output_1.printJson)({ job: response.job });
713
+ return;
714
+ }
715
+ const job = response.job;
716
+ console.log(`Job: ${job.id}`);
717
+ console.log(`Type: ${job.modality.toLowerCase()}`);
561
718
  console.log(`Status: ${formatJobStatus(job)}`);
719
+ console.log(`Created: ${job.createdAt}`);
720
+ console.log(`Updated: ${job.updatedAt}`);
721
+ if (job.errorMessage) {
722
+ console.log(`Error: ${job.errorMessage}`);
723
+ }
724
+ if (job.linkedGenerationId) {
725
+ console.log(`Linked generation: ${job.linkedGenerationId}`);
726
+ }
727
+ console.log('\nNext: run "playdrop ai jobs browse" to review other jobs.');
562
728
  }
563
- if (job.status !== 'SUCCESS') {
564
- const errorCode = typeof job.errorCode === 'string' && job.errorCode.length > 0 ? job.errorCode : 'ai_generation_failed';
565
- const errorMessage = typeof job.errorMessage === 'string' && job.errorMessage.length > 0
566
- ? job.errorMessage
567
- : 'Generation failed.';
568
- throw new Error(`${errorCode}: ${errorMessage}`);
729
+ catch (error) {
730
+ if (!handleAiFailure(error, 'ai jobs detail', 'AI job detail lookup')) {
731
+ throw error;
732
+ }
569
733
  }
570
- const payload = (job.resultData && typeof job.resultData === 'object') ? job.resultData : {};
571
- printGenerateResult(parsed.modality, payload);
572
734
  });
573
735
  }
574
736
  async function generations(options = {}) {
@@ -0,0 +1 @@
1
+ export declare function printGettingStarted(): void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.printGettingStarted = printGettingStarted;
4
+ function printGettingStarted() {
5
+ console.log('Start here:\n');
6
+ console.log('1. Log in');
7
+ console.log(' playdrop auth login');
8
+ console.log('');
9
+ console.log('2. Initialize a workspace');
10
+ console.log(' playdrop project init .');
11
+ console.log('');
12
+ console.log('3. Create an app');
13
+ console.log(' playdrop project create app my-app --template playdrop/template/html_template');
14
+ console.log('');
15
+ console.log('4. Preview locally');
16
+ console.log(' playdrop project dev my-app');
17
+ console.log('');
18
+ console.log('5. Publish');
19
+ console.log(' playdrop project publish .');
20
+ console.log('');
21
+ console.log('Documentation:');
22
+ console.log(' playdrop documentation browse');
23
+ console.log(' playdrop documentation read getting-started.md');
24
+ console.log('');
25
+ console.log('Next: run "playdrop help" for the full command tree.');
26
+ }
@@ -35,9 +35,9 @@ async function resolveUsername(apiBase, token) {
35
35
  const username = data.user?.username?.trim();
36
36
  if (!username) {
37
37
  (0, messages_1.printErrorWithHelp)('The Playdrop API returned an unexpected response.', [
38
- 'Retry "playdrop-cli init" in a moment.',
38
+ 'Retry "playdrop project init" in a moment.',
39
39
  'If the problem continues, contact the Playdrop team.'
40
- ], { command: 'init' });
40
+ ], { command: 'project init' });
41
41
  process.exitCode = 1;
42
42
  return null;
43
43
  }
@@ -53,14 +53,14 @@ async function resolveUsername(apiBase, token) {
53
53
  }
54
54
  if (unknownError instanceof types_1.ApiError) {
55
55
  (0, messages_1.printErrorWithHelp)(`Request failed with status ${unknownError.status}.`, [
56
- 'Run "playdrop-cli login" to refresh your credentials.',
57
- 'Use "playdrop-cli init" again after logging in.'
58
- ], { command: 'init' });
56
+ 'Run "playdrop auth login" to refresh your credentials.',
57
+ 'Use "playdrop project init" again after logging in.'
58
+ ], { command: 'project init' });
59
59
  process.exitCode = 1;
60
60
  return null;
61
61
  }
62
62
  const message = unknownError instanceof Error ? unknownError.message : String(unknownError);
63
- (0, messages_1.printErrorWithHelp)('Could not reach the Playdrop API to resolve your account information.', [message], { command: 'init' });
63
+ (0, messages_1.printErrorWithHelp)('Could not reach the Playdrop API to resolve your account information.', [message], { command: 'project init' });
64
64
  process.exitCode = 1;
65
65
  return null;
66
66
  }
@@ -87,13 +87,13 @@ function normalizeBootstrapPayload(payload) {
87
87
  }
88
88
  const readmeUri = typeof payload.readmeUri === 'string' ? payload.readmeUri.trim() : '';
89
89
  if (!readmeUri) {
90
- (0, messages_1.printErrorWithHelp)('Bootstrap payload is missing a README URI.', ['Contact the platform team or try again shortly.'], { command: 'init' });
90
+ (0, messages_1.printErrorWithHelp)('Bootstrap payload is missing a README URI.', ['Contact the platform team or try again shortly.'], { command: 'project init' });
91
91
  process.exitCode = 1;
92
92
  return null;
93
93
  }
94
94
  const agentsUri = typeof payload.agentsUri === 'string' ? payload.agentsUri.trim() : '';
95
95
  if (!agentsUri) {
96
- (0, messages_1.printErrorWithHelp)('Bootstrap payload is missing an AGENTS URI.', ['Contact the platform team or try again shortly.'], { command: 'init' });
96
+ (0, messages_1.printErrorWithHelp)('Bootstrap payload is missing an AGENTS URI.', ['Contact the platform team or try again shortly.'], { command: 'project init' });
97
97
  process.exitCode = 1;
98
98
  return null;
99
99
  }
@@ -106,8 +106,8 @@ function normalizeBootstrapPayload(payload) {
106
106
  async function downloadBootstrapAsset(webBase, uri, label) {
107
107
  if (!webBase) {
108
108
  (0, messages_1.printErrorWithHelp)(`Cannot download ${label} because the current environment is missing a web base URL.`, [
109
- 'Set PLAYDROP_WEB_BASE, PLAYDROP_WEB_BASE_DEV, or the appropriate environment override before running "playdrop-cli init".'
110
- ], { command: 'init' });
109
+ 'Set PLAYDROP_WEB_BASE, PLAYDROP_WEB_BASE_DEV, or the appropriate environment override before running "playdrop project init".'
110
+ ], { command: 'project init' });
111
111
  process.exitCode = 1;
112
112
  return null;
113
113
  }
@@ -118,12 +118,12 @@ async function downloadBootstrapAsset(webBase, uri, label) {
118
118
  }
119
119
  catch (error) {
120
120
  const message = error instanceof Error ? error.message : String(error);
121
- (0, messages_1.printErrorWithHelp)(`Failed to download ${label} from ${url}.`, [message], { command: 'init' });
121
+ (0, messages_1.printErrorWithHelp)(`Failed to download ${label} from ${url}.`, [message], { command: 'project init' });
122
122
  process.exitCode = 1;
123
123
  return null;
124
124
  }
125
125
  if (!response.ok) {
126
- (0, messages_1.printErrorWithHelp)(`Failed to download ${label} from ${url}.`, [`HTTP ${response.status} ${response.statusText}`], { command: 'init' });
126
+ (0, messages_1.printErrorWithHelp)(`Failed to download ${label} from ${url}.`, [`HTTP ${response.status} ${response.statusText}`], { command: 'project init' });
127
127
  process.exitCode = 1;
128
128
  return null;
129
129
  }
@@ -133,7 +133,7 @@ async function downloadBootstrapAsset(webBase, uri, label) {
133
133
  async function fetchBootstrap(base) {
134
134
  const client = (0, apiClient_1.createCliApiClient)({ baseUrl: base });
135
135
  try {
136
- const payload = await client.fetchCreatorBootstrap();
136
+ const payload = await client.fetchBootstrap();
137
137
  return payload;
138
138
  }
139
139
  catch (unknownError) {
@@ -161,8 +161,8 @@ async function init(targetPath, options = {}) {
161
161
  }
162
162
  if (stats && !stats.isDirectory()) {
163
163
  (0, messages_1.printErrorWithHelp)(`Cannot initialize a Playdrop project because ${resolved} is not a directory.`, [
164
- 'Choose a directory path (use "." for the current folder) or create the directory before running "playdrop-cli init".'
165
- ], { command: 'init' });
164
+ 'Choose a directory path (use "." for the current folder) or create the directory before running "playdrop project init".'
165
+ ], { command: 'project init' });
166
166
  process.exitCode = 1;
167
167
  return null;
168
168
  }
@@ -171,18 +171,20 @@ async function init(targetPath, options = {}) {
171
171
  const catalogueExisted = (0, node_fs_1.existsSync)(cataloguePath);
172
172
  const cfg = (0, config_1.loadConfig)();
173
173
  if (!cfg.token) {
174
- (0, messages_1.printLoginRequired)('Bootstrapping a Playdrop project', 'init');
174
+ (0, messages_1.printLoginRequired)('Bootstrapping a Playdrop project', 'project init');
175
175
  process.exitCode = 1;
176
176
  return null;
177
177
  }
178
- const preferredEnv = cfg.env ?? 'prod';
179
- let envConfig = (0, environment_1.resolveEnvironmentConfig)(preferredEnv);
180
- if (!envConfig && preferredEnv !== 'prod') {
181
- envConfig = (0, environment_1.resolveEnvironmentConfig)('prod');
178
+ if (!cfg.env) {
179
+ (0, messages_1.printConfigEnvironmentMissing)('project init');
180
+ process.exitCode = 1;
181
+ return null;
182
182
  }
183
+ const preferredEnv = cfg.env;
184
+ const envConfig = (0, environment_1.resolveEnvironmentConfig)(preferredEnv);
183
185
  if (!envConfig) {
184
186
  const choices = (0, environment_1.formatEnvironmentList)();
185
- (0, messages_1.printUnknownEnvironment)(preferredEnv, choices, 'init');
187
+ (0, messages_1.printUnknownEnvironment)(preferredEnv || '', choices, 'project init');
186
188
  process.exitCode = 1;
187
189
  return null;
188
190
  }
@@ -292,9 +294,9 @@ async function init(targetPath, options = {}) {
292
294
  console.log(` - ${action}`);
293
295
  }
294
296
  console.log('\nNext steps:');
295
- console.log(' - Run "playdrop-cli create <app-name>" to scaffold your first app.');
296
- console.log(' - Use "playdrop-cli dev <app-name>" to preview locally.');
297
- console.log(' - Upload with "playdrop-cli upload ." when ready to share.');
297
+ console.log(' - Run "playdrop project create app <app-name>" to scaffold your first app.');
298
+ console.log(' - Use "playdrop project dev <app-name>" to preview locally.');
299
+ console.log(' - Publish with "playdrop project publish ." when ready to share.');
298
300
  }
299
301
  return summary;
300
302
  }
@@ -64,8 +64,8 @@ async function login(env, usernameArg, passwordArg) {
64
64
  }
65
65
  if (!username || !password) {
66
66
  (0, messages_1.printErrorWithHelp)('Username and password are required to log in.', [
67
- 'Provide both credentials when prompted, then rerun "playdrop-cli login".',
68
- ], { command: 'login' });
67
+ 'Provide both credentials when prompted, then rerun "playdrop auth login".',
68
+ ], { command: 'auth login' });
69
69
  process.exitCode = 1;
70
70
  return;
71
71
  }
@@ -80,9 +80,9 @@ async function login(env, usernameArg, passwordArg) {
80
80
  }
81
81
  if (unknownError instanceof types_1.ApiError) {
82
82
  (0, messages_1.printErrorWithHelp)(`Login failed with status ${unknownError.status}.`, [
83
- 'Verify your username and password, then rerun "playdrop-cli login".',
84
- 'Use "playdrop-cli whoami" after logging in to confirm your status.'
85
- ], { command: 'login' });
83
+ 'Verify your username and password, then rerun "playdrop auth login".',
84
+ 'Use "playdrop auth whoami" after logging in to confirm your status.'
85
+ ], { command: 'auth login' });
86
86
  process.exitCode = 1;
87
87
  return null;
88
88
  }
@@ -97,7 +97,7 @@ async function login(env, usernameArg, passwordArg) {
97
97
  if (e instanceof http_1.CLIUnsupportedClientError) {
98
98
  return;
99
99
  }
100
- (0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to log in.', 'login');
100
+ (0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to log in.', 'auth login');
101
101
  process.exitCode = 1;
102
102
  return;
103
103
  }
@@ -108,10 +108,11 @@ async function login(env, usernameArg, passwordArg) {
108
108
  (0, messages_1.printErrorWithHelp)('Login succeeded but no access token was returned.', [
109
109
  'Please try again in a moment.',
110
110
  'If the issue persists, contact the Playdrop team.'
111
- ], { command: 'login' });
111
+ ], { command: 'auth login' });
112
112
  process.exitCode = 1;
113
113
  return;
114
114
  }
115
115
  (0, config_1.saveConfig)({ token, env });
116
- console.log(`Logged in as ${username} (${env})`);
116
+ console.log(`Logged in as ${username} on ${env}.`);
117
+ console.log('Next: run "playdrop auth whoami" to confirm your session.');
117
118
  }
@@ -4,5 +4,6 @@ exports.logout = logout;
4
4
  const config_1 = require("../config");
5
5
  function logout() {
6
6
  (0, config_1.clearConfig)();
7
- console.log('Logged out');
7
+ console.log('Logged out.');
8
+ console.log('Next: run "playdrop auth login" when you need a new session.');
8
9
  }
@@ -0,0 +1,14 @@
1
+ type BrowseNotificationsOptions = {
2
+ status?: string;
3
+ limit?: string | number;
4
+ offset?: string | number;
5
+ json?: boolean;
6
+ };
7
+ export declare function browseNotifications(options?: BrowseNotificationsOptions): Promise<void>;
8
+ export declare function readNotification(rawId: string | undefined, options?: {
9
+ json?: boolean;
10
+ }): Promise<void>;
11
+ export declare function readAllNotifications(options?: {
12
+ json?: boolean;
13
+ }): Promise<void>;
14
+ export {};