@postplus/cli 0.1.45 → 0.1.47
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/authed-cloud-request.d.ts +39 -0
- package/build/authed-cloud-request.js +3 -0
- package/build/client-compatibility.js +10 -4
- package/build/generated/hosted-execution-manifest.generated.js +298 -1
- package/build/generated/hosted-field-validation-core.generated.js +84 -0
- package/build/hosted-domain-commands.d.ts +14 -0
- package/build/hosted-domain-commands.js +129 -69
- package/build/hosted-field-validation.js +11 -91
- package/build/hosted-lib.d.ts +34 -0
- package/build/hosted-lib.js +45 -0
- package/build/hosted-manifest-index.d.ts +69 -0
- package/build/hosted-request-schemas.js +0 -108
- package/build/index.js +6 -4
- package/build/update-check.js +1 -2
- package/package.json +14 -1
|
@@ -1,93 +1,13 @@
|
|
|
1
|
-
// Schema-driven early field validation (issue #475).
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
// single source the Web validator reads, so "720P" / "4K" pass and "english" /
|
|
12
|
-
// "999p" fail exactly as they do on the boundary. The two canonicalize functions
|
|
13
|
-
// below are stable 3-line algorithms; WHICH field uses WHICH is decided by the
|
|
14
|
-
// schema hint, never re-guessed here.
|
|
15
|
-
// k-tier normalization for image resolution ("4K" -> "4k"). Mirrors the Web
|
|
16
|
-
// canonicalizeImageResolution exactly.
|
|
17
|
-
function canonicalizeImageResolution(value) {
|
|
18
|
-
const trimmed = value.trim();
|
|
19
|
-
const tier = trimmed.match(/^(\d+(?:\.\d+)?)\s*k$/iu);
|
|
20
|
-
return tier ? `${tier[1]}k` : trimmed;
|
|
21
|
-
}
|
|
22
|
-
function canonicalizeLowercaseToken(value) {
|
|
23
|
-
return value.trim().toLowerCase();
|
|
24
|
-
}
|
|
25
|
-
function canonicalizeModelledFieldValue(field, value) {
|
|
26
|
-
switch (field.canonicalize) {
|
|
27
|
-
case 'image-resolution-tier':
|
|
28
|
-
return canonicalizeImageResolution(value);
|
|
29
|
-
case 'lowercase':
|
|
30
|
-
return canonicalizeLowercaseToken(value);
|
|
31
|
-
default:
|
|
32
|
-
return value;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function isIntegerInRange(min, max, value) {
|
|
36
|
-
return Number.isInteger(value) && value >= min && value <= max;
|
|
37
|
-
}
|
|
38
|
-
function formatReceivedValue(raw) {
|
|
39
|
-
return typeof raw === 'string' ? `"${raw}"` : String(raw);
|
|
40
|
-
}
|
|
41
|
-
function assertModelledNumberFieldValue(endpointKey, field, raw) {
|
|
42
|
-
const enumValues = field.enumValues && field.enumValues.length > 0 ? field.enumValues : null;
|
|
43
|
-
const constraint = enumValues
|
|
44
|
-
? `must be one of ${enumValues.join(', ')}`
|
|
45
|
-
: `must be an integer from ${field.min} to ${field.max}`;
|
|
46
|
-
if (typeof raw !== 'number' || !Number.isFinite(raw)) {
|
|
47
|
-
throw new Error(`${endpointKey} ${field.name} ${constraint}; received ${formatReceivedValue(raw)}.`);
|
|
48
|
-
}
|
|
49
|
-
if (enumValues) {
|
|
50
|
-
if (!enumValues.includes(String(raw))) {
|
|
51
|
-
throw new Error(`${endpointKey} ${field.name} ${constraint}; received ${raw}.`);
|
|
52
|
-
}
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
if (field.min === undefined || field.max === undefined) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (!isIntegerInRange(field.min, field.max, raw)) {
|
|
59
|
-
throw new Error(`${endpointKey} ${field.name} ${constraint}; received ${raw}.`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
// Validates every advertised enum / numeric-range field present in the input against
|
|
63
|
-
// the manifest contract. Skips runner-managed fields (no caller input), fields with
|
|
64
|
-
// neither an enum nor a range, and fields the input omits — exactly mirroring the Web
|
|
65
|
-
// boundary so a value the CLI accepts the boundary also accepts, and vice versa.
|
|
1
|
+
// Schema-driven early field validation (issue #475). The canonicalize + enum/range
|
|
2
|
+
// algorithm is the SSOT `hosted-field-validation-core`, authored in apps/web and
|
|
3
|
+
// projected VERBATIM into ./generated by the hosted-execution-manifest codegen — the CLI
|
|
4
|
+
// submodule cannot import apps/web TS, and a hand-copy here would let the casing / range
|
|
5
|
+
// rules drift from the Web boundary. This module only injects the CLI's plain-Error
|
|
6
|
+
// factory and keeps the established (endpointKey, fields, input) signature its callers
|
|
7
|
+
// use. The Web boundary stays the AUTHORITATIVE gate; this is pre-submit feedback so the
|
|
8
|
+
// agent gets an immediate field-level error (e.g. seedance resolution "999p") instead of
|
|
9
|
+
// waiting for the round-trip.
|
|
10
|
+
import { assertModelledFieldValuesInRange as assertModelledFieldValuesInRangeCore } from './generated/hosted-field-validation-core.generated.js';
|
|
66
11
|
export function assertModelledFieldValuesInRange(endpointKey, fields, input) {
|
|
67
|
-
|
|
68
|
-
if (field.class === 'runner-managed') {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const enumValues = field.enumValues && field.enumValues.length > 0 ? field.enumValues : null;
|
|
72
|
-
const hasRange = field.min !== undefined && field.max !== undefined;
|
|
73
|
-
if (!enumValues && !hasRange) {
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
if (!Object.hasOwn(input, field.name)) {
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
if (field.type === 'number') {
|
|
80
|
-
assertModelledNumberFieldValue(endpointKey, field, input[field.name]);
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
const raw = input[field.name];
|
|
84
|
-
if (typeof raw !== 'string' || !raw.trim()) {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
const value = raw.trim();
|
|
88
|
-
if (enumValues &&
|
|
89
|
-
!enumValues.includes(canonicalizeModelledFieldValue(field, value))) {
|
|
90
|
-
throw new Error(`${endpointKey} ${field.name} must be one of ${enumValues.join(', ')}; received "${value}".`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
12
|
+
assertModelledFieldValuesInRangeCore(endpointKey, fields, input, (message) => new Error(message));
|
|
93
13
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AuthedCloudRequestAuth } from './authed-cloud-request.js';
|
|
2
|
+
export type HostedLibDomain = 'media' | 'research' | 'publish' | 'media-file';
|
|
3
|
+
export type RunHostedRequestInput = {
|
|
4
|
+
/** Which hosted verb family `args` belongs to (the first CLI token). */
|
|
5
|
+
domain: HostedLibDomain;
|
|
6
|
+
/**
|
|
7
|
+
* The CLI tokens AFTER the domain, exactly as the bin would receive them, e.g.
|
|
8
|
+
* `['create', 'video-seedance-2-text']` or `['collect', 'tiktok-research']`.
|
|
9
|
+
* Flags surfaces still pass their `--flag value` tokens here; request-json
|
|
10
|
+
* surfaces pass the body via `requestJson` instead of a `--request <file>`.
|
|
11
|
+
*/
|
|
12
|
+
args: string[];
|
|
13
|
+
/**
|
|
14
|
+
* The request-json envelope for request-json surfaces, injected in place of a
|
|
15
|
+
* `--request <file>` read. Omit it for flags surfaces (media create/transcribe
|
|
16
|
+
* flag-driven) and for surfaces that need no body (polling/run-handle).
|
|
17
|
+
*/
|
|
18
|
+
requestJson?: Record<string, unknown> | unknown[];
|
|
19
|
+
/** The account's fresh session auth, supplied by the trusted host runtime. */
|
|
20
|
+
auth: AuthedCloudRequestAuth;
|
|
21
|
+
/**
|
|
22
|
+
* The skills release id stamped into `x-postplus-skills-release-id`. Provided
|
|
23
|
+
* verbatim by the host (it is NOT read from disk on this path).
|
|
24
|
+
*/
|
|
25
|
+
skillsReleaseId?: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Runs a hosted media / research / publish / media-file request in-process and
|
|
29
|
+
* returns the parsed hosted payload. Throws the structured
|
|
30
|
+
* HostedProductRequestError / quote-confirmation error VERBATIM on failure — no
|
|
31
|
+
* stdout, no file writes, no exit code. The wire request is identical to the bin
|
|
32
|
+
* path for the same input (proven by the parity test).
|
|
33
|
+
*/
|
|
34
|
+
export declare function runHostedRequest(input: RunHostedRequestInput): Promise<unknown>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// In-process hosted-execution library entry. This is the trusted-runtime
|
|
2
|
+
// counterpart to the `postplus` bin: a host process (e.g. eve-agent) that already
|
|
3
|
+
// holds the account's fresh session auth can run the SAME hosted verb grammar
|
|
4
|
+
// in-process — resolve verb -> build the typed envelope -> POST -> return the
|
|
5
|
+
// parsed payload — WITHOUT spawning a CLI subprocess, reading disk config, or
|
|
6
|
+
// writing any temp/output file.
|
|
7
|
+
//
|
|
8
|
+
// Why this exists (anti-drift): the bin path and this lib path share ONE
|
|
9
|
+
// resolve+build+post core in hosted-domain-commands.ts. For the same
|
|
10
|
+
// domain+args+input+auth they produce a byte-identical hosted HTTP request (URL +
|
|
11
|
+
// JSON body + headers). The only divergence is the input source and the result
|
|
12
|
+
// sink, both injected via HostedRequestContext: auth + skillsReleaseId come in as
|
|
13
|
+
// parameters (no `resolveFreshRemoteAuth()` disk read, no 401-refresh-retry — the
|
|
14
|
+
// host supplies fresh session auth each turn), the request-json body comes from
|
|
15
|
+
// `requestJson` instead of a `--request <file>`, and the parsed payload is RETURNED
|
|
16
|
+
// (the structured HostedProductRequestError / quote-confirmation error are thrown
|
|
17
|
+
// verbatim) instead of being written to stdout/file with an exit code.
|
|
18
|
+
//
|
|
19
|
+
// Scope: only the hosted spend/write surfaces go through here —
|
|
20
|
+
// media / research / publish / media-file. Read-only diagnostics (status / doctor
|
|
21
|
+
// / skills / whoami / quote / list / --version / --help) are NOT hosted-domain
|
|
22
|
+
// commands and are out of scope for this entry.
|
|
23
|
+
import { runHostedDomainCommand, runMediaFileCommand, } from './hosted-domain-commands.js';
|
|
24
|
+
/**
|
|
25
|
+
* Runs a hosted media / research / publish / media-file request in-process and
|
|
26
|
+
* returns the parsed hosted payload. Throws the structured
|
|
27
|
+
* HostedProductRequestError / quote-confirmation error VERBATIM on failure — no
|
|
28
|
+
* stdout, no file writes, no exit code. The wire request is identical to the bin
|
|
29
|
+
* path for the same input (proven by the parity test).
|
|
30
|
+
*/
|
|
31
|
+
export async function runHostedRequest(input) {
|
|
32
|
+
const context = {
|
|
33
|
+
auth: input.auth,
|
|
34
|
+
...(input.skillsReleaseId !== undefined
|
|
35
|
+
? { skillsReleaseId: input.skillsReleaseId }
|
|
36
|
+
: {}),
|
|
37
|
+
...(input.requestJson !== undefined
|
|
38
|
+
? { requestJson: input.requestJson }
|
|
39
|
+
: {}),
|
|
40
|
+
};
|
|
41
|
+
if (input.domain === 'media-file') {
|
|
42
|
+
return runMediaFileCommand(input.args, context);
|
|
43
|
+
}
|
|
44
|
+
return runHostedDomainCommand(input.domain, input.args, context);
|
|
45
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export type HostedDomain = 'media' | 'publish' | 'research';
|
|
2
|
+
export type ManifestFieldClass = 'intent' | 'default' | 'runner-managed';
|
|
3
|
+
export type ManifestField = {
|
|
4
|
+
name: string;
|
|
5
|
+
class: ManifestFieldClass;
|
|
6
|
+
flag: string | null;
|
|
7
|
+
type: 'string' | 'number' | 'boolean' | 'media-url';
|
|
8
|
+
repeatable?: boolean;
|
|
9
|
+
enumValues?: readonly string[];
|
|
10
|
+
min?: number;
|
|
11
|
+
max?: number;
|
|
12
|
+
canonicalize?: 'lowercase' | 'image-resolution-tier';
|
|
13
|
+
default?: string | number | boolean;
|
|
14
|
+
required: boolean;
|
|
15
|
+
derivedFrom?: string;
|
|
16
|
+
};
|
|
17
|
+
export type ManifestEndpoint = {
|
|
18
|
+
endpointKey: string;
|
|
19
|
+
provider: string;
|
|
20
|
+
providerModelPath: string;
|
|
21
|
+
fields: readonly ManifestField[];
|
|
22
|
+
billingDimensions?: readonly string[];
|
|
23
|
+
};
|
|
24
|
+
export type ManifestModel = {
|
|
25
|
+
modelKey: string;
|
|
26
|
+
providerModelPath: string;
|
|
27
|
+
};
|
|
28
|
+
export type ManifestCollection = {
|
|
29
|
+
collectionKey: string;
|
|
30
|
+
actorId: string;
|
|
31
|
+
};
|
|
32
|
+
export type ManifestSource = {
|
|
33
|
+
sourceKey: string;
|
|
34
|
+
datasetId: string;
|
|
35
|
+
};
|
|
36
|
+
export type ManifestOperation = {
|
|
37
|
+
operation: string;
|
|
38
|
+
};
|
|
39
|
+
export type ManifestEntry = {
|
|
40
|
+
skill: string;
|
|
41
|
+
mode?: 'cli-runner';
|
|
42
|
+
surface: 'flags' | 'request-json';
|
|
43
|
+
verb: string;
|
|
44
|
+
domain: HostedDomain;
|
|
45
|
+
capability: string;
|
|
46
|
+
endpointKeys?: readonly string[];
|
|
47
|
+
modelKeys?: readonly string[];
|
|
48
|
+
collectionKeys?: readonly string[];
|
|
49
|
+
sourceKeys?: readonly string[];
|
|
50
|
+
endpoints?: readonly ManifestEndpoint[];
|
|
51
|
+
models?: readonly ManifestModel[];
|
|
52
|
+
collections?: readonly ManifestCollection[];
|
|
53
|
+
sources?: readonly ManifestSource[];
|
|
54
|
+
operations?: readonly ManifestOperation[];
|
|
55
|
+
};
|
|
56
|
+
export type ResolvedVerbTarget = {
|
|
57
|
+
skill: string;
|
|
58
|
+
capability: string;
|
|
59
|
+
surface: 'flags' | 'request-json';
|
|
60
|
+
endpoint?: ManifestEndpoint;
|
|
61
|
+
model?: ManifestModel;
|
|
62
|
+
collection?: ManifestCollection;
|
|
63
|
+
source?: ManifestSource;
|
|
64
|
+
operation?: string;
|
|
65
|
+
};
|
|
66
|
+
export declare function allManifestEntries(): ManifestEntry[];
|
|
67
|
+
export declare function buildVerbTargetIndex(domain: HostedDomain): Map<string, Map<string, ResolvedVerbTarget>>;
|
|
68
|
+
export declare function manifestTargetKeys(domain: HostedDomain, capability?: string): string[];
|
|
69
|
+
export declare function findMediaEndpoint(endpointKey: string): ManifestEndpoint | null;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Buffer } from 'node:buffer';
|
|
2
1
|
import { findMediaEndpoint, manifestTargetKeys, } from './hosted-manifest-index.js';
|
|
3
2
|
const JSON_OBJECT_SCHEMA = {
|
|
4
3
|
additionalProperties: true,
|
|
@@ -211,113 +210,6 @@ function requireMediaEndpoint(endpointKey) {
|
|
|
211
210
|
}
|
|
212
211
|
return endpoint;
|
|
213
212
|
}
|
|
214
|
-
const MANIFEST_FIELD_DEFAULTS = buildManifestFieldDefaults();
|
|
215
|
-
const MANIFEST_DERIVED_DIMENSIONS = buildManifestDerivedDimensions();
|
|
216
|
-
function buildManifestFieldDefaults() {
|
|
217
|
-
const index = new Map();
|
|
218
|
-
for (const key of manifestTargetKeys('media', 'media-generation')) {
|
|
219
|
-
const endpoint = findMediaEndpoint(key);
|
|
220
|
-
if (!endpoint) {
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
const byField = new Map();
|
|
224
|
-
for (const field of endpoint.fields) {
|
|
225
|
-
if (field.default !== undefined) {
|
|
226
|
-
byField.set(field.name, field.default);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
index.set(key, byField);
|
|
230
|
-
}
|
|
231
|
-
return index;
|
|
232
|
-
}
|
|
233
|
-
function manifestFieldDefault(endpointKey, fieldName) {
|
|
234
|
-
return MANIFEST_FIELD_DEFAULTS.get(endpointKey)?.get(fieldName);
|
|
235
|
-
}
|
|
236
|
-
function buildManifestDerivedDimensions() {
|
|
237
|
-
const index = new Map();
|
|
238
|
-
for (const key of manifestTargetKeys('media', 'media-generation')) {
|
|
239
|
-
const endpoint = findMediaEndpoint(key);
|
|
240
|
-
if (!endpoint) {
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
const derived = endpoint.fields.flatMap((field) => field.class === 'runner-managed' && field.derivedFrom
|
|
244
|
-
? [{ fieldName: field.name, sourceName: field.derivedFrom }]
|
|
245
|
-
: []);
|
|
246
|
-
if (derived.length > 0) {
|
|
247
|
-
index.set(key, derived);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return index;
|
|
251
|
-
}
|
|
252
|
-
export function buildMediaGenerationRequestDimensions(endpointKey, input) {
|
|
253
|
-
const dimensions = {
|
|
254
|
-
billableUnitCount: 1,
|
|
255
|
-
operationKey: endpointKey,
|
|
256
|
-
};
|
|
257
|
-
for (const derived of MANIFEST_DERIVED_DIMENSIONS.get(endpointKey) ?? []) {
|
|
258
|
-
const value = input[derived.sourceName] ??
|
|
259
|
-
manifestFieldDefault(endpointKey, derived.sourceName);
|
|
260
|
-
if (value !== undefined) {
|
|
261
|
-
dimensions[derived.fieldName] = value;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
if (endpointKey.startsWith('image-')) {
|
|
265
|
-
const resolution = typeof input.resolution === 'string' && input.resolution.trim()
|
|
266
|
-
? input.resolution.trim()
|
|
267
|
-
: manifestFieldDefault(endpointKey, 'resolution');
|
|
268
|
-
const quality = typeof input.quality === 'string' && input.quality.trim()
|
|
269
|
-
? input.quality.trim()
|
|
270
|
-
: manifestFieldDefault(endpointKey, 'quality');
|
|
271
|
-
if (typeof resolution === 'string') {
|
|
272
|
-
dimensions.imageSize = resolution;
|
|
273
|
-
}
|
|
274
|
-
if (typeof quality === 'string') {
|
|
275
|
-
dimensions.quality = quality;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (endpointKey.startsWith('video-')) {
|
|
279
|
-
const manifestResolution = manifestFieldDefault(endpointKey, 'resolution');
|
|
280
|
-
const duration = readPositiveNumber(input.duration) ??
|
|
281
|
-
readPositiveNumber(manifestFieldDefault(endpointKey, 'duration')) ??
|
|
282
|
-
5;
|
|
283
|
-
const resolution = typeof input.resolution === 'string' && input.resolution.trim()
|
|
284
|
-
? input.resolution.trim()
|
|
285
|
-
: typeof manifestResolution === 'string'
|
|
286
|
-
? manifestResolution
|
|
287
|
-
: '720p';
|
|
288
|
-
dimensions.audioMode =
|
|
289
|
-
endpointKey.startsWith('video-kling-v3-0-') && input.sound !== true
|
|
290
|
-
? 'off'
|
|
291
|
-
: 'on';
|
|
292
|
-
dimensions.duration = Math.ceil(duration);
|
|
293
|
-
dimensions.requestBytes = Buffer.byteLength(JSON.stringify(input));
|
|
294
|
-
dimensions.resolution = resolution;
|
|
295
|
-
if (endpointKey.startsWith('video-seedance-2-')) {
|
|
296
|
-
const referenceVideoCount = Array.isArray(input.reference_videos)
|
|
297
|
-
? input.reference_videos.length
|
|
298
|
-
: 0;
|
|
299
|
-
dimensions.referenceVideoCount = referenceVideoCount;
|
|
300
|
-
dimensions.referenceVideoMode =
|
|
301
|
-
referenceVideoCount > 0
|
|
302
|
-
? 'with_reference_videos'
|
|
303
|
-
: 'without_reference_videos';
|
|
304
|
-
}
|
|
305
|
-
if (endpointKey === 'video-kling-v2-6-pro-motion-control') {
|
|
306
|
-
dimensions.characterOrientation =
|
|
307
|
-
typeof input.character_orientation === 'string'
|
|
308
|
-
? input.character_orientation
|
|
309
|
-
: 'image';
|
|
310
|
-
dimensions.motionControlMode = 'reference_motion_transfer';
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
return dimensions;
|
|
314
|
-
}
|
|
315
|
-
function readPositiveNumber(value) {
|
|
316
|
-
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
|
|
317
|
-
return null;
|
|
318
|
-
}
|
|
319
|
-
return value;
|
|
320
|
-
}
|
|
321
213
|
function buildPublishSchemaReport() {
|
|
322
214
|
const operations = manifestTargetKeys('publish', 'social-publishing');
|
|
323
215
|
return {
|
package/build/index.js
CHANGED
|
@@ -412,17 +412,19 @@ async function main() {
|
|
|
412
412
|
case 'doctor':
|
|
413
413
|
process.exitCode = await runDoctor(parseDiagnosticOptions(rest));
|
|
414
414
|
return;
|
|
415
|
+
// The bin path never passes the in-process context, so these always resolve
|
|
416
|
+
// to the numeric exit code (the `unknown` return is the hosted-lib path only).
|
|
415
417
|
case 'research':
|
|
416
|
-
process.exitCode = await runHostedDomainCommand('research', rest);
|
|
418
|
+
process.exitCode = (await runHostedDomainCommand('research', rest));
|
|
417
419
|
return;
|
|
418
420
|
case 'media':
|
|
419
|
-
process.exitCode = await runHostedDomainCommand('media', rest);
|
|
421
|
+
process.exitCode = (await runHostedDomainCommand('media', rest));
|
|
420
422
|
return;
|
|
421
423
|
case 'media-file':
|
|
422
|
-
process.exitCode = await runMediaFileCommand(rest);
|
|
424
|
+
process.exitCode = (await runMediaFileCommand(rest));
|
|
423
425
|
return;
|
|
424
426
|
case 'publish':
|
|
425
|
-
process.exitCode = await runHostedDomainCommand('publish', rest);
|
|
427
|
+
process.exitCode = (await runHostedDomainCommand('publish', rest));
|
|
426
428
|
return;
|
|
427
429
|
case 'quote':
|
|
428
430
|
process.exitCode = await runQuoteCommand(rest);
|
package/build/update-check.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
|
-
import { readCurrentCliVersion } from './client-compatibility.js';
|
|
3
|
+
import { POSTPLUS_CLI_UPDATE_COMMAND, readCurrentCliVersion, } from './client-compatibility.js';
|
|
4
4
|
import { runInteractiveCommand as runDefaultInteractiveCommand, } from './command-runner.js';
|
|
5
5
|
import { getPostPlusConfigDir, readManagedSkillBaseline, } from './local-state.js';
|
|
6
6
|
import { POSTPLUS_SKILLS_REPO, loadPublicSkillCatalog, } from './skill-catalog.js';
|
|
@@ -8,7 +8,6 @@ const UPDATE_CHECK_TTL_MS = 24 * 60 * 60 * 1000;
|
|
|
8
8
|
const UPDATE_CHECK_CACHE_FILE = 'update-check.json';
|
|
9
9
|
const NPM_PACKAGE_NAME = '@postplus/cli';
|
|
10
10
|
const NPM_LATEST_URL = `https://registry.npmjs.org/${encodeURIComponent(NPM_PACKAGE_NAME)}/latest`;
|
|
11
|
-
export const POSTPLUS_CLI_UPDATE_COMMAND = 'npm install -g @postplus/cli@latest';
|
|
12
11
|
const POSTPLUS_CLI_UPDATE_ARGS = ['install', '-g', '@postplus/cli@latest'];
|
|
13
12
|
export async function generateUpdateStatusReport(input = {}, dependencies = {
|
|
14
13
|
fetchFn: fetch,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postplus/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.47",
|
|
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.",
|
|
@@ -13,13 +13,19 @@
|
|
|
13
13
|
"build/auth-validate.js",
|
|
14
14
|
"build/auth.js",
|
|
15
15
|
"build/authed-cloud-request.js",
|
|
16
|
+
"build/authed-cloud-request.d.ts",
|
|
16
17
|
"build/client-compatibility.js",
|
|
17
18
|
"build/command-runner.js",
|
|
18
19
|
"build/doctor.js",
|
|
19
20
|
"build/hosted-domain-commands.js",
|
|
21
|
+
"build/hosted-domain-commands.d.ts",
|
|
22
|
+
"build/hosted-lib.js",
|
|
23
|
+
"build/hosted-lib.d.ts",
|
|
20
24
|
"build/generated/hosted-execution-manifest.generated.js",
|
|
25
|
+
"build/generated/hosted-field-validation-core.generated.js",
|
|
21
26
|
"build/hosted-field-validation.js",
|
|
22
27
|
"build/hosted-manifest-index.js",
|
|
28
|
+
"build/hosted-manifest-index.d.ts",
|
|
23
29
|
"build/hosted-release.js",
|
|
24
30
|
"build/hosted-request-schemas.js",
|
|
25
31
|
"build/index.js",
|
|
@@ -47,6 +53,13 @@
|
|
|
47
53
|
"bin": {
|
|
48
54
|
"postplus": "build/index.js"
|
|
49
55
|
},
|
|
56
|
+
"exports": {
|
|
57
|
+
"./hosted-lib": {
|
|
58
|
+
"types": "./build/hosted-lib.d.ts",
|
|
59
|
+
"default": "./build/hosted-lib.js"
|
|
60
|
+
},
|
|
61
|
+
"./package.json": "./package.json"
|
|
62
|
+
},
|
|
50
63
|
"scripts": {
|
|
51
64
|
"build": "node ./scripts/clean-build.mjs && tsc && node ./scripts/finalize-build.mjs",
|
|
52
65
|
"clean": "rm -rf .turbo node_modules build",
|