@postplus/cli 0.1.39 → 0.1.41
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.
- package/build/doctor.js +78 -6
- package/build/generated/hosted-execution-manifest.generated.js +2529 -0
- package/build/hosted-domain-commands.js +926 -164
- package/build/hosted-manifest-index.js +106 -0
- package/build/hosted-request-schemas.js +171 -322
- package/build/index.js +10 -9
- package/package.json +3 -2
- package/build/hosted-schema-catalog.js +0 -300
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
|
-
import {
|
|
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
|
-
|
|
26
|
-
|
|
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
|
|
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
|
|
67
|
+
collectionKeys,
|
|
40
68
|
selectedCollectionKey: collectionKey ?? undefined,
|
|
41
|
-
sourceKeys
|
|
42
|
-
toolKeys: Object.keys(PUBLIC_CONTENT_DISCOVERY_TOOL_HINTS).sort(),
|
|
69
|
+
sourceKeys,
|
|
43
70
|
notes: [
|
|
44
|
-
'
|
|
45
|
-
'
|
|
46
|
-
'Use
|
|
47
|
-
'
|
|
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-
|
|
53
|
-
description: 'Hosted research collection input
|
|
54
|
-
required: [
|
|
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-
|
|
122
|
-
description: '
|
|
123
|
-
required: [
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
172
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
|
184
|
-
description: 'Schemas for files passed to
|
|
185
|
-
endpointKeys
|
|
186
|
-
modelKeys
|
|
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
|
-
'
|
|
190
|
-
'
|
|
191
|
-
'
|
|
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
|
-
'
|
|
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
|
-
|
|
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: '
|
|
233
|
-
description: '
|
|
234
|
-
required: ['capability', 'operation', '
|
|
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: '
|
|
239
|
-
|
|
240
|
-
|
|
154
|
+
capability: { const: 'video-analysis' },
|
|
155
|
+
modelKey: {
|
|
156
|
+
enum: modelKeys,
|
|
241
157
|
type: 'string',
|
|
242
158
|
},
|
|
243
|
-
operation: { const: '
|
|
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', '
|
|
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
|
-
|
|
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
|
|
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
|
-
: '
|
|
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
|
|
383
|
-
description: 'Schema for files passed to
|
|
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
|
-
'
|
|
386
|
-
'
|
|
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,14 @@ 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
|
|
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
|
|
50
|
+
postplus media <verb> <endpoint-key> --request <input.json> | --<flags> [--output <result.json>]
|
|
51
|
+
postplus media poll --handle <run-id> [--json] [--output <result.json>]
|
|
52
|
+
postplus media-file upload --input-file <path> [--mime <type>] [--skill <skill-id>] [--output <result.json>]
|
|
50
53
|
postplus publish schema [--json]
|
|
51
|
-
postplus publish
|
|
52
|
-
postplus mobile schema [--json]
|
|
53
|
-
postplus mobile capability --request <hosted-capability-request.json> [--output <result.json>]
|
|
54
|
+
postplus publish <operation> --request <input.json> [--output <result.json>]
|
|
54
55
|
postplus quote confirm --json --challenge-file <path> [--auto-confirm-under <millicredits>]
|
|
55
56
|
postplus skills verify [--json]
|
|
56
57
|
postplus studio init|open|status Open bundled Local Studio
|
|
@@ -417,12 +418,12 @@ async function main() {
|
|
|
417
418
|
case 'media':
|
|
418
419
|
process.exitCode = await runHostedDomainCommand('media', rest);
|
|
419
420
|
return;
|
|
421
|
+
case 'media-file':
|
|
422
|
+
process.exitCode = await runMediaFileCommand(rest);
|
|
423
|
+
return;
|
|
420
424
|
case 'publish':
|
|
421
425
|
process.exitCode = await runHostedDomainCommand('publish', rest);
|
|
422
426
|
return;
|
|
423
|
-
case 'mobile':
|
|
424
|
-
process.exitCode = await runHostedDomainCommand('mobile', rest);
|
|
425
|
-
return;
|
|
426
427
|
case 'quote':
|
|
427
428
|
process.exitCode = await runQuoteCommand(rest);
|
|
428
429
|
return;
|