@postplus/cli 0.1.42 → 0.1.44
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/auth-lifecycle.js +6 -11
- package/build/auth-login.js +4 -9
- package/build/auth-session.js +6 -11
- package/build/auth-validate.js +8 -21
- package/build/authed-cloud-request.js +42 -0
- package/build/doctor.js +12 -26
- package/build/hosted-domain-commands.js +57 -49
- package/package.json +2 -1
package/build/auth-lifecycle.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { formatAccountBindingLines } from './account-binding-display.js';
|
|
2
2
|
import { refreshRemoteAuthSession } from './auth-session.js';
|
|
3
3
|
import { clearAuthState, generateAuthStatusReport } from './auth.js';
|
|
4
|
-
import {
|
|
4
|
+
import { sendAuthedCloudRequest } from './authed-cloud-request.js';
|
|
5
|
+
import { formatPostPlusCompatibilityError } from './client-compatibility.js';
|
|
5
6
|
import { requireHostedBaseUrl } from './hosted-release.js';
|
|
6
7
|
import { resolveCliSessionTokenState } from './local-state.js';
|
|
7
8
|
import { readSubscriptionStatusField } from './subscription-status.js';
|
|
@@ -38,17 +39,11 @@ export async function revokeRemoteAuth() {
|
|
|
38
39
|
if (!cliSessionTokenState.present || !cliSessionTokenState.value) {
|
|
39
40
|
throw new Error('Run `postplus auth login` before revoking PostPlus auth.');
|
|
40
41
|
}
|
|
41
|
-
const
|
|
42
|
-
|
|
42
|
+
const response = await sendAuthedCloudRequest({
|
|
43
|
+
auth: { apiBaseUrl, cliSessionToken: cliSessionTokenState.value },
|
|
44
|
+
body: {},
|
|
43
45
|
method: 'POST',
|
|
44
|
-
|
|
45
|
-
accept: 'application/json',
|
|
46
|
-
...compatibilityHeaders,
|
|
47
|
-
authorization: `Bearer ${cliSessionTokenState.value}`,
|
|
48
|
-
'content-type': 'application/json',
|
|
49
|
-
},
|
|
50
|
-
body: JSON.stringify({}),
|
|
51
|
-
signal: AbortSignal.timeout(15000),
|
|
46
|
+
pathName: '/api/postplus-cli/auth/revoke',
|
|
52
47
|
});
|
|
53
48
|
const payload = (await response.json());
|
|
54
49
|
if (!response.ok) {
|
package/build/auth-login.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { sendAuthedCloudRequest } from './authed-cloud-request.js';
|
|
2
3
|
import { buildPostPlusClientCompatibilityHeaders, formatPostPlusCompatibilityError, writeCurrentCliVersionToLocalConfig, } from './client-compatibility.js';
|
|
3
4
|
import { requireHostedBaseUrl } from './hosted-release.js';
|
|
4
5
|
import { setLocalSession } from './local-state.js';
|
|
@@ -127,15 +128,9 @@ export async function pollCloudAuthLogin(input) {
|
|
|
127
128
|
throw new Error('PostPlus CLI sign-in poll returned incomplete data.');
|
|
128
129
|
}
|
|
129
130
|
export async function validateCliSession(input) {
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
headers: {
|
|
134
|
-
accept: 'application/json',
|
|
135
|
-
...compatibilityHeaders,
|
|
136
|
-
authorization: `Bearer ${input.cliSessionToken}`,
|
|
137
|
-
},
|
|
138
|
-
signal: AbortSignal.timeout(15000),
|
|
131
|
+
const response = await sendAuthedCloudRequest({
|
|
132
|
+
auth: input,
|
|
133
|
+
pathName: '/api/postplus-cli/auth/whoami',
|
|
139
134
|
});
|
|
140
135
|
const payload = (await response.json());
|
|
141
136
|
if (!response.ok) {
|
package/build/auth-session.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sendAuthedCloudRequest } from './authed-cloud-request.js';
|
|
2
|
+
import { formatPostPlusCompatibilityError, writeCurrentCliVersionToLocalConfig, } from './client-compatibility.js';
|
|
2
3
|
import { requireHostedBaseUrl } from './hosted-release.js';
|
|
3
4
|
import { resolveCliSessionTokenState, setLocalSession } from './local-state.js';
|
|
4
5
|
export async function resolveFreshRemoteAuth(options = {}) {
|
|
@@ -39,17 +40,11 @@ export async function refreshRemoteAuthSession(input) {
|
|
|
39
40
|
if (!cliSessionToken) {
|
|
40
41
|
throw new Error('Run `postplus auth login` before refreshing PostPlus auth.');
|
|
41
42
|
}
|
|
42
|
-
const
|
|
43
|
-
|
|
43
|
+
const response = await sendAuthedCloudRequest({
|
|
44
|
+
auth: { apiBaseUrl, cliSessionToken },
|
|
45
|
+
body: {},
|
|
44
46
|
method: 'POST',
|
|
45
|
-
|
|
46
|
-
accept: 'application/json',
|
|
47
|
-
...compatibilityHeaders,
|
|
48
|
-
authorization: `Bearer ${cliSessionToken}`,
|
|
49
|
-
'content-type': 'application/json',
|
|
50
|
-
},
|
|
51
|
-
body: JSON.stringify({}),
|
|
52
|
-
signal: AbortSignal.timeout(15000),
|
|
47
|
+
pathName: '/api/postplus-cli/auth/refresh',
|
|
53
48
|
});
|
|
54
49
|
const payload = (await response.json());
|
|
55
50
|
if (!response.ok) {
|
package/build/auth-validate.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { formatAccountBindingLines } from './account-binding-display.js';
|
|
2
2
|
import { resolveFreshRemoteAuth } from './auth-session.js';
|
|
3
|
-
import {
|
|
3
|
+
import { sendAuthedCloudRequest } from './authed-cloud-request.js';
|
|
4
|
+
import { formatPostPlusCompatibilityError } from './client-compatibility.js';
|
|
4
5
|
import { readSubscriptionStatusField } from './subscription-status.js';
|
|
5
6
|
export async function validateRemoteAuth() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
auth
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
response = await fetchWhoami(auth);
|
|
13
|
-
}
|
|
7
|
+
const auth = await resolveFreshRemoteAuth();
|
|
8
|
+
const response = await sendAuthedCloudRequest({
|
|
9
|
+
auth,
|
|
10
|
+
pathName: '/api/postplus-cli/auth/whoami',
|
|
11
|
+
retryOn401: () => resolveFreshRemoteAuth({ forceRefresh: true }),
|
|
12
|
+
});
|
|
14
13
|
const payload = (await response.json());
|
|
15
14
|
if (!response.ok) {
|
|
16
15
|
const compatibilityError = formatPostPlusCompatibilityError(payload);
|
|
@@ -61,18 +60,6 @@ function readAccountType(payload) {
|
|
|
61
60
|
}
|
|
62
61
|
return value;
|
|
63
62
|
}
|
|
64
|
-
async function fetchWhoami(input) {
|
|
65
|
-
const compatibilityHeaders = await buildPostPlusClientCompatibilityHeaders();
|
|
66
|
-
return fetch(`${input.apiBaseUrl}/api/postplus-cli/auth/whoami`, {
|
|
67
|
-
method: 'GET',
|
|
68
|
-
headers: {
|
|
69
|
-
accept: 'application/json',
|
|
70
|
-
...compatibilityHeaders,
|
|
71
|
-
authorization: `Bearer ${input.cliSessionToken}`,
|
|
72
|
-
},
|
|
73
|
-
signal: AbortSignal.timeout(15000),
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
63
|
function readRequiredString(payload, fieldName) {
|
|
77
64
|
const value = payload[fieldName];
|
|
78
65
|
if (typeof value !== 'string' || !value.trim()) {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { buildPostPlusClientCompatibilityHeaders } from './client-compatibility.js';
|
|
2
|
+
const DEFAULT_AUTHED_REQUEST_TIMEOUT_MS = 15_000;
|
|
3
|
+
/**
|
|
4
|
+
* Single transport envelope for every authenticated PostPlus Cloud request:
|
|
5
|
+
* canonical header set (`accept` + compatibility headers + `Bearer` token +
|
|
6
|
+
* optional `content-type`), `AbortSignal.timeout`, and an optional once-only
|
|
7
|
+
* 401-refresh-retry. It returns the raw `Response` so each caller keeps its own
|
|
8
|
+
* `!ok` interpretation — this is a narrow transport primitive, not a request
|
|
9
|
+
* framework.
|
|
10
|
+
*/
|
|
11
|
+
export async function sendAuthedCloudRequest(input) {
|
|
12
|
+
let response = await issueAuthedCloudRequest(input.auth, input);
|
|
13
|
+
if (response.status === 401 && input.retryOn401) {
|
|
14
|
+
const refreshedAuth = await input.retryOn401();
|
|
15
|
+
response = await issueAuthedCloudRequest(refreshedAuth, input);
|
|
16
|
+
}
|
|
17
|
+
return response;
|
|
18
|
+
}
|
|
19
|
+
async function issueAuthedCloudRequest(auth, input) {
|
|
20
|
+
const compatibilityHeaders = await buildPostPlusClientCompatibilityHeaders({
|
|
21
|
+
skillName: input.skillName ?? null,
|
|
22
|
+
});
|
|
23
|
+
const hasBody = input.body !== undefined;
|
|
24
|
+
const headers = {
|
|
25
|
+
accept: 'application/json',
|
|
26
|
+
...compatibilityHeaders,
|
|
27
|
+
authorization: `Bearer ${auth.cliSessionToken}`,
|
|
28
|
+
};
|
|
29
|
+
if (hasBody) {
|
|
30
|
+
headers['content-type'] = 'application/json';
|
|
31
|
+
}
|
|
32
|
+
const requestUrl = new URL(input.pathName, normalizeBaseUrl(auth.apiBaseUrl));
|
|
33
|
+
return fetch(requestUrl, {
|
|
34
|
+
method: input.method ?? 'GET',
|
|
35
|
+
headers,
|
|
36
|
+
...(hasBody ? { body: JSON.stringify(input.body) } : {}),
|
|
37
|
+
signal: AbortSignal.timeout(input.timeoutMs ?? DEFAULT_AUTHED_REQUEST_TIMEOUT_MS),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function normalizeBaseUrl(apiBaseUrl) {
|
|
41
|
+
return apiBaseUrl.endsWith('/') ? apiBaseUrl : `${apiBaseUrl}/`;
|
|
42
|
+
}
|
package/build/doctor.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { formatAccountBindingName } from './account-binding-display.js';
|
|
2
2
|
import { resolveFreshRemoteAuth, } from './auth-session.js';
|
|
3
|
-
import {
|
|
3
|
+
import { sendAuthedCloudRequest } from './authed-cloud-request.js';
|
|
4
|
+
import { formatPostPlusCompatibilityError } from './client-compatibility.js';
|
|
4
5
|
import { resolveHostedBaseUrl } from './hosted-release.js';
|
|
5
6
|
import { formatLocalDependencyReport, generateLocalDependencyReport, } from './local-dependencies.js';
|
|
6
7
|
import { loadPublicSkillCatalog, } from './skill-catalog.js';
|
|
@@ -136,13 +137,11 @@ function buildDoctorReport(checks, skillId) {
|
|
|
136
137
|
}
|
|
137
138
|
async function checkRemoteAuth(input) {
|
|
138
139
|
try {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
response = await requestWithAuth(refreshedAuth, '/api/postplus-cli/auth/whoami');
|
|
145
|
-
}
|
|
140
|
+
const response = await sendAuthedCloudRequest({
|
|
141
|
+
auth: input,
|
|
142
|
+
pathName: '/api/postplus-cli/auth/whoami',
|
|
143
|
+
retryOn401: () => resolveFreshRemoteAuth({ forceRefresh: true }),
|
|
144
|
+
});
|
|
146
145
|
const payload = (await response.json());
|
|
147
146
|
if (!response.ok) {
|
|
148
147
|
return createFail('remote_auth', 'Remote auth', readErrorMessage(payload, 'PostPlus Cloud rejected the CLI session.'), 'Run `postplus auth login`.');
|
|
@@ -172,13 +171,11 @@ async function checkRemoteAuth(input) {
|
|
|
172
171
|
}
|
|
173
172
|
async function checkHostedCapabilities(input, skillScope) {
|
|
174
173
|
try {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
response = await requestWithAuth(refreshedAuth, '/api/postplus-cli/hosted/readiness');
|
|
181
|
-
}
|
|
174
|
+
const response = await sendAuthedCloudRequest({
|
|
175
|
+
auth: input,
|
|
176
|
+
pathName: '/api/postplus-cli/hosted/readiness',
|
|
177
|
+
retryOn401: () => resolveFreshRemoteAuth({ forceRefresh: true }),
|
|
178
|
+
});
|
|
182
179
|
const payload = (await response.json());
|
|
183
180
|
if (!response.ok) {
|
|
184
181
|
return createFail('hosted_capabilities', 'Hosted capabilities', readErrorMessage(payload, 'PostPlus Cloud hosted readiness check failed.'));
|
|
@@ -459,17 +456,6 @@ function readErrorMessage(payload, fallback) {
|
|
|
459
456
|
? payload.error
|
|
460
457
|
: fallback;
|
|
461
458
|
}
|
|
462
|
-
async function requestWithAuth(input, path) {
|
|
463
|
-
const compatibilityHeaders = await buildPostPlusClientCompatibilityHeaders();
|
|
464
|
-
return fetch(`${input.apiBaseUrl}${path}`, {
|
|
465
|
-
headers: {
|
|
466
|
-
accept: 'application/json',
|
|
467
|
-
...compatibilityHeaders,
|
|
468
|
-
authorization: `Bearer ${input.cliSessionToken}`,
|
|
469
|
-
},
|
|
470
|
-
signal: AbortSignal.timeout(15000),
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
459
|
export function formatDoctorReport(report) {
|
|
474
460
|
const lines = ['PostPlus CLI doctor', ''];
|
|
475
461
|
for (const check of report.checks) {
|
|
@@ -3,9 +3,10 @@ import { createReadStream } from 'node:fs';
|
|
|
3
3
|
import { mkdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { resolveFreshRemoteAuth } from './auth-session.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { sendAuthedCloudRequest } from './authed-cloud-request.js';
|
|
7
|
+
import { formatPostPlusCompatibilityError } from './client-compatibility.js';
|
|
8
8
|
import { buildVerbTargetIndex, } from './hosted-manifest-index.js';
|
|
9
|
+
import { buildHostedRequestSchemaReport, buildMediaGenerationRequestDimensions, } from './hosted-request-schemas.js';
|
|
9
10
|
import { readLargeCreditQuoteConfirmationChallenge, } from './quote-confirmation.js';
|
|
10
11
|
// Manifest-driven verb grammar indexes (SSOT projected from apps/web +
|
|
11
12
|
// public-skill-metadata via the generated manifest). The verb/flag grammar,
|
|
@@ -66,7 +67,9 @@ export async function runHostedDomainCommand(domain, args) {
|
|
|
66
67
|
if (domain === 'media' && subcommand === 'poll') {
|
|
67
68
|
return runMediaPoll(rest);
|
|
68
69
|
}
|
|
69
|
-
if (domain === 'media' &&
|
|
70
|
+
if (domain === 'media' &&
|
|
71
|
+
subcommand &&
|
|
72
|
+
MEDIA_VERB_ENDPOINTS.has(subcommand)) {
|
|
70
73
|
return runMediaVerb(subcommand, rest);
|
|
71
74
|
}
|
|
72
75
|
// publish: the OPERATION is the subcommand (no separate target positional).
|
|
@@ -217,8 +220,7 @@ async function runMediaVerbRequestJson(args) {
|
|
|
217
220
|
// Runner-managed fields are minted/derived by the CLI; reject them in the body so
|
|
218
221
|
// the agent cannot smuggle in ids, tokens, or billing dimensions.
|
|
219
222
|
for (const field of endpoint.fields) {
|
|
220
|
-
if (field.class === 'runner-managed' &&
|
|
221
|
-
Object.hasOwn(input, field.name)) {
|
|
223
|
+
if (field.class === 'runner-managed' && Object.hasOwn(input, field.name)) {
|
|
222
224
|
throw new Error(`media ${verb} ${endpointKey} input must not include runner-managed field "${field.name}"; the CLI mints or derives it.`);
|
|
223
225
|
}
|
|
224
226
|
}
|
|
@@ -308,14 +310,12 @@ async function runVideoAnalysisVerb(args) {
|
|
|
308
310
|
outputPath,
|
|
309
311
|
});
|
|
310
312
|
}
|
|
311
|
-
// `media-file upload`: the generic local-file -> hosted
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
// holds no provider keys — it asks the Web boundary for a signed upload target,
|
|
318
|
-
// PUTs the bytes, and returns the storageReference the Web boundary issued.
|
|
313
|
+
// `media-file upload`: the generic local-file -> hosted media verb. Released
|
|
314
|
+
// skills ship no scripts, so a skill that must place a local file behind hosted
|
|
315
|
+
// media first drives it through this verb. It is capability-generic: it knows no
|
|
316
|
+
// skill request payload. The runner asks the Web boundary for a signed upload
|
|
317
|
+
// target, PUTs bytes outside the JSON envelope, then asks the hosted provider
|
|
318
|
+
// upload operation for the reusable provider-facing result.
|
|
319
319
|
const MEDIA_FILE_MIME_BY_EXTENSION = {
|
|
320
320
|
'.gif': 'image/gif',
|
|
321
321
|
'.jpeg': 'image/jpeg',
|
|
@@ -366,6 +366,7 @@ async function runMediaFileUpload(args) {
|
|
|
366
366
|
}
|
|
367
367
|
const mimeType = flags.values.get('mime') ?? inferUploadMimeType(absolutePath);
|
|
368
368
|
const outputPath = flags.values.get('output') ?? null;
|
|
369
|
+
const hostedOperationId = flags.values.get('hosted-operation-id') ?? null;
|
|
369
370
|
const body = {
|
|
370
371
|
capability: 'media-file',
|
|
371
372
|
operation: 'create-upload-url',
|
|
@@ -374,7 +375,7 @@ async function runMediaFileUpload(args) {
|
|
|
374
375
|
name: path.basename(absolutePath),
|
|
375
376
|
sizeBytes: fileStat.size,
|
|
376
377
|
},
|
|
377
|
-
operationId:
|
|
378
|
+
operationId: hostedOperationId ??
|
|
378
379
|
`postplus-cli:media-file:create-upload-url:${randomUUID()}`,
|
|
379
380
|
quoteConfirmationToken: flags.values.get('quote-confirmation-token') ?? undefined,
|
|
380
381
|
};
|
|
@@ -387,8 +388,25 @@ async function runMediaFileUpload(args) {
|
|
|
387
388
|
});
|
|
388
389
|
const output = readHostedUploadOutput(payload);
|
|
389
390
|
const signedUpload = readSignedUpload(output);
|
|
391
|
+
const storageReference = readStorageReferenceValue(output);
|
|
390
392
|
await putHostedMediaBytes(signedUpload, absolutePath);
|
|
391
|
-
return
|
|
393
|
+
return await postHostedJson({
|
|
394
|
+
body: {
|
|
395
|
+
capability: 'media-file',
|
|
396
|
+
operation: 'upload',
|
|
397
|
+
file: {
|
|
398
|
+
mimeType,
|
|
399
|
+
name: path.basename(absolutePath),
|
|
400
|
+
storageReference,
|
|
401
|
+
},
|
|
402
|
+
operationId: hostedOperationId
|
|
403
|
+
? `${hostedOperationId}:upload`
|
|
404
|
+
: `postplus-cli:media-file:upload:${randomUUID()}`,
|
|
405
|
+
quoteConfirmationToken: flags.values.get('quote-confirmation-token') ?? undefined,
|
|
406
|
+
},
|
|
407
|
+
pathName: '/api/postplus-cli/hosted/capability',
|
|
408
|
+
skillName: flags.values.get('skill') ?? null,
|
|
409
|
+
});
|
|
392
410
|
},
|
|
393
411
|
errorInputLabel: inputFile,
|
|
394
412
|
json: flags.booleans.has('json'),
|
|
@@ -581,7 +599,7 @@ async function runResearchCollect(args) {
|
|
|
581
599
|
const outputPath = flags.values.get('output') ?? null;
|
|
582
600
|
return runHostedCommand({
|
|
583
601
|
request: () => postHostedJson({
|
|
584
|
-
body: { runHandle },
|
|
602
|
+
body: { runHandle, runHandleType: 'hosted-collection' },
|
|
585
603
|
pathName: '/api/postplus-cli/hosted/collection',
|
|
586
604
|
skillName: null,
|
|
587
605
|
}),
|
|
@@ -669,8 +687,19 @@ async function runResearchScrape(args) {
|
|
|
669
687
|
const verb = 'scrape';
|
|
670
688
|
const targets = RESEARCH_VERB_TARGETS.get(verb);
|
|
671
689
|
if (!first || first.startsWith('--')) {
|
|
672
|
-
const
|
|
673
|
-
|
|
690
|
+
const flags = parseFlags(args, new Set(['json']));
|
|
691
|
+
const runHandle = requireFlag(flags, 'run-handle');
|
|
692
|
+
const outputPath = flags.values.get('output') ?? null;
|
|
693
|
+
return runHostedCommand({
|
|
694
|
+
request: () => postHostedJson({
|
|
695
|
+
body: { runHandle, runHandleType: 'public-content-collection' },
|
|
696
|
+
pathName: '/api/postplus-cli/hosted/collection',
|
|
697
|
+
skillName: null,
|
|
698
|
+
}),
|
|
699
|
+
errorInputLabel: 'research-scrape-run-handle',
|
|
700
|
+
json: flags.booleans.has('json'),
|
|
701
|
+
outputPath,
|
|
702
|
+
});
|
|
674
703
|
}
|
|
675
704
|
const sourceKey = first;
|
|
676
705
|
const resolved = targets?.get(sourceKey);
|
|
@@ -819,24 +848,16 @@ async function runHostedSchema(domain, args) {
|
|
|
819
848
|
return 0;
|
|
820
849
|
}
|
|
821
850
|
async function postHostedJson(input) {
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
851
|
+
const auth = await resolveFreshRemoteAuth();
|
|
852
|
+
const response = await sendAuthedCloudRequest({
|
|
853
|
+
auth,
|
|
825
854
|
body: input.body,
|
|
826
|
-
|
|
855
|
+
method: 'POST',
|
|
827
856
|
pathName: input.pathName,
|
|
857
|
+
retryOn401: () => resolveFreshRemoteAuth({ forceRefresh: true }),
|
|
828
858
|
skillName: input.skillName,
|
|
859
|
+
timeoutMs: 120000,
|
|
829
860
|
});
|
|
830
|
-
if (response.status === 401) {
|
|
831
|
-
auth = await resolveFreshRemoteAuth({ forceRefresh: true });
|
|
832
|
-
response = await postJson({
|
|
833
|
-
apiBaseUrl: auth.apiBaseUrl,
|
|
834
|
-
body: input.body,
|
|
835
|
-
cliSessionToken: auth.cliSessionToken,
|
|
836
|
-
pathName: input.pathName,
|
|
837
|
-
skillName: input.skillName,
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
861
|
const payload = await readJsonResponse(response);
|
|
841
862
|
if (!response.ok) {
|
|
842
863
|
const productError = readHostedProductError(payload);
|
|
@@ -895,22 +916,6 @@ async function writeQuoteConfirmationChallenge(error, input) {
|
|
|
895
916
|
});
|
|
896
917
|
return challengePath;
|
|
897
918
|
}
|
|
898
|
-
async function postJson(input) {
|
|
899
|
-
const headers = await buildPostPlusClientCompatibilityHeaders({
|
|
900
|
-
skillName: input.skillName,
|
|
901
|
-
});
|
|
902
|
-
return fetch(`${input.apiBaseUrl}${input.pathName}`, {
|
|
903
|
-
body: JSON.stringify(input.body),
|
|
904
|
-
headers: {
|
|
905
|
-
accept: 'application/json',
|
|
906
|
-
authorization: `Bearer ${input.cliSessionToken}`,
|
|
907
|
-
...headers,
|
|
908
|
-
'content-type': 'application/json',
|
|
909
|
-
},
|
|
910
|
-
method: 'POST',
|
|
911
|
-
signal: AbortSignal.timeout(120000),
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
919
|
async function readJsonResponse(response) {
|
|
915
920
|
const text = await response.text();
|
|
916
921
|
if (!text.trim()) {
|
|
@@ -1020,6 +1025,7 @@ Usage:
|
|
|
1020
1025
|
postplus research collect <collection-key> --request <input.json> [--skill <skill-id>] [--max-charge-usd <usd>] [--output <result.json>]
|
|
1021
1026
|
postplus research collect --run-handle <runHandle> [--output <result.json>]
|
|
1022
1027
|
postplus research scrape <source-key> --request <input-array.json> [--skill <skill-id>] [--max-charge-usd <usd>] [--output <result.json>]
|
|
1028
|
+
postplus research scrape --run-handle <runHandle> [--output <result.json>]
|
|
1023
1029
|
`);
|
|
1024
1030
|
}
|
|
1025
1031
|
function printDomainVerbHelp(domain) {
|
|
@@ -1138,7 +1144,9 @@ function printOpaqueTargetHelp(domain, verb, targetKey, resolved) {
|
|
|
1138
1144
|
: 'a provider-shaped JSON object of input';
|
|
1139
1145
|
// publish's operation is both the verb and the target, so the header/usage show
|
|
1140
1146
|
// it once; research shows `<verb> <target>`.
|
|
1141
|
-
const header = domain === 'publish'
|
|
1147
|
+
const header = domain === 'publish'
|
|
1148
|
+
? `publish ${targetKey}`
|
|
1149
|
+
: `research ${verb} ${targetKey}`;
|
|
1142
1150
|
const usage = domain === 'publish'
|
|
1143
1151
|
? ` postplus publish ${targetKey} --request <input.json> [--json] [--output <result.json>]`
|
|
1144
1152
|
: ` postplus research ${verb} ${targetKey} --request <input.json> [--skill <skill-id>] [--max-charge-usd <usd>] [--json] [--output <result.json>]`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postplus/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.44",
|
|
4
4
|
"packageManager": "pnpm@10.30.3+sha512.c961d1e0a2d8e354ecaa5166b822516668b7f44cb5bd95122d590dd81922f606f5473b6d23ec4a5be05e7fcd18e8488d47d978bbe981872f1145d06e9a740017",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "PostPlus CLI for PostPlus Cloud auth, status, and diagnostics.",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"build/auth-session.js",
|
|
13
13
|
"build/auth-validate.js",
|
|
14
14
|
"build/auth.js",
|
|
15
|
+
"build/authed-cloud-request.js",
|
|
15
16
|
"build/client-compatibility.js",
|
|
16
17
|
"build/command-runner.js",
|
|
17
18
|
"build/doctor.js",
|