@privos_ai/app-server 0.8.4 → 0.10.0
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/README.md +76 -1
- package/dist/cli/commands/lint.d.ts +8 -0
- package/dist/cli/commands/lint.d.ts.map +1 -0
- package/dist/cli/commands/lint.js +24 -0
- package/dist/cli/commands/lint.js.map +1 -0
- package/dist/cli/commands/publish.d.ts +20 -0
- package/dist/cli/commands/publish.d.ts.map +1 -0
- package/dist/cli/commands/publish.js +365 -0
- package/dist/cli/commands/publish.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +36 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/lib/authorize.d.ts +80 -0
- package/dist/cli/lib/authorize.d.ts.map +1 -0
- package/dist/cli/lib/authorize.js +86 -0
- package/dist/cli/lib/authorize.js.map +1 -0
- package/dist/cli/lib/manifest.d.ts +30 -0
- package/dist/cli/lib/manifest.d.ts.map +1 -0
- package/dist/cli/lib/manifest.js +61 -0
- package/dist/cli/lib/manifest.js.map +1 -0
- package/dist/cli/lib/output.d.ts +66 -0
- package/dist/cli/lib/output.d.ts.map +1 -0
- package/dist/cli/lib/output.js +61 -0
- package/dist/cli/lib/output.js.map +1 -0
- package/dist/cli/lib/package-source.d.ts +63 -0
- package/dist/cli/lib/package-source.d.ts.map +1 -0
- package/dist/cli/lib/package-source.js +219 -0
- package/dist/cli/lib/package-source.js.map +1 -0
- package/dist/cli/lib/portal-client.d.ts +38 -0
- package/dist/cli/lib/portal-client.d.ts.map +1 -0
- package/dist/cli/lib/portal-client.js +87 -0
- package/dist/cli/lib/portal-client.js.map +1 -0
- package/dist/cli/lib/upload.d.ts +54 -0
- package/dist/cli/lib/upload.d.ts.map +1 -0
- package/dist/cli/lib/upload.js +75 -0
- package/dist/cli/lib/upload.js.map +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest-lint-cli.js +5 -16
- package/dist/manifest-lint-cli.js.map +1 -1
- package/dist/relay/relay-client.d.ts.map +1 -1
- package/dist/relay/relay-client.js +25 -5
- package/dist/relay/relay-client.js.map +1 -1
- package/dist/runtime.d.ts +38 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +92 -5
- package/dist/runtime.js.map +1 -1
- package/dist/ui/asset-filename-rule.d.ts +18 -0
- package/dist/ui/asset-filename-rule.d.ts.map +1 -0
- package/dist/ui/asset-filename-rule.js +39 -0
- package/dist/ui/asset-filename-rule.js.map +1 -0
- package/dist/ui/assets-manifest.d.ts +19 -0
- package/dist/ui/assets-manifest.d.ts.map +1 -0
- package/dist/ui/assets-manifest.js +128 -0
- package/dist/ui/assets-manifest.js.map +1 -0
- package/dist/ui/serve-built-ui.d.ts +28 -0
- package/dist/ui/serve-built-ui.d.ts.map +1 -0
- package/dist/ui/serve-built-ui.js +131 -0
- package/dist/ui/serve-built-ui.js.map +1 -0
- package/dist/ui/shell-watchdog.d.ts +12 -0
- package/dist/ui/shell-watchdog.d.ts.map +1 -0
- package/dist/ui/shell-watchdog.js +25 -0
- package/dist/ui/shell-watchdog.js.map +1 -0
- package/package.json +3 -1
- package/skill/README.md +14 -0
- package/skill/SKILL.md +124 -0
- package/skill/references/errors.md +68 -0
package/README.md
CHANGED
|
@@ -463,16 +463,91 @@ it is delivered live or the app is re-paired — this is expected, not a bug.
|
|
|
463
463
|
`loadStandaloneIdentity` refuses to load a tampered file (wrong mode, foreign
|
|
464
464
|
owner, or invalid content) with a specific reason instead of degrading silently.
|
|
465
465
|
|
|
466
|
+
## Split-build UI (`serveBuiltUi`)
|
|
467
|
+
|
|
468
|
+
Serve a Vite-built app UI (`base: './'`) over MCP `resources/read` without inlining the whole
|
|
469
|
+
bundle: the shell HTML stays a small resource, and hashed `assets/` files (JS/CSS/fonts/etc) are
|
|
470
|
+
served individually so a Hub can cache them by content hash instead of refetching the entire
|
|
471
|
+
bundle on every open.
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
import { serveBuiltUi } from '@privos_ai/app-server';
|
|
475
|
+
|
|
476
|
+
const appSlug = 'ai.privos.demo';
|
|
477
|
+
const shell = serveBuiltUi({ distDir: './dist/ui', appSlug });
|
|
478
|
+
|
|
479
|
+
const ui = {
|
|
480
|
+
uri: `ui://${appSlug}/form.html`,
|
|
481
|
+
renderHtml: () => shell.renderHtml(),
|
|
482
|
+
readAsset: (uri: string) => shell.readAsset(uri),
|
|
483
|
+
readAssetsManifest: () => shell.readAssetsManifest(),
|
|
484
|
+
};
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
`serveBuiltUi({ distDir, appSlug })` reads `distDir/index.html` once at construction, injects the
|
|
488
|
+
opt-in `<meta name="privos-ui-assets" content="relay">` tag (if not already present) plus an
|
|
489
|
+
inline boot watchdog `<script>`, and throws immediately if any `<script src>`/`<link href>` is not
|
|
490
|
+
relative (`./assets/…` or `assets/…`) — a sure sign the app was built without Vite `base: './'`.
|
|
491
|
+
It also validates every file under `distDir/assets` at construction: each name must match
|
|
492
|
+
`MCP_UI_ASSET_FILENAME_RE` (content-hashed, allowlisted extension), be ≤ 2 MB, and no `.map` files
|
|
493
|
+
may be present — a violation throws with the full list of offenders rather than serving a broken
|
|
494
|
+
build. `readAsset(uri)` answers `ui://<appSlug>/assets/<file>` resources (`assetUriPrefix`),
|
|
495
|
+
`readAssetsManifest()` answers the sibling `ui://<appSlug>/assets-manifest.json` resource; both are
|
|
496
|
+
wired automatically once `UiResourceProvider.readAsset` / `readAssetsManifest` are set — see
|
|
497
|
+
`runtime.ts`'s `resources/read` handling.
|
|
498
|
+
|
|
499
|
+
`MCP_UI_ASSET_FILENAME_RE`, `MCP_UI_ASSET_EXTENSIONS`, and `deriveAssetUriPrefix(appSlug)` are
|
|
500
|
+
exported for callers that need to validate or derive asset identifiers outside `serveBuiltUi`
|
|
501
|
+
itself.
|
|
502
|
+
|
|
466
503
|
## Manifest v2 preflight
|
|
467
504
|
|
|
468
505
|
```bash
|
|
469
506
|
npx privos-app-lint ./privos-app.json
|
|
507
|
+
# equivalent to:
|
|
508
|
+
npx privos-app lint ./privos-app.json
|
|
470
509
|
```
|
|
471
510
|
|
|
472
511
|
The command rejects mixed legacy/v2 permission declarations and prints deterministic
|
|
473
512
|
`canonicalManifestHash` and `publisherPermissionDeclarationHash` values. The latter covers the
|
|
474
513
|
publisher declaration only; Hub/Portal compute the authoritative permission contract hash with
|
|
475
|
-
the versioned server-owned catalog and immutable image digest.
|
|
514
|
+
the versioned server-owned catalog and immutable image digest. `privos-app-lint` is kept as a
|
|
515
|
+
compatibility alias for `privos-app lint` — same output, same exit code.
|
|
516
|
+
|
|
517
|
+
## CLI: `privos-app publish`
|
|
518
|
+
|
|
519
|
+
Run from inside the app folder (where `privos-app.json` and `package.json` live):
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
npx privos-app publish
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
This packages the git worktree into a source archive (`git archive`, with the same
|
|
526
|
+
dirty-tree refusal, credential-file scan, and entry-policy checks as
|
|
527
|
+
`scripts/package-source.sh`), authorizes with the Portal, uploads the archive, creates
|
|
528
|
+
the version, and submits it for review — in one command, no hand-minted session.
|
|
529
|
+
|
|
530
|
+
Two authorization modes, both ending in a scoped, short-lived Portal grant (never a
|
|
531
|
+
browser session):
|
|
532
|
+
|
|
533
|
+
- **Browser approval (default).** The CLI prints a URL and a user code; approve on
|
|
534
|
+
`client.privos.io` and the CLI proceeds automatically once approved.
|
|
535
|
+
- **Publisher token (CI).** Set `PRIVOS_PUBLISHER_TOKEN` (or pass `--token-stdin`) to
|
|
536
|
+
skip the browser step — only works once the listing's first version was approved
|
|
537
|
+
interactively (`409 LISTING_NOT_BOUND` otherwise).
|
|
538
|
+
|
|
539
|
+
Useful flags: `--listing <slug>`, `--changelog <text>` / `--changelog-file <path>`,
|
|
540
|
+
`--allow-dirty`, `--dry-run` (package only, prints the git revision + archive sha256),
|
|
541
|
+
`--yes` (skip the confirmation prompt), `--portal <origin>`, `--machine-label <text>`,
|
|
542
|
+
`--open` (open the approval URL), `--json` (one NDJSON event per step), `--cwd <path>`.
|
|
543
|
+
|
|
544
|
+
Exit codes: `0` submitted, `2` blocked by policy (lint/package/semver/preflight
|
|
545
|
+
failed/unbound listing), `3` authorization denied/expired, `4` network/portal error,
|
|
546
|
+
`5` usage. The CLI's own manifest lint is structure-only — its
|
|
547
|
+
`canonicalManifestHash` is **not** the Portal's canonical digest and is never sent;
|
|
548
|
+
the Portal returns the authoritative `manifestDigest` after upload. Secrets are never
|
|
549
|
+
printed in full: publisher tokens are shown masked to a prefix, and the publish grant
|
|
550
|
+
value is never printed.
|
|
476
551
|
|
|
477
552
|
## Scripts
|
|
478
553
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `privos-app lint [manifestPath]` — identical behavior to the original
|
|
3
|
+
* `privos-app-lint` binary (byte-identical stdout/stderr and exit code).
|
|
4
|
+
* `src/manifest-lint-cli.ts` delegates here so the compatibility alias never
|
|
5
|
+
* drifts from this implementation.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runLint(argv: readonly string[]): number;
|
|
8
|
+
//# sourceMappingURL=lint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/lint.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAavD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { lintManifest } from '../../manifest-tools.js';
|
|
4
|
+
/**
|
|
5
|
+
* `privos-app lint [manifestPath]` — identical behavior to the original
|
|
6
|
+
* `privos-app-lint` binary (byte-identical stdout/stderr and exit code).
|
|
7
|
+
* `src/manifest-lint-cli.ts` delegates here so the compatibility alias never
|
|
8
|
+
* drifts from this implementation.
|
|
9
|
+
*/
|
|
10
|
+
export function runLint(argv) {
|
|
11
|
+
const manifestPath = path.resolve(argv[0] || 'privos-app.json');
|
|
12
|
+
let manifest;
|
|
13
|
+
try {
|
|
14
|
+
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
console.error(JSON.stringify({ valid: false, errors: [`Unable to read valid JSON from ${manifestPath}`] }, null, 2));
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
const result = lintManifest(manifest);
|
|
21
|
+
console.log(JSON.stringify({ manifestPath, ...result }, null, 2));
|
|
22
|
+
return result.valid ? 0 : 1;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../../../src/cli/commands/lint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,IAAuB;IAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC;IAChE,IAAI,QAAiB,CAAC;IACtB,IAAI,CAAC;QACJ,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,kCAAkC,YAAY,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACrH,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type PublishRuntimeOptions = Readonly<{
|
|
2
|
+
env?: NodeJS.ProcessEnv;
|
|
3
|
+
cwd?: string;
|
|
4
|
+
fetchImpl?: typeof fetch;
|
|
5
|
+
sleepImpl?: (ms: number) => Promise<void>;
|
|
6
|
+
openBrowser?: (url: string) => void;
|
|
7
|
+
readTokenFromStdin?: () => Promise<string>;
|
|
8
|
+
confirm?: (question: string) => Promise<boolean>;
|
|
9
|
+
isTTY?: boolean;
|
|
10
|
+
cliVersion?: string;
|
|
11
|
+
}>;
|
|
12
|
+
/**
|
|
13
|
+
* `privos-app publish` — package → lint (structure only) → authorize
|
|
14
|
+
* (browser device flow or `PRIVOS_PUBLISHER_TOKEN`) → upload → version →
|
|
15
|
+
* submit. See phase-04 requirements for the exact sequencing and exit codes
|
|
16
|
+
* (0 submitted, 2 blocked by policy, 3 authorization denied/expired, 4
|
|
17
|
+
* network/portal error, 5 usage).
|
|
18
|
+
*/
|
|
19
|
+
export declare function runPublish(argv: readonly string[], runtime?: PublishRuntimeOptions): Promise<number>;
|
|
20
|
+
//# sourceMappingURL=publish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/publish.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAUH;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAiL9G"}
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import readline from 'node:readline/promises';
|
|
4
|
+
import { parseArgs } from 'node:util';
|
|
5
|
+
import { spawn } from 'node:child_process';
|
|
6
|
+
import { loadManifest, loadPackageJson, assertIdentityAgreement, structuralLint, ManifestLoadError } from '../lib/manifest.js';
|
|
7
|
+
import { packageSource, PackagePolicyError } from '../lib/package-source.js';
|
|
8
|
+
import { PortalClient, PortalError } from '../lib/portal-client.js';
|
|
9
|
+
import { createAuthorization, waitForApproval } from '../lib/authorize.js';
|
|
10
|
+
import { createUploadSession, uploadPartsSequentially, completeUpload, createVersion, submitVersion, waitForPreflight, DEFAULT_PART_SIZE_BYTES, } from '../lib/upload.js';
|
|
11
|
+
import { Reporter, maskSecret } from '../lib/output.js';
|
|
12
|
+
const DEFAULT_PORTAL_ORIGIN = 'https://portal.privos.io';
|
|
13
|
+
/** Internal control-flow error carrying the CLI exit code to return. */
|
|
14
|
+
class CliExitError extends Error {
|
|
15
|
+
exitCode;
|
|
16
|
+
code;
|
|
17
|
+
constructor(message, exitCode, code) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.exitCode = exitCode;
|
|
20
|
+
this.code = code;
|
|
21
|
+
this.name = 'CliExitError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* `privos-app publish` — package → lint (structure only) → authorize
|
|
26
|
+
* (browser device flow or `PRIVOS_PUBLISHER_TOKEN`) → upload → version →
|
|
27
|
+
* submit. See phase-04 requirements for the exact sequencing and exit codes
|
|
28
|
+
* (0 submitted, 2 blocked by policy, 3 authorization denied/expired, 4
|
|
29
|
+
* network/portal error, 5 usage).
|
|
30
|
+
*/
|
|
31
|
+
export async function runPublish(argv, runtime = {}) {
|
|
32
|
+
const env = runtime.env ?? process.env;
|
|
33
|
+
let values;
|
|
34
|
+
try {
|
|
35
|
+
({ values } = parseArgs({
|
|
36
|
+
args: argv,
|
|
37
|
+
options: {
|
|
38
|
+
listing: { type: 'string' },
|
|
39
|
+
changelog: { type: 'string' },
|
|
40
|
+
'changelog-file': { type: 'string' },
|
|
41
|
+
'allow-dirty': { type: 'boolean', default: false },
|
|
42
|
+
'dry-run': { type: 'boolean', default: false },
|
|
43
|
+
yes: { type: 'boolean', default: false },
|
|
44
|
+
portal: { type: 'string' },
|
|
45
|
+
'machine-label': { type: 'string' },
|
|
46
|
+
open: { type: 'boolean', default: false },
|
|
47
|
+
json: { type: 'boolean', default: false },
|
|
48
|
+
cwd: { type: 'string' },
|
|
49
|
+
'token-stdin': { type: 'boolean', default: false },
|
|
50
|
+
help: { type: 'boolean', default: false, short: 'h' },
|
|
51
|
+
},
|
|
52
|
+
allowPositionals: false,
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
57
|
+
return 5;
|
|
58
|
+
}
|
|
59
|
+
if (values.help) {
|
|
60
|
+
printPublishUsage();
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
const jsonMode = Boolean(values.json);
|
|
64
|
+
const reporter = new Reporter(jsonMode);
|
|
65
|
+
const cwd = path.resolve(runtime.cwd ?? (typeof values.cwd === 'string' ? values.cwd : process.cwd()));
|
|
66
|
+
try {
|
|
67
|
+
// Step 1: locate + validate manifest identity (structure only — never send this hash to the Portal).
|
|
68
|
+
const { manifestPath, manifest } = loadManifest(cwd);
|
|
69
|
+
const { pkg } = loadPackageJson(cwd);
|
|
70
|
+
const lintResult = structuralLint(manifest);
|
|
71
|
+
if (!lintResult.valid) {
|
|
72
|
+
reporter.emit({ event: 'lint', ok: false, manifestPath });
|
|
73
|
+
throw new CliExitError(`Manifest is invalid:\n- ${lintResult.errors.join('\n- ')}`, 2, 'MANIFEST_INVALID');
|
|
74
|
+
}
|
|
75
|
+
const identityErrors = assertIdentityAgreement(manifest, pkg);
|
|
76
|
+
if (identityErrors.length > 0) {
|
|
77
|
+
reporter.emit({ event: 'lint', ok: false, manifestPath });
|
|
78
|
+
throw new CliExitError(identityErrors.join('\n'), 2, 'MANIFEST_IDENTITY_MISMATCH');
|
|
79
|
+
}
|
|
80
|
+
reporter.emit({ event: 'lint', ok: true, manifestPath });
|
|
81
|
+
const name = String(manifest.name);
|
|
82
|
+
const version = String(manifest.version);
|
|
83
|
+
// Step 2: package (refuse dirty tree unless --allow-dirty; entry policy enforced inside).
|
|
84
|
+
const packaged = packageOrThrow(cwd, name, version, Boolean(values['allow-dirty']));
|
|
85
|
+
reporter.emit({
|
|
86
|
+
event: 'package',
|
|
87
|
+
archivePath: packaged.archivePath,
|
|
88
|
+
bytes: packaged.bytes,
|
|
89
|
+
sha256: packaged.sha256,
|
|
90
|
+
entryCount: packaged.entries.length,
|
|
91
|
+
});
|
|
92
|
+
if (values['dry-run']) {
|
|
93
|
+
reporter.emit({ event: 'status', state: 'DRY_RUN', message: `git ${packaged.gitRevision} · sha256:${packaged.sha256}` });
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
// Step 3: resolve config + credentials.
|
|
97
|
+
const changelog = resolveChangelog(values, cwd);
|
|
98
|
+
const portalOrigin = typeof values.portal === 'string' ? values.portal : env.PRIVOS_PORTAL_ORIGIN || DEFAULT_PORTAL_ORIGIN;
|
|
99
|
+
const cliVersion = runtime.cliVersion ?? getOwnPackageVersion();
|
|
100
|
+
const token = values['token-stdin']
|
|
101
|
+
? (await (runtime.readTokenFromStdin ?? readTokenFromStdin)()).trim()
|
|
102
|
+
: env.PRIVOS_PUBLISHER_TOKEN || undefined;
|
|
103
|
+
if (token)
|
|
104
|
+
reporter.emit({ event: 'authorization_token', maskedToken: maskSecret(token) });
|
|
105
|
+
if (!values.yes && !jsonMode && (runtime.isTTY ?? Boolean(process.stdin.isTTY))) {
|
|
106
|
+
const confirm = runtime.confirm ?? defaultConfirm;
|
|
107
|
+
const proceed = await confirm(`Publish ${name}@${version} (sha256:${packaged.sha256.slice(0, 12)}…)? [y/N] `);
|
|
108
|
+
if (!proceed)
|
|
109
|
+
throw new CliExitError('Publish cancelled.', 5, 'CANCELLED');
|
|
110
|
+
}
|
|
111
|
+
const client = new PortalClient({ origin: portalOrigin, fetchImpl: runtime.fetchImpl, sleepImpl: runtime.sleepImpl });
|
|
112
|
+
// Step 4: authorize — browser device flow (default) or publisher-token auto-approve (CI).
|
|
113
|
+
const { grant, listing } = await authorize(client, runtime, reporter, token, {
|
|
114
|
+
manifestName: name,
|
|
115
|
+
semver: version,
|
|
116
|
+
archiveSha256: packaged.sha256,
|
|
117
|
+
archiveBytes: packaged.bytes,
|
|
118
|
+
cliVersion,
|
|
119
|
+
listingSlug: typeof values.listing === 'string' ? values.listing : undefined,
|
|
120
|
+
machineLabel: typeof values['machine-label'] === 'string' ? values['machine-label'] : undefined,
|
|
121
|
+
open: Boolean(values.open),
|
|
122
|
+
});
|
|
123
|
+
reporter.emit({ event: 'authorization_approved', listingId: listing.id, listingSlug: listing.slug });
|
|
124
|
+
// Step 5: upload sequentially under the grant.
|
|
125
|
+
const archiveBuffer = fs.readFileSync(packaged.archivePath);
|
|
126
|
+
let uploadId;
|
|
127
|
+
try {
|
|
128
|
+
({ uploadId } = await createUploadSession(client, grant.value, listing.id, {
|
|
129
|
+
fileName: path.basename(packaged.archivePath),
|
|
130
|
+
totalBytes: archiveBuffer.length,
|
|
131
|
+
paths: packaged.filePaths,
|
|
132
|
+
}));
|
|
133
|
+
await uploadPartsSequentially(client, grant.value, uploadId, archiveBuffer, DEFAULT_PART_SIZE_BYTES, (part, totalParts) => reporter.emit({ event: 'upload_progress', part, totalParts }));
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
throw mapGrantPortalError(error);
|
|
137
|
+
}
|
|
138
|
+
// Step 6: complete — verify + print the Portal's canonical digest.
|
|
139
|
+
let manifestDigest;
|
|
140
|
+
try {
|
|
141
|
+
const completed = await completeUpload(client, grant.value, uploadId);
|
|
142
|
+
manifestDigest = completed.manifestDigest;
|
|
143
|
+
reporter.emit({ event: 'upload_complete', sha256: completed.sha256, manifestDigest });
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
throw mapGrantPortalError(error);
|
|
147
|
+
}
|
|
148
|
+
// Step 7: version.
|
|
149
|
+
let createdVersion;
|
|
150
|
+
try {
|
|
151
|
+
createdVersion = await createVersion(client, grant.value, listing.id, { semver: version, uploadId, changelog });
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
throw mapGrantPortalError(error);
|
|
155
|
+
}
|
|
156
|
+
reporter.emit({ event: 'version_created', versionId: createdVersion.id, semver: createdVersion.semver });
|
|
157
|
+
// Step 8: submit, then wait ≤60s for preflight to leave PENDING.
|
|
158
|
+
try {
|
|
159
|
+
await submitVersion(client, grant.value, listing.id, createdVersion.id);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
throw mapGrantPortalError(error);
|
|
163
|
+
}
|
|
164
|
+
reporter.emit({ event: 'submitted', versionId: createdVersion.id });
|
|
165
|
+
const finalVersion = await waitForPreflight(client, grant.value, listing.id, createdVersion.id, { sleepImpl: runtime.sleepImpl });
|
|
166
|
+
const finalState = finalVersion?.state ?? 'PREFLIGHT_PENDING';
|
|
167
|
+
if (finalState === 'PREFLIGHT_FAILED') {
|
|
168
|
+
const findings = JSON.stringify(finalVersion.preflightFindings ?? finalVersion);
|
|
169
|
+
throw new CliExitError(`Preflight failed:\n${findings}`, 2, 'PREFLIGHT_FAILED');
|
|
170
|
+
}
|
|
171
|
+
if (finalState === 'PREFLIGHT_BLOCKED_INFRA') {
|
|
172
|
+
reporter.emit({
|
|
173
|
+
event: 'status',
|
|
174
|
+
state: finalState,
|
|
175
|
+
message: 'blocked on Portal build infrastructure — this is admin-side, not a problem with your submission',
|
|
176
|
+
});
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
reporter.emit({ event: 'status', state: finalState, message: 'follow up in Creator Studio' });
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (error instanceof CliExitError) {
|
|
184
|
+
reporter.emit({ event: 'error', code: error.code, message: error.message });
|
|
185
|
+
return error.exitCode;
|
|
186
|
+
}
|
|
187
|
+
if (error instanceof ManifestLoadError) {
|
|
188
|
+
reporter.emit({ event: 'error', message: error.message });
|
|
189
|
+
return 5;
|
|
190
|
+
}
|
|
191
|
+
if (error instanceof PortalError) {
|
|
192
|
+
reporter.emit({ event: 'error', code: error.code, message: error.message });
|
|
193
|
+
return 4;
|
|
194
|
+
}
|
|
195
|
+
reporter.emit({ event: 'error', message: error instanceof Error ? error.message : String(error) });
|
|
196
|
+
return 4;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function packageOrThrow(cwd, name, version, allowDirty) {
|
|
200
|
+
try {
|
|
201
|
+
return packageSource({ cwd, name, version, allowDirty });
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
if (error instanceof PackagePolicyError) {
|
|
205
|
+
const exitCode = error.code === 'NOT_GIT_REPOSITORY' || error.code === 'GIT_ARCHIVE_FAILED' ? 5 : 2;
|
|
206
|
+
const message = error.details.length > 0 ? `${error.message}\n- ${error.details.join('\n- ')}` : error.message;
|
|
207
|
+
throw new CliExitError(message, exitCode, error.code);
|
|
208
|
+
}
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async function authorize(client, runtime, reporter, token, request) {
|
|
213
|
+
try {
|
|
214
|
+
const outcome = await createAuthorization(client, request, token);
|
|
215
|
+
if (outcome.kind === 'grant') {
|
|
216
|
+
return { grant: outcome.grant, listing: outcome.listing };
|
|
217
|
+
}
|
|
218
|
+
reporter.emit({
|
|
219
|
+
event: 'authorization_device',
|
|
220
|
+
verificationUrl: outcome.verificationUrl,
|
|
221
|
+
userCode: outcome.userCode,
|
|
222
|
+
expiresIn: outcome.expiresIn,
|
|
223
|
+
});
|
|
224
|
+
if (request.open) {
|
|
225
|
+
try {
|
|
226
|
+
(runtime.openBrowser ?? openBrowser)(outcome.verificationUrl);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// best-effort only — the printed URL remains the source of truth.
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const pollOutcome = await waitForApproval(client, outcome.deviceCode, {
|
|
233
|
+
intervalMs: outcome.interval * 1000,
|
|
234
|
+
expiresInMs: outcome.expiresIn * 1000,
|
|
235
|
+
sleepImpl: runtime.sleepImpl,
|
|
236
|
+
onPending: (elapsedMs) => reporter.emit({ event: 'authorization_waiting', elapsedMs }),
|
|
237
|
+
});
|
|
238
|
+
if (pollOutcome.state === 'DENIED') {
|
|
239
|
+
reporter.emit({ event: 'authorization_denied' });
|
|
240
|
+
throw new CliExitError('Publish authorization was denied.', 3, 'AUTHORIZATION_DENIED');
|
|
241
|
+
}
|
|
242
|
+
if (pollOutcome.state === 'EXPIRED') {
|
|
243
|
+
reporter.emit({ event: 'authorization_expired' });
|
|
244
|
+
throw new CliExitError('Publish authorization expired; re-run to request a new approval.', 3, 'AUTHORIZATION_EXPIRED');
|
|
245
|
+
}
|
|
246
|
+
if (pollOutcome.state === 'CONSUMED') {
|
|
247
|
+
throw new CliExitError('Publish authorization was already consumed; re-run to request a new approval.', 3, 'AUTHORIZATION_CONSUMED');
|
|
248
|
+
}
|
|
249
|
+
return { grant: pollOutcome.grant, listing: { id: pollOutcome.grant.listingId, slug: pollOutcome.grant.listingSlug } };
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (error instanceof CliExitError)
|
|
253
|
+
throw error;
|
|
254
|
+
if (error instanceof PortalError)
|
|
255
|
+
throw mapAuthorizationPortalError(error);
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function mapAuthorizationPortalError(error) {
|
|
260
|
+
if (error.code === 'LISTING_NOT_BOUND') {
|
|
261
|
+
return new CliExitError('Listing is not yet bound to this manifest — approve the first version of this listing in your browser: run without the token.', 2, error.code);
|
|
262
|
+
}
|
|
263
|
+
if (error.code === 'LISTING_UNRESOLVED') {
|
|
264
|
+
return new CliExitError('Listing could not be resolved — pass --listing <slug> to select it.', 2, error.code);
|
|
265
|
+
}
|
|
266
|
+
// A revoked/expired/invalid publisher token is an authorization denial, not a
|
|
267
|
+
// transport fault — surface it as exit 3 so CI can tell "rotate the token" apart
|
|
268
|
+
// from "the Portal is unreachable".
|
|
269
|
+
if (error.code === 'PUBLISHER_TOKEN_REVOKED' ||
|
|
270
|
+
error.code === 'PUBLISHER_TOKEN_EXPIRED' ||
|
|
271
|
+
error.code === 'PUBLISHER_TOKEN_INVALID') {
|
|
272
|
+
return new CliExitError(`Publisher token rejected (${error.code}); rotate it in Creator Studio.`, 3, error.code);
|
|
273
|
+
}
|
|
274
|
+
return new CliExitError(error.message, 4, error.code);
|
|
275
|
+
}
|
|
276
|
+
function mapGrantPortalError(error) {
|
|
277
|
+
if (!(error instanceof PortalError))
|
|
278
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
279
|
+
if (error.code === 'PUBLISH_GRANT_EXPIRED') {
|
|
280
|
+
return new CliExitError('Publish grant expired mid-upload; re-run to request a new approval.', 3, error.code);
|
|
281
|
+
}
|
|
282
|
+
if (error.code === 'PUBLISH_GRANT_MISMATCH') {
|
|
283
|
+
return new CliExitError('Uploaded archive or manifest does not match the approved authorization; re-run publish from a clean state.', 2, error.code);
|
|
284
|
+
}
|
|
285
|
+
if (error.code === 'VERSION_SEMVER_EXISTS') {
|
|
286
|
+
return new CliExitError('Version already exists — bump `version` in privos-app.json and package.json.', 2, error.code);
|
|
287
|
+
}
|
|
288
|
+
return new CliExitError(error.message, 4, error.code);
|
|
289
|
+
}
|
|
290
|
+
function resolveChangelog(values, cwd) {
|
|
291
|
+
if (typeof values.changelog === 'string')
|
|
292
|
+
return values.changelog;
|
|
293
|
+
if (typeof values['changelog-file'] === 'string') {
|
|
294
|
+
const changelogPath = path.resolve(cwd, values['changelog-file']);
|
|
295
|
+
try {
|
|
296
|
+
return fs.readFileSync(changelogPath, 'utf8').trim();
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
throw new CliExitError(`Unable to read changelog file: ${changelogPath}`, 5, 'USAGE');
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return '';
|
|
303
|
+
}
|
|
304
|
+
function getOwnPackageVersion() {
|
|
305
|
+
try {
|
|
306
|
+
const packageJsonUrl = new URL('../../../package.json', import.meta.url);
|
|
307
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonUrl, 'utf8'));
|
|
308
|
+
return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return '0.0.0';
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
async function readTokenFromStdin() {
|
|
315
|
+
const chunks = [];
|
|
316
|
+
for await (const chunk of process.stdin)
|
|
317
|
+
chunks.push(Buffer.from(chunk));
|
|
318
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
319
|
+
}
|
|
320
|
+
async function defaultConfirm(question) {
|
|
321
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
322
|
+
try {
|
|
323
|
+
const answer = await rl.question(question);
|
|
324
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
325
|
+
}
|
|
326
|
+
finally {
|
|
327
|
+
rl.close();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function openBrowser(url) {
|
|
331
|
+
if (process.platform === 'darwin') {
|
|
332
|
+
spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
333
|
+
}
|
|
334
|
+
else if (process.platform === 'win32') {
|
|
335
|
+
spawn('cmd', ['/c', 'start', '""', url], { detached: true, stdio: 'ignore' }).unref();
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function printPublishUsage() {
|
|
342
|
+
console.log(`Usage: privos-app publish [options]
|
|
343
|
+
|
|
344
|
+
Packages the app in the current directory (or --cwd), authorizes with the
|
|
345
|
+
Portal (browser approval by default, or PRIVOS_PUBLISHER_TOKEN for CI),
|
|
346
|
+
uploads the source archive, creates the version, and submits it for review.
|
|
347
|
+
|
|
348
|
+
Options:
|
|
349
|
+
--listing <slug> Listing slug when it cannot be resolved from the manifest name
|
|
350
|
+
--changelog <text> Changelog text for this version
|
|
351
|
+
--changelog-file <path> Read changelog text from a file
|
|
352
|
+
--allow-dirty Package an uncommitted working tree (git write-tree snapshot)
|
|
353
|
+
--dry-run Package only; print the git revision and archive sha256, then stop
|
|
354
|
+
--yes Skip the interactive confirmation prompt
|
|
355
|
+
--portal <origin> Portal origin (default: $PRIVOS_PORTAL_ORIGIN or https://portal.privos.io)
|
|
356
|
+
--machine-label <text> Label shown on the approval page (never the hostname by default)
|
|
357
|
+
--open Open the approval URL in a browser
|
|
358
|
+
--json Emit one NDJSON event per step
|
|
359
|
+
--cwd <path> Directory containing privos-app.json and package.json
|
|
360
|
+
--token-stdin Read PRIVOS_PUBLISHER_TOKEN from stdin instead of the environment
|
|
361
|
+
-h, --help Show this help
|
|
362
|
+
|
|
363
|
+
Exit codes: 0 submitted, 2 blocked by policy, 3 authorization denied/expired, 4 network/portal error, 5 usage.`);
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/cli/commands/publish.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runLint } from './commands/lint.js';
|
|
3
|
+
import { runPublish } from './commands/publish.js';
|
|
4
|
+
function printUsage() {
|
|
5
|
+
console.log(`Usage: privos-app <command> [options]
|
|
6
|
+
|
|
7
|
+
Commands:
|
|
8
|
+
lint [manifestPath] Validate privos-app.json structure (default: ./privos-app.json)
|
|
9
|
+
publish [options] Package, authorize, upload and submit the app to the Marketplace
|
|
10
|
+
|
|
11
|
+
Run "privos-app publish --help" for publish options.`);
|
|
12
|
+
}
|
|
13
|
+
async function main() {
|
|
14
|
+
const [subcommand, ...rest] = process.argv.slice(2);
|
|
15
|
+
switch (subcommand) {
|
|
16
|
+
case 'lint':
|
|
17
|
+
return runLint(rest);
|
|
18
|
+
case 'publish':
|
|
19
|
+
return runPublish(rest);
|
|
20
|
+
case '-h':
|
|
21
|
+
case '--help':
|
|
22
|
+
printUsage();
|
|
23
|
+
return 0;
|
|
24
|
+
case undefined:
|
|
25
|
+
printUsage();
|
|
26
|
+
return 5;
|
|
27
|
+
default:
|
|
28
|
+
console.error(`Unknown command "${subcommand}". Usage: privos-app <lint|publish> [options]`);
|
|
29
|
+
return 5;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
main().then((exitCode) => process.exit(exitCode), (error) => {
|
|
33
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
34
|
+
process.exit(4);
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,SAAS,UAAU;IAClB,OAAO,CAAC,GAAG,CAAC;;;;;;qDAMwC,CAAC,CAAC;AACvD,CAAC;AAED,KAAK,UAAU,IAAI;IAClB,MAAM,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpD,QAAQ,UAAU,EAAE,CAAC;QACpB,KAAK,MAAM;YACV,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,KAAK,SAAS;YACb,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,IAAI,CAAC;QACV,KAAK,QAAQ;YACZ,UAAU,EAAE,CAAC;YACb,OAAO,CAAC,CAAC;QACV,KAAK,SAAS;YACb,UAAU,EAAE,CAAC;YACb,OAAO,CAAC,CAAC;QACV;YACC,OAAO,CAAC,KAAK,CAAC,oBAAoB,UAAU,+CAA+C,CAAC,CAAC;YAC7F,OAAO,CAAC,CAAC;IACX,CAAC;AACF,CAAC;AAED,IAAI,EAAE,CAAC,IAAI,CACV,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpC,CAAC,KAAc,EAAE,EAAE;IAClB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CACD,CAAC"}
|