@postplus/cli 0.1.39 → 0.1.40

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
  import { Buffer } from 'node:buffer';
2
- import { MEDIA_ENDPOINT_HINTS, PUBLIC_CONTENT_DISCOVERY_TOOL_HINTS, PUBLIC_CONTENT_SOURCE_HINTS, RESEARCH_COLLECTION_HINTS, VIDEO_ANALYSIS_MODEL_HINTS, } from './hosted-schema-catalog.js';
2
+ import { findMediaEndpoint, manifestTargetKeys, } from './hosted-manifest-index.js';
3
3
  const JSON_OBJECT_SCHEMA = {
4
4
  additionalProperties: true,
5
5
  type: 'object',
@@ -9,6 +9,40 @@ const OPERATION_ID_SCHEMA = {
9
9
  minLength: 1,
10
10
  type: 'string',
11
11
  };
12
+ function toFieldContract(field) {
13
+ const contract = {
14
+ name: field.name,
15
+ kind: field.class,
16
+ flag: field.flag,
17
+ type: field.type,
18
+ required: field.required,
19
+ };
20
+ if (field.repeatable) {
21
+ contract.repeatable = true;
22
+ }
23
+ if (field.enumValues) {
24
+ contract.enumValues = field.enumValues;
25
+ }
26
+ if (field.min !== undefined) {
27
+ contract.min = field.min;
28
+ }
29
+ if (field.max !== undefined) {
30
+ contract.max = field.max;
31
+ }
32
+ if (field.default !== undefined) {
33
+ contract.default = field.default;
34
+ }
35
+ if (field.derivedFrom) {
36
+ contract.derivedFrom = field.derivedFrom;
37
+ }
38
+ return contract;
39
+ }
40
+ function toEndpointContract(endpoint) {
41
+ return {
42
+ endpointKey: endpoint.endpointKey,
43
+ fields: endpoint.fields.map(toFieldContract),
44
+ };
45
+ }
12
46
  export function buildHostedRequestSchemaReport(input) {
13
47
  switch (input.domain) {
14
48
  case 'research':
@@ -17,198 +51,85 @@ export function buildHostedRequestSchemaReport(input) {
17
51
  return buildMediaSchemaReport(input.endpointKey ?? null);
18
52
  case 'publish':
19
53
  return buildPublishSchemaReport();
20
- case 'mobile':
21
- return buildMobileSchemaReport();
22
54
  }
23
55
  }
24
56
  function buildResearchSchemaReport(collectionKey) {
25
- if (collectionKey && !RESEARCH_COLLECTION_HINTS[collectionKey]) {
26
- throw new Error(`Unknown research collection ${collectionKey}. Known collections: ${Object.keys(RESEARCH_COLLECTION_HINTS).join(', ')}`);
57
+ const collectionKeys = manifestTargetKeys('research', 'hosted-collection');
58
+ const sourceKeys = manifestTargetKeys('research', 'public-content-collection');
59
+ if (collectionKey && !collectionKeys.includes(collectionKey)) {
60
+ throw new Error(`Unknown research collection ${collectionKey}. Known collections: ${collectionKeys.join(', ')}`);
27
61
  }
28
- const collectionInput = collectionKey
29
- ? RESEARCH_COLLECTION_HINTS[collectionKey]
30
- : {
31
- maxItems: 20,
32
- query: 'electric toothbrush morning routine',
33
- };
34
62
  return {
35
63
  schemaVersion: 1,
36
64
  domain: 'research',
37
- command: 'postplus research collect --skill <skill-id> --collection-key <key> --input <hosted-envelope.json> --output <result.json>; postplus research capability --request <hosted-capability-request.json> --output <result.json>',
65
+ command: 'postplus research collect <collection-key> --request <input.json> --output <result.json>; postplus research scrape <source-key> --request <input-array.json> --output <result.json>',
38
66
  description: 'Schemas for files passed to hosted research commands.',
39
- collectionKeys: Object.keys(RESEARCH_COLLECTION_HINTS).sort(),
67
+ collectionKeys,
40
68
  selectedCollectionKey: collectionKey ?? undefined,
41
- sourceKeys: Object.keys(PUBLIC_CONTENT_SOURCE_HINTS).sort(),
42
- toolKeys: Object.keys(PUBLIC_CONTENT_DISCOVERY_TOOL_HINTS).sort(),
69
+ sourceKeys,
43
70
  notes: [
44
- 'The collection key stays in the CLI flag, not inside the JSON file.',
45
- 'Put the skill-specific provider input under input.',
46
- 'Use --run-handle for polling instead of this envelope.',
47
- 'Use research capability for public-content sourceKey and discovery tool requests.',
48
- 'The CLI derives operationId before sending capability requests to PostPlus Cloud.',
71
+ 'collect / scrape input is an opaque provider-shaped JSON object the agent authors; the collection/source key stays on the CLI flag, not inside the file.',
72
+ 'Use --run-handle with research collect for polling instead of a new launch.',
73
+ 'Use research scrape <source-key> with a JSON array of records for public-content sources.',
74
+ 'The CLI derives operationId before sending requests to PostPlus Cloud.',
49
75
  ],
50
76
  schemas: [
51
77
  {
52
- id: 'research.collection-envelope',
53
- description: 'Hosted research collection input envelope.',
54
- required: ['schemaVersion', 'input'],
55
- jsonSchema: {
56
- additionalProperties: false,
57
- properties: {
58
- hostedOperationId: OPERATION_ID_SCHEMA,
59
- input: JSON_OBJECT_SCHEMA,
60
- operationId: OPERATION_ID_SCHEMA,
61
- quoteConfirmationToken: {
62
- minLength: 1,
63
- type: 'string',
64
- },
65
- schemaVersion: {
66
- const: 1,
67
- },
68
- },
69
- required: ['schemaVersion', 'input'],
70
- type: 'object',
71
- },
72
- },
73
- {
74
- id: 'public-content-collection.scrape',
75
- description: 'Collect public content from a released sourceKey.',
76
- required: ['capability', 'operation', 'sourceKey', 'input'],
77
- jsonSchema: {
78
- additionalProperties: false,
79
- properties: {
80
- capability: { const: 'public-content-collection' },
81
- input: {
82
- items: JSON_OBJECT_SCHEMA,
83
- minItems: 1,
84
- type: 'array',
85
- },
86
- operation: { const: 'scrape' },
87
- operationId: OPERATION_ID_SCHEMA,
88
- quoteConfirmationToken: {
89
- minLength: 1,
90
- type: 'string',
91
- },
92
- sourceKey: {
93
- enum: Object.keys(PUBLIC_CONTENT_SOURCE_HINTS).sort(),
94
- type: 'string',
95
- },
96
- },
97
- required: ['capability', 'operation', 'sourceKey', 'input'],
98
- type: 'object',
99
- },
100
- },
101
- {
102
- id: 'public-content-collection.status',
103
- description: 'Poll a public-content collection job.',
104
- required: ['capability', 'operation', 'handle'],
105
- jsonSchema: {
106
- additionalProperties: false,
107
- properties: {
108
- capability: { const: 'public-content-collection' },
109
- handle: {
110
- minLength: 1,
111
- type: 'string',
112
- },
113
- operation: { const: 'status' },
114
- operationId: OPERATION_ID_SCHEMA,
115
- },
116
- required: ['capability', 'operation', 'handle'],
117
- type: 'object',
118
- },
78
+ id: 'research.collection-input',
79
+ description: 'Hosted research collection input: the provider-shaped JSON object placed in --request <file>.',
80
+ required: [],
81
+ jsonSchema: JSON_OBJECT_SCHEMA,
119
82
  },
120
83
  {
121
- id: 'public-content-discovery.tool-call',
122
- description: 'Run a hosted public-content discovery tool.',
123
- required: ['capability', 'operation', 'toolKey', 'args'],
84
+ id: 'public-content-collection.scrape-input',
85
+ description: 'Public-content scrape input: a non-empty JSON array of provider-shaped records placed in --request <file>.',
86
+ required: [],
124
87
  jsonSchema: {
125
- additionalProperties: false,
126
- properties: {
127
- args: JSON_OBJECT_SCHEMA,
128
- capability: { const: 'public-content-discovery' },
129
- operation: { const: 'tool-call' },
130
- operationId: OPERATION_ID_SCHEMA,
131
- quoteConfirmationToken: {
132
- minLength: 1,
133
- type: 'string',
134
- },
135
- toolKey: {
136
- enum: Object.keys(PUBLIC_CONTENT_DISCOVERY_TOOL_HINTS).sort(),
137
- type: 'string',
138
- },
139
- },
140
- required: ['capability', 'operation', 'toolKey', 'args'],
141
- type: 'object',
88
+ items: JSON_OBJECT_SCHEMA,
89
+ minItems: 1,
90
+ type: 'array',
142
91
  },
143
92
  },
144
93
  ],
145
- examples: {
146
- 'research.collection-envelope': {
147
- schemaVersion: 1,
148
- input: collectionInput,
149
- },
150
- 'public-content-collection.scrape': {
151
- capability: 'public-content-collection',
152
- operation: 'scrape',
153
- sourceKey: 'youtube-videos',
154
- input: PUBLIC_CONTENT_SOURCE_HINTS['youtube-videos'],
155
- },
156
- 'public-content-collection.status': {
157
- capability: 'public-content-collection',
158
- operation: 'status',
159
- handle: '<output.data.id>',
160
- },
161
- 'public-content-discovery.tool-call': {
162
- capability: 'public-content-discovery',
163
- operation: 'tool-call',
164
- toolKey: 'web-search',
165
- args: PUBLIC_CONTENT_DISCOVERY_TOOL_HINTS['web-search'],
166
- },
167
- },
168
94
  };
169
95
  }
170
96
  function buildMediaSchemaReport(endpointKey) {
171
- if (endpointKey && !MEDIA_ENDPOINT_HINTS[endpointKey]) {
172
- throw new Error(`Unknown media endpoint ${endpointKey}. Known endpoints: ${Object.keys(MEDIA_ENDPOINT_HINTS).join(', ')}`);
97
+ const endpointKeys = manifestTargetKeys('media', 'media-generation');
98
+ const modelKeys = manifestTargetKeys('media', 'video-analysis');
99
+ if (endpointKey && !endpointKeys.includes(endpointKey)) {
100
+ throw new Error(`Unknown media endpoint ${endpointKey}. Known endpoints: ${endpointKeys.join(', ')}`);
173
101
  }
174
- const endpointInput = endpointKey
175
- ? MEDIA_ENDPOINT_HINTS[endpointKey]
176
- : {
177
- prompt: 'A realistic vertical short-form product reveal.',
178
- };
179
- const selectedEndpoint = endpointKey ?? '<endpoint-key>';
102
+ // When an endpoint is selected, narrow to that one field contract; otherwise
103
+ // publish every modelled endpoint's field contract.
104
+ const endpoints = endpointKey
105
+ ? [toEndpointContract(requireMediaEndpoint(endpointKey))]
106
+ : endpointKeys.map((key) => toEndpointContract(requireMediaEndpoint(key)));
180
107
  return {
181
108
  schemaVersion: 1,
182
109
  domain: 'media',
183
- command: 'postplus media capability --request <hosted-capability-request.json> --output <result.json>',
184
- description: 'Schemas for files passed to postplus media capability --request.',
185
- endpointKeys: Object.keys(MEDIA_ENDPOINT_HINTS).sort(),
186
- modelKeys: Object.keys(VIDEO_ANALYSIS_MODEL_HINTS).sort(),
110
+ command: 'postplus media <verb> <endpoint-key> --request <input.json> | --<flags> --output <result.json>',
111
+ description: 'Schemas for files passed to hosted media commands.',
112
+ endpointKeys,
113
+ modelKeys,
187
114
  selectedEndpointKey: endpointKey ?? undefined,
188
115
  notes: [
189
- 'Use media-generation request for async generation, transcription, and voice jobs.',
190
- 'Use media-generation status with the output.data.id handle returned by a pending request.',
191
- 'Use media-file operations for upload/download setup when a workflow needs hosted media storage.',
192
- 'Use video-analysis analyze for Gemini video understanding payloads.',
116
+ 'Each media-generation endpoint declares its fields as intent (you write it), default (manifest-defaulted; write only to deviate), or runner-managed (minted by the CLI; no flag, never in the body).',
117
+ 'Endpoint-specific input belongs under input; capability / endpointKey come from the verb + positional, not the body.',
118
+ 'video-analysis analyze takes an opaque Gemini request object the agent authors verbatim under payload.',
193
119
  'The CLI derives operationId and billing dimensions before sending requests to PostPlus Cloud.',
194
- 'Endpoint-specific input belongs under input; top-level provider or billing fields are not public contract fields.',
120
+ 'Run `postplus media <verb> <endpoint-key> --help` for a single endpoint flag/enum/default breakdown.',
195
121
  ],
196
122
  schemas: [
197
123
  {
198
124
  id: 'media-generation.request',
199
125
  description: 'Submit an async media generation/transcription job.',
200
- required: [
201
- 'capability',
202
- 'operation',
203
- 'endpointKey',
204
- 'input',
205
- ],
126
+ required: ['capability', 'operation', 'endpointKey', 'input'],
206
127
  jsonSchema: {
207
128
  additionalProperties: false,
208
129
  properties: {
209
130
  capability: { const: 'media-generation' },
210
131
  endpointKey: {
211
- minLength: 1,
132
+ enum: endpointKeys,
212
133
  type: 'string',
213
134
  },
214
135
  input: JSON_OBJECT_SCHEMA,
@@ -219,37 +140,37 @@ function buildMediaSchemaReport(endpointKey) {
219
140
  type: 'string',
220
141
  },
221
142
  },
222
- required: [
223
- 'capability',
224
- 'operation',
225
- 'endpointKey',
226
- 'input',
227
- ],
143
+ required: ['capability', 'operation', 'endpointKey', 'input'],
228
144
  type: 'object',
229
145
  },
230
146
  },
231
147
  {
232
- id: 'media-generation.status',
233
- description: 'Poll an async media generation/transcription job.',
234
- required: ['capability', 'operation', 'handle'],
148
+ id: 'video-analysis.analyze',
149
+ description: 'Run hosted Gemini video analysis.',
150
+ required: ['capability', 'operation', 'modelKey', 'payload'],
235
151
  jsonSchema: {
236
152
  additionalProperties: false,
237
153
  properties: {
238
- capability: { const: 'media-generation' },
239
- handle: {
240
- minLength: 1,
154
+ capability: { const: 'video-analysis' },
155
+ modelKey: {
156
+ enum: modelKeys,
241
157
  type: 'string',
242
158
  },
243
- operation: { const: 'status' },
159
+ operation: { const: 'analyze' },
244
160
  operationId: OPERATION_ID_SCHEMA,
161
+ payload: JSON_OBJECT_SCHEMA,
162
+ quoteConfirmationToken: {
163
+ minLength: 1,
164
+ type: 'string',
165
+ },
245
166
  },
246
- required: ['capability', 'operation', 'handle'],
167
+ required: ['capability', 'operation', 'modelKey', 'payload'],
247
168
  type: 'object',
248
169
  },
249
170
  },
250
171
  {
251
172
  id: 'media-file.create-upload-url',
252
- description: 'Create a hosted media upload target.',
173
+ description: 'Create a hosted media upload target via `postplus media-file upload`.',
253
174
  required: ['capability', 'operation', 'file'],
254
175
  jsonSchema: {
255
176
  additionalProperties: false,
@@ -276,72 +197,91 @@ function buildMediaSchemaReport(endpointKey) {
276
197
  type: 'object',
277
198
  },
278
199
  },
279
- {
280
- id: 'video-analysis.analyze',
281
- description: 'Run hosted Gemini video analysis.',
282
- required: ['capability', 'operation', 'modelKey', 'payload'],
283
- jsonSchema: {
284
- additionalProperties: false,
285
- properties: {
286
- capability: { const: 'video-analysis' },
287
- estimatedUsage: JSON_OBJECT_SCHEMA,
288
- modelKey: {
289
- enum: Object.keys(VIDEO_ANALYSIS_MODEL_HINTS).sort(),
290
- type: 'string',
291
- },
292
- operation: { const: 'analyze' },
293
- operationId: OPERATION_ID_SCHEMA,
294
- payload: JSON_OBJECT_SCHEMA,
295
- quoteConfirmationToken: {
296
- minLength: 1,
297
- type: 'string',
298
- },
299
- },
300
- required: ['capability', 'operation', 'modelKey', 'payload'],
301
- type: 'object',
302
- },
303
- },
304
200
  ],
305
- examples: {
306
- 'media-generation.request': {
307
- capability: 'media-generation',
308
- operation: 'request',
309
- endpointKey: selectedEndpoint,
310
- input: endpointInput,
311
- },
312
- 'media-generation.status': {
313
- capability: 'media-generation',
314
- operation: 'status',
315
- handle: '<output.data.id>',
316
- },
317
- 'media-file.create-upload-url': {
318
- capability: 'media-file',
319
- operation: 'create-upload-url',
320
- file: {
321
- mimeType: 'video/mp4',
322
- name: 'input.mp4',
323
- sizeBytes: 1048576,
324
- },
325
- },
326
- 'video-analysis.analyze': {
327
- capability: 'video-analysis',
328
- operation: 'analyze',
329
- modelKey: 'gemini-video-analysis',
330
- payload: VIDEO_ANALYSIS_MODEL_HINTS['gemini-video-analysis'],
331
- },
332
- },
201
+ endpoints,
333
202
  };
334
203
  }
204
+ function requireMediaEndpoint(endpointKey) {
205
+ const endpoint = findMediaEndpoint(endpointKey);
206
+ if (!endpoint) {
207
+ throw new Error(`hosted-request-schemas: ${endpointKey} is not a modelled media-generation endpoint.`);
208
+ }
209
+ return endpoint;
210
+ }
211
+ const MANIFEST_FIELD_DEFAULTS = buildManifestFieldDefaults();
212
+ const MANIFEST_DERIVED_DIMENSIONS = buildManifestDerivedDimensions();
213
+ function buildManifestFieldDefaults() {
214
+ const index = new Map();
215
+ for (const key of manifestTargetKeys('media', 'media-generation')) {
216
+ const endpoint = findMediaEndpoint(key);
217
+ if (!endpoint) {
218
+ continue;
219
+ }
220
+ const byField = new Map();
221
+ for (const field of endpoint.fields) {
222
+ if (field.default !== undefined) {
223
+ byField.set(field.name, field.default);
224
+ }
225
+ }
226
+ index.set(key, byField);
227
+ }
228
+ return index;
229
+ }
230
+ function manifestFieldDefault(endpointKey, fieldName) {
231
+ return MANIFEST_FIELD_DEFAULTS.get(endpointKey)?.get(fieldName);
232
+ }
233
+ function buildManifestDerivedDimensions() {
234
+ const index = new Map();
235
+ for (const key of manifestTargetKeys('media', 'media-generation')) {
236
+ const endpoint = findMediaEndpoint(key);
237
+ if (!endpoint) {
238
+ continue;
239
+ }
240
+ const derived = endpoint.fields.flatMap((field) => field.class === 'runner-managed' && field.derivedFrom
241
+ ? [{ fieldName: field.name, sourceName: field.derivedFrom }]
242
+ : []);
243
+ if (derived.length > 0) {
244
+ index.set(key, derived);
245
+ }
246
+ }
247
+ return index;
248
+ }
335
249
  export function buildMediaGenerationRequestDimensions(endpointKey, input) {
336
250
  const dimensions = {
337
251
  billableUnitCount: 1,
338
252
  operationKey: endpointKey,
339
253
  };
254
+ for (const derived of MANIFEST_DERIVED_DIMENSIONS.get(endpointKey) ?? []) {
255
+ const value = input[derived.sourceName] ??
256
+ manifestFieldDefault(endpointKey, derived.sourceName);
257
+ if (value !== undefined) {
258
+ dimensions[derived.fieldName] = value;
259
+ }
260
+ }
261
+ if (endpointKey.startsWith('image-')) {
262
+ const resolution = typeof input.resolution === 'string' && input.resolution.trim()
263
+ ? input.resolution.trim()
264
+ : manifestFieldDefault(endpointKey, 'resolution');
265
+ const quality = typeof input.quality === 'string' && input.quality.trim()
266
+ ? input.quality.trim()
267
+ : manifestFieldDefault(endpointKey, 'quality');
268
+ if (typeof resolution === 'string') {
269
+ dimensions.imageSize = resolution;
270
+ }
271
+ if (typeof quality === 'string') {
272
+ dimensions.quality = quality;
273
+ }
274
+ }
340
275
  if (endpointKey.startsWith('video-')) {
341
- const duration = readPositiveNumber(input.duration) ?? 5;
276
+ const manifestResolution = manifestFieldDefault(endpointKey, 'resolution');
277
+ const duration = readPositiveNumber(input.duration) ??
278
+ readPositiveNumber(manifestFieldDefault(endpointKey, 'duration')) ??
279
+ 5;
342
280
  const resolution = typeof input.resolution === 'string' && input.resolution.trim()
343
281
  ? input.resolution.trim()
344
- : '720p';
282
+ : typeof manifestResolution === 'string'
283
+ ? manifestResolution
284
+ : '720p';
345
285
  dimensions.audioMode =
346
286
  endpointKey.startsWith('video-kling-v3-0-') && input.sound !== true
347
287
  ? 'off'
@@ -376,14 +316,16 @@ function readPositiveNumber(value) {
376
316
  return value;
377
317
  }
378
318
  function buildPublishSchemaReport() {
319
+ const operations = manifestTargetKeys('publish', 'social-publishing');
379
320
  return {
380
321
  schemaVersion: 1,
381
322
  domain: 'publish',
382
- command: 'postplus publish capability --request <hosted-capability-request.json> --output <result.json>',
383
- description: 'Schema for files passed to postplus publish capability --request.',
323
+ command: 'postplus publish <operation> --request <input.json> --output <result.json>',
324
+ description: 'Schema for files passed to hosted publish commands.',
325
+ operations,
384
326
  notes: [
385
- 'Use social-publishing operations only through PostPlus Cloud.',
386
- 'Put the operation-specific publishing payload under input.',
327
+ 'The operation is BOTH the CLI subcommand and the target; the operation-specific publishing payload goes under input in --request <file>.',
328
+ 'Side-effecting operations may surface a quote-confirmation challenge; replay the fixed confirm/retry commands.',
387
329
  ],
388
330
  schemas: [
389
331
  {
@@ -396,93 +338,7 @@ function buildPublishSchemaReport() {
396
338
  capability: { const: 'social-publishing' },
397
339
  input: JSON_OBJECT_SCHEMA,
398
340
  operation: {
399
- enum: [
400
- 'analytics',
401
- 'channel-settings',
402
- 'create-post',
403
- 'delete-post',
404
- 'delete-post-group',
405
- 'list-channels',
406
- 'list-posts',
407
- 'missing-content',
408
- 'notifications',
409
- 'set-release-id',
410
- 'trigger-channel-tool',
411
- 'update-post-status',
412
- 'upload-file',
413
- 'upload-from-url',
414
- ],
415
- type: 'string',
416
- },
417
- operationId: OPERATION_ID_SCHEMA,
418
- quoteConfirmationToken: {
419
- minLength: 1,
420
- type: 'string',
421
- },
422
- },
423
- required: ['capability', 'operation', 'input'],
424
- type: 'object',
425
- },
426
- },
427
- ],
428
- examples: {
429
- 'social-publishing.list-channels': {
430
- capability: 'social-publishing',
431
- operation: 'list-channels',
432
- input: {},
433
- },
434
- 'social-publishing.create-post': {
435
- capability: 'social-publishing',
436
- operation: 'create-post',
437
- input: {
438
- body: {
439
- posts: [],
440
- },
441
- },
442
- },
443
- },
444
- };
445
- }
446
- function buildMobileSchemaReport() {
447
- return {
448
- schemaVersion: 1,
449
- domain: 'mobile',
450
- command: 'postplus mobile capability --request <hosted-capability-request.json> --output <result.json>',
451
- description: 'Schema for files passed to postplus mobile capability --request.',
452
- notes: [
453
- 'Use mobile-automation operations only through PostPlus Cloud.',
454
- 'Put the operation-specific mobile automation payload under input.',
455
- ],
456
- schemas: [
457
- {
458
- id: 'mobile-automation.request',
459
- description: 'Run a hosted mobile automation operation.',
460
- required: ['capability', 'operation', 'input'],
461
- jsonSchema: {
462
- additionalProperties: false,
463
- properties: {
464
- capability: { const: 'mobile-automation' },
465
- input: JSON_OBJECT_SCHEMA,
466
- operation: {
467
- enum: [
468
- 'cancel-tasks',
469
- 'create-cloud-phones',
470
- 'install-app',
471
- 'list-cloud-phones',
472
- 'list-installed-apps',
473
- 'list-installable-apps',
474
- 'query-phone-status',
475
- 'query-tasks',
476
- 'start-app',
477
- 'start-cloud-phones',
478
- 'stop-cloud-phones',
479
- 'task-detail',
480
- 'tiktok-login',
481
- 'tiktok-publish-image-set',
482
- 'tiktok-publish-video',
483
- 'tiktok-warmup',
484
- 'uninstall-app',
485
- ],
341
+ enum: operations,
486
342
  type: 'string',
487
343
  },
488
344
  operationId: OPERATION_ID_SCHEMA,
@@ -496,12 +352,5 @@ function buildMobileSchemaReport() {
496
352
  },
497
353
  },
498
354
  ],
499
- examples: {
500
- 'mobile-automation.list-cloud-phones': {
501
- capability: 'mobile-automation',
502
- operation: 'list-cloud-phones',
503
- input: {},
504
- },
505
- },
506
355
  };
507
356
  }
package/build/index.js CHANGED
@@ -7,7 +7,7 @@ import { formatAuthValidateReport, validateRemoteAuth, } from './auth-validate.j
7
7
  import { clearAuthState, formatAuthStatusReport, generateAuthStatusReport, } from './auth.js';
8
8
  import { readCurrentCliVersion } from './client-compatibility.js';
9
9
  import { formatDoctorReport, generateDoctorReport } from './doctor.js';
10
- import { runHostedDomainCommand } from './hosted-domain-commands.js';
10
+ import { runHostedDomainCommand, runMediaFileCommand, } from './hosted-domain-commands.js';
11
11
  import { assertConfigFilePermissions } from './local-state.js';
12
12
  import { QUOTE_AUTO_CONFIRM_UNDER_ENV, QuoteAutoConfirmCeilingExceededError, QuoteConfirmationNonInteractiveError, confirmLargeCreditQuote, readLargeCreditQuoteConfirmationChallenge, resolveLargeCreditQuoteConfirmation, } from './quote-confirmation.js';
13
13
  import { POSTPLUS_SKILLS_CURRENT_DIRECTORY_INSTALL_COMMAND, POSTPLUS_SKILLS_INSTALL_COMMAND, formatPostPlusSkillsInstallCommand, loadPublicSkillCatalog, } from './skill-catalog.js';
@@ -44,13 +44,13 @@ Usage:
44
44
  postplus auth logout [--json]
45
45
  postplus doctor [--skill <skill-id>] [--json]
46
46
  postplus research schema [--collection-key <key>] [--json]
47
- postplus research collect --skill <skill-id> --collection-key <key> --input <hosted-envelope.json> [--output <result.json>]
47
+ postplus research collect <collection-key> --request <input.json> [--skill <skill-id>] [--output <result.json>]
48
+ postplus research scrape <source-key> --request <input-array.json> [--skill <skill-id>] [--output <result.json>]
48
49
  postplus media schema [--endpoint <endpoint-key>] [--json]
49
- postplus media capability --request <hosted-capability-request.json> [--output <result.json>]
50
+ postplus media <verb> <endpoint-key> --request <input.json> | --<flags> [--output <result.json>]
51
+ postplus media-file upload --input-file <path> [--mime <type>] [--skill <skill-id>] [--output <result.json>]
50
52
  postplus publish schema [--json]
51
- postplus publish capability --request <hosted-capability-request.json> [--output <result.json>]
52
- postplus mobile schema [--json]
53
- postplus mobile capability --request <hosted-capability-request.json> [--output <result.json>]
53
+ postplus publish <operation> --request <input.json> [--output <result.json>]
54
54
  postplus quote confirm --json --challenge-file <path> [--auto-confirm-under <millicredits>]
55
55
  postplus skills verify [--json]
56
56
  postplus studio init|open|status Open bundled Local Studio
@@ -417,12 +417,12 @@ async function main() {
417
417
  case 'media':
418
418
  process.exitCode = await runHostedDomainCommand('media', rest);
419
419
  return;
420
+ case 'media-file':
421
+ process.exitCode = await runMediaFileCommand(rest);
422
+ return;
420
423
  case 'publish':
421
424
  process.exitCode = await runHostedDomainCommand('publish', rest);
422
425
  return;
423
- case 'mobile':
424
- process.exitCode = await runHostedDomainCommand('mobile', rest);
425
- return;
426
426
  case 'quote':
427
427
  process.exitCode = await runQuoteCommand(rest);
428
428
  return;