@miakapp/cli 4.0.0-alpha.3 → 4.0.0-alpha.5
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/assets/agent-guide.md +5 -5
- package/dist/agent-pack.d.ts +86 -0
- package/dist/agent-pack.d.ts.map +1 -0
- package/dist/agent-pack.js +202 -0
- package/dist/agent-pack.js.map +1 -0
- package/dist/artifact.d.ts +32 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +328 -0
- package/dist/artifact.js.map +1 -0
- package/dist/control-plane.d.ts +37 -0
- package/dist/control-plane.d.ts.map +1 -0
- package/dist/control-plane.js +127 -0
- package/dist/control-plane.js.map +1 -0
- package/dist/discovery.d.ts +95 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +389 -0
- package/dist/discovery.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +56 -0
- package/dist/errors.js.map +1 -0
- package/dist/internal/http.d.ts +35 -0
- package/dist/internal/http.d.ts.map +1 -0
- package/dist/internal/http.js +125 -0
- package/dist/internal/http.js.map +1 -0
- package/dist/internal/json.d.ts +15 -0
- package/dist/internal/json.d.ts.map +1 -0
- package/dist/internal/json.js +227 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/names.d.ts +45 -0
- package/dist/internal/names.d.ts.map +1 -0
- package/dist/internal/names.js +98 -0
- package/dist/internal/names.js.map +1 -0
- package/dist/internal/requirements.d.ts +10 -0
- package/dist/internal/requirements.d.ts.map +1 -0
- package/dist/internal/requirements.js +50 -0
- package/dist/internal/requirements.js.map +1 -0
- package/dist/internal/yaml.d.ts +26 -0
- package/dist/internal/yaml.d.ts.map +1 -0
- package/dist/internal/yaml.js +184 -0
- package/dist/internal/yaml.js.map +1 -0
- package/dist/main.d.ts +88 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +698 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp.d.ts +93 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +539 -0
- package/dist/mcp.js.map +1 -0
- package/dist/project.d.ts +25 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +90 -0
- package/dist/project.js.map +1 -0
- package/dist/publication.d.ts +95 -0
- package/dist/publication.d.ts.map +1 -0
- package/dist/publication.js +408 -0
- package/dist/publication.js.map +1 -0
- package/dist/version.d.ts +15 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -1
package/dist/project.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { isAbsolute, join, normalize, resolve, sep } from 'node:path';
|
|
2
|
+
import { projectError } from './errors.js';
|
|
3
|
+
import { canonicalHttpsUrl } from './internal/http.js';
|
|
4
|
+
import { isHomeId, isRelease } from './internal/names.js';
|
|
5
|
+
import { canonicalRequirements } from './internal/requirements.js';
|
|
6
|
+
import { parseYaml } from './internal/yaml.js';
|
|
7
|
+
export const PROJECT_FILE = 'miakapp.yaml';
|
|
8
|
+
export const PROJECT_SCHEMA = 'miakapp.project/1';
|
|
9
|
+
function mapping(value, label) {
|
|
10
|
+
if (value === null || value === undefined || Array.isArray(value) || typeof value !== 'object') {
|
|
11
|
+
throw projectError(`${label} must be a mapping`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function exactKeys(source, allowed, label) {
|
|
16
|
+
const unknown = Object.keys(source).filter((key) => !allowed.includes(key));
|
|
17
|
+
if (unknown.length > 0) {
|
|
18
|
+
throw projectError(`${label} has unknown keys: ${unknown.join(', ')}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolves a declared path inside the project root. An absolute path or one that
|
|
23
|
+
* escapes the root is rejected so a published artifact always comes from the
|
|
24
|
+
* repository the agent is working in.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveProjectPath(root, declared, label) {
|
|
27
|
+
if (typeof declared !== 'string' || declared === '') {
|
|
28
|
+
throw projectError(`${label} must be a relative path inside the project`);
|
|
29
|
+
}
|
|
30
|
+
if (isAbsolute(declared) || declared.includes('\0')) {
|
|
31
|
+
throw projectError(`${label} must be relative to the project root`);
|
|
32
|
+
}
|
|
33
|
+
const normalized = normalize(declared);
|
|
34
|
+
if (normalized === '..' || normalized.startsWith(`..${sep}`)) {
|
|
35
|
+
throw projectError(`${label} must not leave the project root`);
|
|
36
|
+
}
|
|
37
|
+
return join(root, normalized);
|
|
38
|
+
}
|
|
39
|
+
export function parseProject(root, source) {
|
|
40
|
+
const document = parseYaml(source);
|
|
41
|
+
exactKeys(document, ['schema', 'home', 'control_plane', 'component', 'coordinator'], PROJECT_FILE);
|
|
42
|
+
if (document.schema !== PROJECT_SCHEMA) {
|
|
43
|
+
throw projectError(`${PROJECT_FILE} must declare schema: ${PROJECT_SCHEMA}`, 'Run miakapp init to generate a current project file.');
|
|
44
|
+
}
|
|
45
|
+
if (!isHomeId(document.home)) {
|
|
46
|
+
throw projectError('home must be a Miakapp home ID of 3..63 bytes matching [a-z][a-z0-9-]*[a-z0-9]');
|
|
47
|
+
}
|
|
48
|
+
const issuer = canonicalHttpsUrl(document.control_plane, 'control_plane');
|
|
49
|
+
if (issuer.endsWith('/'))
|
|
50
|
+
throw projectError('control_plane must not have a trailing slash');
|
|
51
|
+
const component = mapping(document.component, 'component');
|
|
52
|
+
exactKeys(component, ['artifact', 'release', 'requires'], 'component');
|
|
53
|
+
if (!isRelease(component.release)) {
|
|
54
|
+
throw projectError('component.release must be 1..64 UTF-8 bytes without control characters');
|
|
55
|
+
}
|
|
56
|
+
const requires = canonicalRequirements(component.requires === undefined || component.requires === null ? {} : component.requires);
|
|
57
|
+
let coordinatorEntry;
|
|
58
|
+
if (document.coordinator !== undefined && document.coordinator !== null) {
|
|
59
|
+
const coordinator = mapping(document.coordinator, 'coordinator');
|
|
60
|
+
exactKeys(coordinator, ['entry'], 'coordinator');
|
|
61
|
+
coordinatorEntry = resolveProjectPath(root, coordinator.entry, 'coordinator.entry');
|
|
62
|
+
}
|
|
63
|
+
return Object.freeze({
|
|
64
|
+
root,
|
|
65
|
+
homeId: document.home,
|
|
66
|
+
issuer,
|
|
67
|
+
artifactPath: resolveProjectPath(root, component.artifact, 'component.artifact'),
|
|
68
|
+
release: component.release,
|
|
69
|
+
requires,
|
|
70
|
+
coordinatorEntry,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Walks up from `start` to find the project root. An agent may run the CLI from
|
|
75
|
+
* any subdirectory of the repository it is editing.
|
|
76
|
+
*/
|
|
77
|
+
export async function findProjectFile(start, exists) {
|
|
78
|
+
let directory = resolve(start);
|
|
79
|
+
while (true) {
|
|
80
|
+
const candidate = join(directory, PROJECT_FILE);
|
|
81
|
+
if (await exists(candidate))
|
|
82
|
+
return candidate;
|
|
83
|
+
const parent = resolve(directory, '..');
|
|
84
|
+
if (parent === directory) {
|
|
85
|
+
throw projectError(`No ${PROJECT_FILE} found in ${start} or any parent directory`, 'Run miakapp init to create one.');
|
|
86
|
+
}
|
|
87
|
+
directory = parent;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type FetchLike } from './internal/http.js';
|
|
2
|
+
import { type Requirements } from './internal/names.js';
|
|
3
|
+
import type { Artifact } from './artifact.js';
|
|
4
|
+
export declare const COMPONENT_ABI = "miakapp.component/1";
|
|
5
|
+
export type UploadStatus = 'awaiting_upload' | 'delivered' | 'finalized';
|
|
6
|
+
export interface UploadCapability {
|
|
7
|
+
readonly uploadId: string;
|
|
8
|
+
readonly uploadUrl: string;
|
|
9
|
+
readonly uploadToken: string;
|
|
10
|
+
readonly expiresAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface UploadState {
|
|
13
|
+
readonly uploadId: string;
|
|
14
|
+
readonly status: UploadStatus;
|
|
15
|
+
readonly release: string;
|
|
16
|
+
readonly abi: string;
|
|
17
|
+
readonly sha256: string;
|
|
18
|
+
readonly size: number;
|
|
19
|
+
readonly requires: Requirements;
|
|
20
|
+
readonly expiresAt: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ComponentRelease {
|
|
23
|
+
readonly release: string;
|
|
24
|
+
readonly abi: string;
|
|
25
|
+
readonly sha256: string;
|
|
26
|
+
readonly size: number;
|
|
27
|
+
readonly requires: Requirements;
|
|
28
|
+
readonly finalizedAt: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ComponentPointer {
|
|
31
|
+
readonly homeId: string;
|
|
32
|
+
readonly generation: number;
|
|
33
|
+
readonly release: string;
|
|
34
|
+
readonly abi: string;
|
|
35
|
+
readonly url: string;
|
|
36
|
+
readonly sha256: string;
|
|
37
|
+
readonly size: number;
|
|
38
|
+
readonly requires: Requirements;
|
|
39
|
+
}
|
|
40
|
+
export interface PublicationTarget {
|
|
41
|
+
/** Control-plane issuer, without a trailing slash. */
|
|
42
|
+
readonly issuer: string;
|
|
43
|
+
readonly homeId: string;
|
|
44
|
+
/** Five-minute `components:publish` access token. */
|
|
45
|
+
readonly token: string;
|
|
46
|
+
readonly fetch?: FetchLike;
|
|
47
|
+
readonly signal?: AbortSignal;
|
|
48
|
+
}
|
|
49
|
+
export interface UploadRequest {
|
|
50
|
+
readonly release: string;
|
|
51
|
+
readonly requires: Requirements;
|
|
52
|
+
}
|
|
53
|
+
/** Step 1: request one capability bound to the complete publication tuple. */
|
|
54
|
+
export declare function requestUpload(target: PublicationTarget, artifact: Artifact, request: UploadRequest): Promise<UploadCapability>;
|
|
55
|
+
/**
|
|
56
|
+
* Step 2: deliver the exact bytes once.
|
|
57
|
+
*
|
|
58
|
+
* A lost response is never retried with a new capability: the caller reconciles
|
|
59
|
+
* through {@link readUpload}, which distinguishes `awaiting_upload` from
|
|
60
|
+
* `delivered`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function deliverArtifact(target: PublicationTarget, capability: UploadCapability, artifact: Artifact): Promise<void>;
|
|
63
|
+
/** Step 3: finalize only the delivered, content-addressed object. */
|
|
64
|
+
export declare function finalizeUpload(target: PublicationTarget, uploadId: string): Promise<ComponentRelease>;
|
|
65
|
+
/** Reconciliation read that tells a lost `PUT` from an undelivered upload. */
|
|
66
|
+
export declare function readUpload(target: PublicationTarget, uploadId: string): Promise<UploadState>;
|
|
67
|
+
/** Reconciliation read for a lost finalization response. */
|
|
68
|
+
export declare function readRelease(target: PublicationTarget, sha256: string): Promise<ComponentRelease | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Step 4: compare-and-set the home pointer to a strictly greater generation.
|
|
71
|
+
*
|
|
72
|
+
* Activation is one transaction and is never blindly retried: a stale
|
|
73
|
+
* `expected_generation` fails with `generation_conflict` rather than
|
|
74
|
+
* last-write-wins.
|
|
75
|
+
*/
|
|
76
|
+
export declare function activateRelease(target: PublicationTarget, activation: {
|
|
77
|
+
readonly sha256: string;
|
|
78
|
+
readonly expectedGeneration: number;
|
|
79
|
+
readonly generation: number;
|
|
80
|
+
}): Promise<ComponentPointer>;
|
|
81
|
+
/**
|
|
82
|
+
* Publishes one artifact: capability, delivery, finalization, activation.
|
|
83
|
+
*
|
|
84
|
+
* Every step is checked against the locally computed digest, size and
|
|
85
|
+
* requirements, so a control plane that echoes different metadata is rejected
|
|
86
|
+
* rather than trusted.
|
|
87
|
+
*/
|
|
88
|
+
export declare function publish(target: PublicationTarget, artifact: Artifact, request: UploadRequest & {
|
|
89
|
+
readonly expectedGeneration: number;
|
|
90
|
+
readonly generation: number;
|
|
91
|
+
}): Promise<{
|
|
92
|
+
readonly release: ComponentRelease;
|
|
93
|
+
readonly pointer: ComponentPointer;
|
|
94
|
+
}>;
|
|
95
|
+
//# sourceMappingURL=publication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication.d.ts","sourceRoot":"","sources":["../src/publication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { artifactError, authorizationError, conflictError, contractError, unknownOutcomeError, } from './errors.js';
|
|
2
|
+
import { MAXIMUM_RESPONSE_BYTES, cancelBody, jsonRequestInit, readBoundedBody, readJsonBody, requestBody, } from './internal/http.js';
|
|
3
|
+
import { boundedString, exactRecord, instant, parseJson, positiveInteger, } from './internal/json.js';
|
|
4
|
+
import { MAXIMUM_ARTIFACT_BYTES, isDigest, isGeneration, isHomeId, isRandomId, isRelease, isUploadToken, REQUIREMENT_KINDS, } from './internal/names.js';
|
|
5
|
+
import { canonicalRequirements, sameRequirements } from './internal/requirements.js';
|
|
6
|
+
export const COMPONENT_ABI = 'miakapp.component/1';
|
|
7
|
+
/** RFC 0004 §13.2 expires an upload capability within fifteen minutes. */
|
|
8
|
+
const MAXIMUM_CAPABILITY_LIFETIME_MS = 900_000;
|
|
9
|
+
function client(target) {
|
|
10
|
+
if (!isHomeId(target.homeId))
|
|
11
|
+
throw contractError('homeId is not a valid Miakapp home ID');
|
|
12
|
+
const fetcher = target.fetch ?? globalThis.fetch;
|
|
13
|
+
return {
|
|
14
|
+
fetcher,
|
|
15
|
+
signal: target.signal ?? new AbortController().signal,
|
|
16
|
+
base: `${target.issuer}/v1/homes/${target.homeId}`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async function readFailure(response) {
|
|
20
|
+
let parsed;
|
|
21
|
+
try {
|
|
22
|
+
parsed = parseJson(await readBoundedBody(response, MAXIMUM_RESPONSE_BYTES));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return {
|
|
26
|
+
code: 'unparseable',
|
|
27
|
+
retryable: false,
|
|
28
|
+
requestId: '',
|
|
29
|
+
message: `HTTP ${response.status} with no closed error body`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const envelope = exactRecord(parsed, ['error']);
|
|
33
|
+
const error = exactRecord(envelope.error, ['code', 'message', 'retryable', 'request_id']);
|
|
34
|
+
if (typeof error.retryable !== 'boolean') {
|
|
35
|
+
throw contractError('Error envelope has a non-boolean retryable field');
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
code: boundedString(error.code, 1, 64),
|
|
39
|
+
retryable: error.retryable,
|
|
40
|
+
requestId: boundedString(error.request_id, 0, 64),
|
|
41
|
+
message: boundedString(error.message, 1, 1_024),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Maps the RFC 0004 §16 closed failure table onto CLI outcomes.
|
|
46
|
+
*
|
|
47
|
+
* `temporarily_unavailable` after a mutating request is deliberately
|
|
48
|
+
* `unknown_outcome`: §17 states the effect may already have crossed its commit
|
|
49
|
+
* boundary, so the caller reconciles with a read instead of repeating it.
|
|
50
|
+
*/
|
|
51
|
+
function failure(operation, status, error, mutating) {
|
|
52
|
+
const detail = `${operation} failed with HTTP ${status} ${error.code}`
|
|
53
|
+
+ (error.requestId === '' ? '' : ` (request ${error.requestId})`);
|
|
54
|
+
switch (error.code) {
|
|
55
|
+
case 'invalid_home_key':
|
|
56
|
+
case 'invalid_access_token':
|
|
57
|
+
case 'insufficient_scope':
|
|
58
|
+
case 'not_home_owner':
|
|
59
|
+
case 'publisher_mismatch':
|
|
60
|
+
case 'recent_authentication_required':
|
|
61
|
+
return authorizationError(detail, error.message);
|
|
62
|
+
case 'invalid_upload_capability':
|
|
63
|
+
return authorizationError(detail, 'The capability is absent, expired, replayed or bound to another tuple. '
|
|
64
|
+
+ 'Read the upload status before requesting a new one.');
|
|
65
|
+
case 'generation_conflict':
|
|
66
|
+
return conflictError(detail, 'Another publication advanced the pointer. Read the active generation and retry the '
|
|
67
|
+
+ 'activation with the observed expected_generation.');
|
|
68
|
+
case 'digest_quarantined':
|
|
69
|
+
return artifactError(detail, 'A quarantined digest cannot be activated, even by the owner.');
|
|
70
|
+
case 'invalid_artifact':
|
|
71
|
+
return artifactError(detail, error.message);
|
|
72
|
+
case 'limit_exceeded':
|
|
73
|
+
return artifactError(detail, error.message);
|
|
74
|
+
case 'temporarily_unavailable':
|
|
75
|
+
return mutating
|
|
76
|
+
? unknownOutcomeError(detail, 'The effect may already have committed. Reconcile with the upload-status or '
|
|
77
|
+
+ 'release read before acting again.')
|
|
78
|
+
: contractError(detail, error.message);
|
|
79
|
+
default:
|
|
80
|
+
return contractError(detail, error.message);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function decodeRequirements(value) {
|
|
84
|
+
const record = exactRecord(value, [...REQUIREMENT_KINDS]);
|
|
85
|
+
return canonicalRequirements(record);
|
|
86
|
+
}
|
|
87
|
+
function decodeUploadCapability(value, uploadBase) {
|
|
88
|
+
const document = exactRecord(value, [
|
|
89
|
+
'schema',
|
|
90
|
+
'upload_id',
|
|
91
|
+
'upload_url',
|
|
92
|
+
'upload_token',
|
|
93
|
+
'expires_at',
|
|
94
|
+
]);
|
|
95
|
+
if (document.schema !== 'miakapp.component-upload/1') {
|
|
96
|
+
throw contractError('Upload response has an unsupported schema');
|
|
97
|
+
}
|
|
98
|
+
const uploadId = document.upload_id;
|
|
99
|
+
if (!isRandomId(uploadId))
|
|
100
|
+
throw contractError('upload_id is not a 22-character random ID');
|
|
101
|
+
if (!isUploadToken(document.upload_token)) {
|
|
102
|
+
throw contractError('upload_token is not a 43-character capability secret');
|
|
103
|
+
}
|
|
104
|
+
const uploadUrl = boundedString(document.upload_url, 1, 2_048);
|
|
105
|
+
let parsed;
|
|
106
|
+
try {
|
|
107
|
+
parsed = new URL(uploadUrl);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
throw contractError('upload_url is not a URL');
|
|
111
|
+
}
|
|
112
|
+
if (parsed.protocol !== 'https:'
|
|
113
|
+
|| parsed.username !== ''
|
|
114
|
+
|| parsed.password !== ''
|
|
115
|
+
|| parsed.search !== ''
|
|
116
|
+
|| parsed.hash !== ''
|
|
117
|
+
|| parsed.href !== uploadUrl
|
|
118
|
+
|| !uploadUrl.endsWith(`/${uploadId}`)
|
|
119
|
+
|| !uploadUrl.startsWith(uploadBase)) {
|
|
120
|
+
throw contractError('upload_url is not a credential-free HTTPS identifier for this home ending in its upload ID');
|
|
121
|
+
}
|
|
122
|
+
const expiresAt = instant(document.expires_at);
|
|
123
|
+
const lifetime = Date.parse(expiresAt) - Date.now();
|
|
124
|
+
if (lifetime <= 0 || lifetime > MAXIMUM_CAPABILITY_LIFETIME_MS) {
|
|
125
|
+
throw contractError('Upload capability is expired or exceeds the fifteen-minute ceiling');
|
|
126
|
+
}
|
|
127
|
+
return Object.freeze({
|
|
128
|
+
uploadId,
|
|
129
|
+
uploadUrl,
|
|
130
|
+
uploadToken: document.upload_token,
|
|
131
|
+
expiresAt,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function decodeUploadState(value) {
|
|
135
|
+
const document = exactRecord(value, [
|
|
136
|
+
'schema',
|
|
137
|
+
'upload_id',
|
|
138
|
+
'status',
|
|
139
|
+
'release',
|
|
140
|
+
'abi',
|
|
141
|
+
'sha256',
|
|
142
|
+
'size',
|
|
143
|
+
'requires',
|
|
144
|
+
'expires_at',
|
|
145
|
+
]);
|
|
146
|
+
if (document.schema !== 'miakapp.component-upload-status/1') {
|
|
147
|
+
throw contractError('Upload-status response has an unsupported schema');
|
|
148
|
+
}
|
|
149
|
+
const status = document.status;
|
|
150
|
+
if (status !== 'awaiting_upload' && status !== 'delivered' && status !== 'finalized') {
|
|
151
|
+
throw contractError('Upload status is outside the closed set');
|
|
152
|
+
}
|
|
153
|
+
if (!isRandomId(document.upload_id))
|
|
154
|
+
throw contractError('upload_id is invalid');
|
|
155
|
+
if (!isRelease(document.release))
|
|
156
|
+
throw contractError('release is invalid');
|
|
157
|
+
if (!isDigest(document.sha256))
|
|
158
|
+
throw contractError('sha256 is not a base64url SHA-256 digest');
|
|
159
|
+
if (document.abi !== COMPONENT_ABI)
|
|
160
|
+
throw contractError('abi is not the supported ABI');
|
|
161
|
+
return Object.freeze({
|
|
162
|
+
uploadId: document.upload_id,
|
|
163
|
+
status,
|
|
164
|
+
release: document.release,
|
|
165
|
+
abi: COMPONENT_ABI,
|
|
166
|
+
sha256: document.sha256,
|
|
167
|
+
size: positiveInteger(document.size, MAXIMUM_ARTIFACT_BYTES),
|
|
168
|
+
requires: decodeRequirements(document.requires),
|
|
169
|
+
expiresAt: instant(document.expires_at),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function decodeRelease(value) {
|
|
173
|
+
const document = exactRecord(value, [
|
|
174
|
+
'schema',
|
|
175
|
+
'release',
|
|
176
|
+
'abi',
|
|
177
|
+
'sha256',
|
|
178
|
+
'size',
|
|
179
|
+
'requires',
|
|
180
|
+
'finalized_at',
|
|
181
|
+
]);
|
|
182
|
+
if (document.schema !== 'miakapp.component-release/1') {
|
|
183
|
+
throw contractError('Release response has an unsupported schema');
|
|
184
|
+
}
|
|
185
|
+
if (!isRelease(document.release))
|
|
186
|
+
throw contractError('release is invalid');
|
|
187
|
+
if (!isDigest(document.sha256))
|
|
188
|
+
throw contractError('sha256 is not a base64url SHA-256 digest');
|
|
189
|
+
if (document.abi !== COMPONENT_ABI)
|
|
190
|
+
throw contractError('abi is not the supported ABI');
|
|
191
|
+
return Object.freeze({
|
|
192
|
+
release: document.release,
|
|
193
|
+
abi: COMPONENT_ABI,
|
|
194
|
+
sha256: document.sha256,
|
|
195
|
+
size: positiveInteger(document.size, MAXIMUM_ARTIFACT_BYTES),
|
|
196
|
+
requires: decodeRequirements(document.requires),
|
|
197
|
+
finalizedAt: instant(document.finalized_at),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function decodePointer(value, target) {
|
|
201
|
+
const document = exactRecord(value, [
|
|
202
|
+
'schema',
|
|
203
|
+
'home_id',
|
|
204
|
+
'generation',
|
|
205
|
+
'release',
|
|
206
|
+
'abi',
|
|
207
|
+
'url',
|
|
208
|
+
'sha256',
|
|
209
|
+
'size',
|
|
210
|
+
'requires',
|
|
211
|
+
]);
|
|
212
|
+
if (document.schema !== 'miakapp.component-pointer/1') {
|
|
213
|
+
throw contractError('Pointer response has an unsupported schema');
|
|
214
|
+
}
|
|
215
|
+
if (document.home_id !== target.homeId) {
|
|
216
|
+
throw contractError('Pointer names a different home');
|
|
217
|
+
}
|
|
218
|
+
if (!isGeneration(document.generation)) {
|
|
219
|
+
throw contractError('Pointer generation is not a positive safe integer');
|
|
220
|
+
}
|
|
221
|
+
if (!isRelease(document.release))
|
|
222
|
+
throw contractError('Pointer release is invalid');
|
|
223
|
+
if (!isDigest(document.sha256))
|
|
224
|
+
throw contractError('Pointer sha256 is invalid');
|
|
225
|
+
if (document.abi !== COMPONENT_ABI)
|
|
226
|
+
throw contractError('Pointer abi is not the supported ABI');
|
|
227
|
+
const url = boundedString(document.url, 1, 2_048);
|
|
228
|
+
if (url !== `${target.issuer}/v1/components/${document.sha256}.js`) {
|
|
229
|
+
throw contractError('Pointer url is not the token-free control-plane artifact resource');
|
|
230
|
+
}
|
|
231
|
+
return Object.freeze({
|
|
232
|
+
homeId: target.homeId,
|
|
233
|
+
generation: document.generation,
|
|
234
|
+
release: document.release,
|
|
235
|
+
abi: COMPONENT_ABI,
|
|
236
|
+
url,
|
|
237
|
+
sha256: document.sha256,
|
|
238
|
+
size: positiveInteger(document.size, MAXIMUM_ARTIFACT_BYTES),
|
|
239
|
+
requires: decodeRequirements(document.requires),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/** Step 1: request one capability bound to the complete publication tuple. */
|
|
243
|
+
export async function requestUpload(target, artifact, request) {
|
|
244
|
+
const { fetcher, signal, base } = client(target);
|
|
245
|
+
if (!isRelease(request.release)) {
|
|
246
|
+
throw contractError('release must be 1..64 UTF-8 bytes without control characters');
|
|
247
|
+
}
|
|
248
|
+
const body = requestBody({
|
|
249
|
+
release: request.release,
|
|
250
|
+
abi: COMPONENT_ABI,
|
|
251
|
+
sha256: artifact.sha256,
|
|
252
|
+
size: artifact.size,
|
|
253
|
+
requires: request.requires,
|
|
254
|
+
});
|
|
255
|
+
const response = await fetcher(`${base}/component-uploads`, jsonRequestInit('POST', target.token, body, signal));
|
|
256
|
+
if (response.status !== 201) {
|
|
257
|
+
throw failure('Upload capability request', response.status, await readFailure(response), false);
|
|
258
|
+
}
|
|
259
|
+
return decodeUploadCapability(await readJsonBody(response), `${base}/component-uploads/`);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Step 2: deliver the exact bytes once.
|
|
263
|
+
*
|
|
264
|
+
* A lost response is never retried with a new capability: the caller reconciles
|
|
265
|
+
* through {@link readUpload}, which distinguishes `awaiting_upload` from
|
|
266
|
+
* `delivered`.
|
|
267
|
+
*/
|
|
268
|
+
export async function deliverArtifact(target, capability, artifact) {
|
|
269
|
+
const { fetcher, signal } = client(target);
|
|
270
|
+
let response;
|
|
271
|
+
try {
|
|
272
|
+
response = await fetcher(capability.uploadUrl, {
|
|
273
|
+
method: 'PUT',
|
|
274
|
+
headers: {
|
|
275
|
+
authorization: `Bearer ${capability.uploadToken}`,
|
|
276
|
+
'content-type': 'application/javascript; charset=utf-8',
|
|
277
|
+
'content-length': String(artifact.size),
|
|
278
|
+
},
|
|
279
|
+
body: artifact.bytes,
|
|
280
|
+
redirect: 'error',
|
|
281
|
+
credentials: 'omit',
|
|
282
|
+
signal,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
throw unknownOutcomeError('Artifact delivery did not return a response', 'Read the upload status before deciding whether to deliver again.');
|
|
287
|
+
}
|
|
288
|
+
if (response.status === 204) {
|
|
289
|
+
cancelBody(response);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
throw failure('Artifact delivery', response.status, await readFailure(response), true);
|
|
293
|
+
}
|
|
294
|
+
/** Step 3: finalize only the delivered, content-addressed object. */
|
|
295
|
+
export async function finalizeUpload(target, uploadId) {
|
|
296
|
+
const { fetcher, signal, base } = client(target);
|
|
297
|
+
if (!isRandomId(uploadId))
|
|
298
|
+
throw contractError('uploadId is not a 22-character random ID');
|
|
299
|
+
const response = await fetcher(`${base}/component-uploads/${uploadId}:finalize`, jsonRequestInit('POST', target.token, requestBody({}), signal));
|
|
300
|
+
if (response.status !== 200) {
|
|
301
|
+
throw failure('Finalization', response.status, await readFailure(response), true);
|
|
302
|
+
}
|
|
303
|
+
return decodeRelease(await readJsonBody(response));
|
|
304
|
+
}
|
|
305
|
+
/** Reconciliation read that tells a lost `PUT` from an undelivered upload. */
|
|
306
|
+
export async function readUpload(target, uploadId) {
|
|
307
|
+
const { fetcher, signal, base } = client(target);
|
|
308
|
+
if (!isRandomId(uploadId))
|
|
309
|
+
throw contractError('uploadId is not a 22-character random ID');
|
|
310
|
+
const response = await fetcher(`${base}/component-uploads/${uploadId}`, jsonRequestInit('GET', target.token, undefined, signal));
|
|
311
|
+
if (response.status !== 200) {
|
|
312
|
+
throw failure('Upload-status read', response.status, await readFailure(response), false);
|
|
313
|
+
}
|
|
314
|
+
return decodeUploadState(await readJsonBody(response));
|
|
315
|
+
}
|
|
316
|
+
/** Reconciliation read for a lost finalization response. */
|
|
317
|
+
export async function readRelease(target, sha256) {
|
|
318
|
+
const { fetcher, signal, base } = client(target);
|
|
319
|
+
if (!isDigest(sha256))
|
|
320
|
+
throw contractError('sha256 is not a base64url SHA-256 digest');
|
|
321
|
+
const response = await fetcher(`${base}/component-releases/${sha256}`, jsonRequestInit('GET', target.token, undefined, signal));
|
|
322
|
+
if (response.status === 422) {
|
|
323
|
+
const error = await readFailure(response);
|
|
324
|
+
if (error.code === 'invalid_artifact')
|
|
325
|
+
return undefined;
|
|
326
|
+
throw failure('Release read', response.status, error, false);
|
|
327
|
+
}
|
|
328
|
+
if (response.status !== 200) {
|
|
329
|
+
throw failure('Release read', response.status, await readFailure(response), false);
|
|
330
|
+
}
|
|
331
|
+
return decodeRelease(await readJsonBody(response));
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Step 4: compare-and-set the home pointer to a strictly greater generation.
|
|
335
|
+
*
|
|
336
|
+
* Activation is one transaction and is never blindly retried: a stale
|
|
337
|
+
* `expected_generation` fails with `generation_conflict` rather than
|
|
338
|
+
* last-write-wins.
|
|
339
|
+
*/
|
|
340
|
+
export async function activateRelease(target, activation) {
|
|
341
|
+
const { fetcher, signal, base } = client(target);
|
|
342
|
+
if (!isDigest(activation.sha256)) {
|
|
343
|
+
throw contractError('sha256 is not a base64url SHA-256 digest');
|
|
344
|
+
}
|
|
345
|
+
if (!Number.isSafeInteger(activation.expectedGeneration) || activation.expectedGeneration < 0) {
|
|
346
|
+
throw contractError('expected_generation must be a non-negative safe integer');
|
|
347
|
+
}
|
|
348
|
+
if (!isGeneration(activation.generation)
|
|
349
|
+
|| activation.generation <= activation.expectedGeneration) {
|
|
350
|
+
throw contractError('generation must be a positive safe integer above expected_generation');
|
|
351
|
+
}
|
|
352
|
+
const body = requestBody({
|
|
353
|
+
sha256: activation.sha256,
|
|
354
|
+
expected_generation: activation.expectedGeneration,
|
|
355
|
+
generation: activation.generation,
|
|
356
|
+
});
|
|
357
|
+
const response = await fetcher(`${base}/component-releases:activate`, jsonRequestInit('POST', target.token, body, signal));
|
|
358
|
+
if (response.status !== 200) {
|
|
359
|
+
throw failure('Activation', response.status, await readFailure(response), true);
|
|
360
|
+
}
|
|
361
|
+
return decodePointer(await readJsonBody(response), target);
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Publishes one artifact: capability, delivery, finalization, activation.
|
|
365
|
+
*
|
|
366
|
+
* Every step is checked against the locally computed digest, size and
|
|
367
|
+
* requirements, so a control plane that echoes different metadata is rejected
|
|
368
|
+
* rather than trusted.
|
|
369
|
+
*/
|
|
370
|
+
export async function publish(target, artifact, request) {
|
|
371
|
+
const requires = canonicalRequirements(request.requires);
|
|
372
|
+
const capability = await requestUpload(target, artifact, { release: request.release, requires });
|
|
373
|
+
await deliverArtifact(target, capability, artifact);
|
|
374
|
+
const state = await readUpload(target, capability.uploadId);
|
|
375
|
+
if (state.sha256 !== artifact.sha256
|
|
376
|
+
|| state.size !== artifact.size
|
|
377
|
+
|| state.release !== request.release
|
|
378
|
+
|| !sameRequirements(state.requires, requires)) {
|
|
379
|
+
throw contractError('Upload state does not match the tuple the capability was bound to');
|
|
380
|
+
}
|
|
381
|
+
if (state.status === 'awaiting_upload') {
|
|
382
|
+
throw unknownOutcomeError('The control plane still reports the upload as awaiting delivery', 'Request a new capability and deliver the bytes again; do not finalize this upload.');
|
|
383
|
+
}
|
|
384
|
+
const release = state.status === 'finalized'
|
|
385
|
+
? await requireRelease(target, artifact.sha256)
|
|
386
|
+
: await finalizeUpload(target, capability.uploadId);
|
|
387
|
+
if (release.sha256 !== artifact.sha256 || release.size !== artifact.size) {
|
|
388
|
+
throw contractError('Finalized release does not match the delivered artifact');
|
|
389
|
+
}
|
|
390
|
+
const pointer = await activateRelease(target, {
|
|
391
|
+
sha256: artifact.sha256,
|
|
392
|
+
expectedGeneration: request.expectedGeneration,
|
|
393
|
+
generation: request.generation,
|
|
394
|
+
});
|
|
395
|
+
if (pointer.sha256 !== artifact.sha256 || !sameRequirements(pointer.requires, requires)) {
|
|
396
|
+
throw contractError('Activated pointer does not match the published release');
|
|
397
|
+
}
|
|
398
|
+
return { release, pointer };
|
|
399
|
+
}
|
|
400
|
+
async function requireRelease(target, sha256) {
|
|
401
|
+
const release = await readRelease(target, sha256);
|
|
402
|
+
if (release === undefined) {
|
|
403
|
+
throw unknownOutcomeError('The upload reports finalized but no release record is readable', 'Re-read the release before publishing again; the control plane is mid-commit or '
|
|
404
|
+
+ 'has quarantined the digest.');
|
|
405
|
+
}
|
|
406
|
+
return release;
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=publication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication.js","sourceRoot":"","sources":["../src/publication.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package's own identity, in one place.
|
|
3
|
+
*
|
|
4
|
+
* `main.ts` imports `agent-pack.ts`, so the constants cannot live in `main.ts`
|
|
5
|
+
* without a cycle: the pack needs them to write a runnable MCP entry.
|
|
6
|
+
*
|
|
7
|
+
* Both values are duplicates of `package.json`, which cannot be imported here
|
|
8
|
+
* without a JSON import assertion the build does not emit. `test/version.test.ts`
|
|
9
|
+
* compares them to the manifest, because the drift is not cosmetic: the pack
|
|
10
|
+
* writes `PACKAGE_NAME@CLI_VERSION` into a repository, and a stale version
|
|
11
|
+
* would resolve a different release than the guide shipped beside it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const PACKAGE_NAME = "@miakapp/cli";
|
|
14
|
+
export declare const CLI_VERSION = "4.0.0-alpha.5";
|
|
15
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,eAAO,MAAM,WAAW,kBAAkB,CAAC"}
|