@red-hat-developer-hub/backstage-plugin-ai-skills-common 0.0.0-stage → 0.2.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/CHANGELOG.md +8 -0
- package/README.md +118 -2
- package/dist/catalog-helpers.cjs.js +198 -0
- package/dist/catalog-helpers.cjs.js.map +1 -0
- package/dist/catalog-helpers.esm.js +190 -0
- package/dist/catalog-helpers.esm.js.map +1 -0
- package/dist/fixtures.cjs.js +269 -0
- package/dist/fixtures.cjs.js.map +1 -0
- package/dist/fixtures.esm.js +239 -0
- package/dist/fixtures.esm.js.map +1 -0
- package/dist/index.cjs.js +62 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +764 -0
- package/dist/index.esm.js +6 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/rest-contract.cjs.js +8 -0
- package/dist/rest-contract.cjs.js.map +1 -0
- package/dist/rest-contract.esm.js +5 -0
- package/dist/rest-contract.esm.js.map +1 -0
- package/dist/snapshot.cjs.js +115 -0
- package/dist/snapshot.cjs.js.map +1 -0
- package/dist/snapshot.esm.js +110 -0
- package/dist/snapshot.esm.js.map +1 -0
- package/dist/validation.cjs.js +442 -0
- package/dist/validation.cjs.js.map +1 -0
- package/dist/validation.esm.js +432 -0
- package/dist/validation.esm.js.map +1 -0
- package/package.json +47 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported source types for skill connectors.
|
|
3
|
+
*
|
|
4
|
+
* This is a closed union. Adding a new member is a breaking change
|
|
5
|
+
* for consumers performing exhaustive switching.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
type SkillSourceType = 'oci' | 'npx';
|
|
10
|
+
/**
|
|
11
|
+
* Supported snapshot statuses per design D6.
|
|
12
|
+
*
|
|
13
|
+
* - `loading` — first acquisition is in progress
|
|
14
|
+
* - `ready` — all discovery pages and candidates completed without failures
|
|
15
|
+
* - `partial` — discovery or processing was incomplete
|
|
16
|
+
* - `failed` — no usable discovery result could be obtained
|
|
17
|
+
*
|
|
18
|
+
* This is a closed union. Adding a new member is a breaking change
|
|
19
|
+
* for consumers performing exhaustive switching.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
type SnapshotStatus = 'loading' | 'ready' | 'partial' | 'failed';
|
|
24
|
+
/**
|
|
25
|
+
* An author entry with a required name and optional email.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
interface SkillAuthor {
|
|
30
|
+
/** Display name of the author. */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Optional contact email. */
|
|
33
|
+
email?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A normalized v1 skill record per design D2.
|
|
37
|
+
*
|
|
38
|
+
* `key`, `name`, `sourceUri`, and `digest` are non-empty required fields.
|
|
39
|
+
* Optional fields are omitted when absent.
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
interface SkillRecord {
|
|
44
|
+
/** Stable identity within this source; never a content digest. */
|
|
45
|
+
key: string;
|
|
46
|
+
/** Published human-readable name. */
|
|
47
|
+
name: string;
|
|
48
|
+
/** Optional description. */
|
|
49
|
+
description?: string;
|
|
50
|
+
/** Declared version, before catalog SemVer fallback. */
|
|
51
|
+
version?: string;
|
|
52
|
+
/** SPDX license identifier or free-text license. */
|
|
53
|
+
license?: string;
|
|
54
|
+
/** Skill authors — informational only, never implies catalog ownership. */
|
|
55
|
+
authors?: SkillAuthor[];
|
|
56
|
+
/** Metadata tags. */
|
|
57
|
+
tags?: string[];
|
|
58
|
+
/** Compatibility information. */
|
|
59
|
+
compatibility?: string;
|
|
60
|
+
/** Optional catalog owner hint. */
|
|
61
|
+
owner?: string;
|
|
62
|
+
/** Optional catalog lifecycle hint. */
|
|
63
|
+
lifecycle?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Digest-addressed OCI URI or fragment-free HTTPS URL.
|
|
66
|
+
* OCI: `oci://<registry>/<repository>@sha256:<hex>`
|
|
67
|
+
* npx: absolute HTTPS artifact URL.
|
|
68
|
+
*/
|
|
69
|
+
sourceUri: string;
|
|
70
|
+
/** Content digest in `sha256:<64 lowercase hex digits>` format. */
|
|
71
|
+
digest: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* OCI-specific extension fields.
|
|
75
|
+
*
|
|
76
|
+
* @public
|
|
77
|
+
*/
|
|
78
|
+
interface OciExtensions {
|
|
79
|
+
/** OCI namespace scope for the skill image. */
|
|
80
|
+
namespace?: string;
|
|
81
|
+
/** System prompt embedded in the skill image metadata. */
|
|
82
|
+
prompt?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* npx-specific extension fields.
|
|
86
|
+
*
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
interface NpxExtensions {
|
|
90
|
+
/**
|
|
91
|
+
* Artifact format type. Currently only `'skill-md'` is supported.
|
|
92
|
+
* This is a closed literal — adding a new format requires expanding
|
|
93
|
+
* both the type and the validator, which are breaking changes.
|
|
94
|
+
*/
|
|
95
|
+
type?: 'skill-md';
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A skill record from an OCI source with optional OCI-specific extensions.
|
|
99
|
+
*
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
interface OciSkillRecord extends SkillRecord {
|
|
103
|
+
/** OCI-specific extension fields scoped under the `oci` container. */
|
|
104
|
+
extensions?: {
|
|
105
|
+
oci?: OciExtensions;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* A skill record from an npx source with optional npx-specific extensions.
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
*/
|
|
113
|
+
interface NpxSkillRecord extends SkillRecord {
|
|
114
|
+
/** npx-specific extension fields scoped under the `npx` container. */
|
|
115
|
+
extensions?: {
|
|
116
|
+
npx?: NpxExtensions;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Source identity within a snapshot.
|
|
121
|
+
*
|
|
122
|
+
* @public
|
|
123
|
+
*/
|
|
124
|
+
interface SnapshotSource {
|
|
125
|
+
/** Configured source ID. */
|
|
126
|
+
id: string;
|
|
127
|
+
/** Source type discriminator. */
|
|
128
|
+
type: SkillSourceType;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* A versioned v1 skill snapshot per design D2.
|
|
132
|
+
*
|
|
133
|
+
* One response contains one bounded snapshot: at most 1,000 records and
|
|
134
|
+
* 5 MiB of serialized JSON.
|
|
135
|
+
*
|
|
136
|
+
* @public
|
|
137
|
+
*/
|
|
138
|
+
interface SkillSnapshot {
|
|
139
|
+
/** Schema version; must be `'1'` for v1. */
|
|
140
|
+
schemaVersion: '1';
|
|
141
|
+
/** Source identity. */
|
|
142
|
+
source: SnapshotSource;
|
|
143
|
+
/** Snapshot completeness status per design D6. */
|
|
144
|
+
status: SnapshotStatus;
|
|
145
|
+
/**
|
|
146
|
+
* UTC completion time as ISO 8601 string, or `null` before first attempt.
|
|
147
|
+
* `loading` snapshots have `null`; completed attempts have a UTC time.
|
|
148
|
+
*/
|
|
149
|
+
observedAt: string | null;
|
|
150
|
+
/** Successfully normalized skill records. */
|
|
151
|
+
skills: Array<OciSkillRecord | NpxSkillRecord>;
|
|
152
|
+
/** Stable keys of skills that failed processing; disjoint from skill keys. */
|
|
153
|
+
failedSkillKeys: string[];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Forward-compatibility alias for the v1 snapshot interface.
|
|
157
|
+
*
|
|
158
|
+
* When v2 is introduced, `SkillSnapshot` will widen to a union and
|
|
159
|
+
* `SkillSnapshotV1` will continue to refer to the v1 shape, allowing
|
|
160
|
+
* consumers to migrate without a breaking change.
|
|
161
|
+
*
|
|
162
|
+
* @public
|
|
163
|
+
*/
|
|
164
|
+
type SkillSnapshotV1 = SkillSnapshot;
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Maximum number of records in a single snapshot (design D2).
|
|
178
|
+
*
|
|
179
|
+
* @public
|
|
180
|
+
*/
|
|
181
|
+
declare const MAX_SNAPSHOT_RECORDS = 1000;
|
|
182
|
+
/**
|
|
183
|
+
* Maximum serialized snapshot size in bytes (design D2: 5 MiB).
|
|
184
|
+
*
|
|
185
|
+
* @public
|
|
186
|
+
*/
|
|
187
|
+
declare const MAX_SNAPSHOT_BYTES: number;
|
|
188
|
+
/**
|
|
189
|
+
* Supported schema version.
|
|
190
|
+
*
|
|
191
|
+
* @public
|
|
192
|
+
*/
|
|
193
|
+
declare const SUPPORTED_SCHEMA_VERSION = "1";
|
|
194
|
+
/**
|
|
195
|
+
* Result of a validation operation.
|
|
196
|
+
*
|
|
197
|
+
* @public
|
|
198
|
+
*/
|
|
199
|
+
interface ValidationResult {
|
|
200
|
+
/** Whether the validated input passed all checks. */
|
|
201
|
+
valid: boolean;
|
|
202
|
+
/** Human-readable error messages for each failed check. */
|
|
203
|
+
errors: string[];
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Validates a SHA-256 digest string.
|
|
207
|
+
*
|
|
208
|
+
* @public
|
|
209
|
+
*/
|
|
210
|
+
declare function isValidDigest(digest: string): boolean;
|
|
211
|
+
/**
|
|
212
|
+
* Validates an ISO 8601 UTC date string. Accepts strings ending in `Z`
|
|
213
|
+
* or `+00:00` that parse to a valid Date.
|
|
214
|
+
*
|
|
215
|
+
* @public
|
|
216
|
+
*/
|
|
217
|
+
declare function isValidUtcTimestamp(value: string): boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Validates a complete v1 SkillSnapshot.
|
|
220
|
+
*
|
|
221
|
+
* Checks:
|
|
222
|
+
* - Schema version is supported
|
|
223
|
+
* - Source identity is valid
|
|
224
|
+
* - Status is valid
|
|
225
|
+
* - Status invariants (loading/ready/partial/failed) per design D6
|
|
226
|
+
* - Timestamp validity
|
|
227
|
+
* - Record validation including source-discriminated extensions
|
|
228
|
+
* - Unique record keys
|
|
229
|
+
* - Disjoint successful/failed key sets
|
|
230
|
+
* - Count and size bounds
|
|
231
|
+
*
|
|
232
|
+
* Does NOT check deterministic ordering — that is the producer's
|
|
233
|
+
* responsibility enforced by {@link boundSnapshot}.
|
|
234
|
+
*
|
|
235
|
+
* @public
|
|
236
|
+
*/
|
|
237
|
+
declare function validateSnapshot(snapshot: unknown): ValidationResult;
|
|
238
|
+
/**
|
|
239
|
+
* Validates the serialized byte size of a snapshot against the 5 MiB
|
|
240
|
+
* limit. Call after `validateSnapshot` succeeds.
|
|
241
|
+
*
|
|
242
|
+
* @public
|
|
243
|
+
*/
|
|
244
|
+
declare function validateSnapshotSize(snapshot: SkillSnapshot): ValidationResult;
|
|
245
|
+
/**
|
|
246
|
+
* Type guard for OciSkillRecord.
|
|
247
|
+
*
|
|
248
|
+
* Requires the snapshot's `source.type` to disambiguate records that
|
|
249
|
+
* have no `extensions` field — a bare record is only an OCI record
|
|
250
|
+
* when the enclosing snapshot source is `'oci'`.
|
|
251
|
+
*
|
|
252
|
+
* @public
|
|
253
|
+
*/
|
|
254
|
+
declare function isOciSkillRecord(record: SkillRecord, sourceType: SkillSourceType): record is OciSkillRecord;
|
|
255
|
+
/**
|
|
256
|
+
* Type guard for NpxSkillRecord.
|
|
257
|
+
*
|
|
258
|
+
* Requires the snapshot's `source.type` to disambiguate records that
|
|
259
|
+
* have no `extensions` field — a bare record is only an npx record
|
|
260
|
+
* when the enclosing snapshot source is `'npx'`.
|
|
261
|
+
*
|
|
262
|
+
* @public
|
|
263
|
+
*/
|
|
264
|
+
declare function isNpxSkillRecord(record: SkillRecord, sourceType: SkillSourceType): record is NpxSkillRecord;
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* The identity tuple used for deterministic catalog entity naming.
|
|
270
|
+
*
|
|
271
|
+
* @public
|
|
272
|
+
*/
|
|
273
|
+
interface IdentityTuple {
|
|
274
|
+
/** Source type discriminator. */
|
|
275
|
+
type: SkillSourceType;
|
|
276
|
+
/** Configured source ID. */
|
|
277
|
+
id: string;
|
|
278
|
+
/** Stable record key within the source. */
|
|
279
|
+
key: string;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Computes the deterministic catalog entity name from an identity tuple.
|
|
283
|
+
*
|
|
284
|
+
* Per design D5, the name is `skill-` followed by the first 56 lowercase
|
|
285
|
+
* hex digits of the SHA-256 hash of the compact JSON UTF-8 encoding of
|
|
286
|
+
* `[source.type, source.id, record.key]`.
|
|
287
|
+
*
|
|
288
|
+
* Names, versions, tags, and content digests do not affect entity
|
|
289
|
+
* identity. A source ID or native key change creates a different name.
|
|
290
|
+
*
|
|
291
|
+
* @remarks
|
|
292
|
+
* The hashing algorithm (SHA-256 of compact JSON identity tuple, truncated
|
|
293
|
+
* to 56 hex digits) is part of the stable public contract. Persisted
|
|
294
|
+
* entities depend on this producing the same output for the same input.
|
|
295
|
+
* Any change to the algorithm constitutes a breaking (major) change.
|
|
296
|
+
*
|
|
297
|
+
* @public
|
|
298
|
+
*/
|
|
299
|
+
declare function computeCatalogName(tuple: IdentityTuple): string;
|
|
300
|
+
/**
|
|
301
|
+
* Result of tag normalization.
|
|
302
|
+
*
|
|
303
|
+
* @public
|
|
304
|
+
*/
|
|
305
|
+
interface NormalizeTagsResult {
|
|
306
|
+
/** Valid, deduplicated tags in lowercase. */
|
|
307
|
+
tags: string[];
|
|
308
|
+
/** Diagnostic messages for tags that were dropped. */
|
|
309
|
+
diagnostics: string[];
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Normalizes tags for catalog use per design D3/D5.
|
|
313
|
+
*
|
|
314
|
+
* Trims whitespace, lowercases, deduplicates, and retains only values
|
|
315
|
+
* accepted by an extended catalog tag pattern (per design D3/D5) that
|
|
316
|
+
* allows colons, plus signs, and hash characters beyond the standard
|
|
317
|
+
* Backstage tag validator. Invalid or overlength values are omitted
|
|
318
|
+
* with a diagnostic — tags are never truncated and replacement
|
|
319
|
+
* characters are never synthesized.
|
|
320
|
+
*
|
|
321
|
+
* @public
|
|
322
|
+
*/
|
|
323
|
+
declare function normalizeTags(tags: string[]): NormalizeTagsResult;
|
|
324
|
+
/**
|
|
325
|
+
* Resolves a catalog version from a declared version string and record
|
|
326
|
+
* digest, per design D5.
|
|
327
|
+
*
|
|
328
|
+
* Removes at most one leading `v`, validates the result as SemVer, and
|
|
329
|
+
* falls back to `0.0.0+<first 12 hex digits of record.digest>` when no
|
|
330
|
+
* valid SemVer is present.
|
|
331
|
+
*
|
|
332
|
+
* @param declaredVersion - The raw version string from the record, or undefined.
|
|
333
|
+
* @param digest - The record's content digest in `sha256:<64 hex>` format.
|
|
334
|
+
* @returns A valid SemVer string.
|
|
335
|
+
*
|
|
336
|
+
* @public
|
|
337
|
+
*/
|
|
338
|
+
declare function resolveVersion(declaredVersion: string | undefined, digest: string): string;
|
|
339
|
+
/**
|
|
340
|
+
* A parsed OCI skill reference.
|
|
341
|
+
*
|
|
342
|
+
* @public
|
|
343
|
+
*/
|
|
344
|
+
interface OciRef {
|
|
345
|
+
/** Full OCI URI: `oci://<registry>/<repository>@sha256:<hex>`. */
|
|
346
|
+
uri: string;
|
|
347
|
+
/** Registry host (and optional port). */
|
|
348
|
+
registry: string;
|
|
349
|
+
/** Repository path (may contain slashes). */
|
|
350
|
+
repository: string;
|
|
351
|
+
/** Content digest in `sha256:<64 hex>` format. */
|
|
352
|
+
digest: string;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Constructs a digest-addressed OCI reference URI.
|
|
356
|
+
*
|
|
357
|
+
* The returned URI has the form `oci://<registry>/<repository>@sha256:<hex>`.
|
|
358
|
+
* The provided digest must be a valid SHA-256 digest string.
|
|
359
|
+
*
|
|
360
|
+
* @param registry - Registry host (e.g., `quay.io`).
|
|
361
|
+
* @param repository - Repository path (e.g., `octo/hello-world-skill`).
|
|
362
|
+
* @param digest - Content digest in `sha256:<64 hex>` format.
|
|
363
|
+
* @returns The constructed OCI URI.
|
|
364
|
+
* @throws If the digest is invalid.
|
|
365
|
+
*
|
|
366
|
+
* @public
|
|
367
|
+
*/
|
|
368
|
+
declare function buildOciRef(registry: string, repository: string, digest: string): string;
|
|
369
|
+
/**
|
|
370
|
+
* Parses a digest-addressed OCI reference URI.
|
|
371
|
+
*
|
|
372
|
+
* Rejects URIs that do not match the `oci://<registry>/<repository>@sha256:<hex>`
|
|
373
|
+
* pattern. When a `recordDigest` is provided, validates that the URI digest
|
|
374
|
+
* agrees with the record digest.
|
|
375
|
+
*
|
|
376
|
+
* @param uri - The OCI URI to parse.
|
|
377
|
+
* @param recordDigest - Optional record digest to verify agreement.
|
|
378
|
+
* @returns The parsed OCI reference.
|
|
379
|
+
* @throws If the URI is malformed or the digest does not agree.
|
|
380
|
+
*
|
|
381
|
+
* @public
|
|
382
|
+
*/
|
|
383
|
+
declare function parseOciRef(uri: string, recordDigest?: string): OciRef;
|
|
384
|
+
/**
|
|
385
|
+
* A parsed npx skill reference.
|
|
386
|
+
*
|
|
387
|
+
* @public
|
|
388
|
+
*/
|
|
389
|
+
interface NpxRef {
|
|
390
|
+
/** Serialized reference: `<sourceUri>#<digest>`. */
|
|
391
|
+
ref: string;
|
|
392
|
+
/** The artifact source URL (HTTPS, no credentials or fragments). */
|
|
393
|
+
sourceUri: string;
|
|
394
|
+
/** Content digest in `sha256:<64 hex>` format. */
|
|
395
|
+
digest: string;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Constructs an npx skill reference from a verified artifact URL and digest.
|
|
399
|
+
*
|
|
400
|
+
* The reference has the form `<sourceUri>#<digest>` where `sourceUri` is an
|
|
401
|
+
* absolute HTTPS URL without credentials or fragments, and `digest` is a
|
|
402
|
+
* lowercase SHA-256 digest.
|
|
403
|
+
*
|
|
404
|
+
* Non-sensitive query parameters retain their original order.
|
|
405
|
+
*
|
|
406
|
+
* @param sourceUri - Absolute HTTPS artifact URL.
|
|
407
|
+
* @param digest - Content digest in `sha256:<64 hex>` format.
|
|
408
|
+
* @returns The serialized npx reference string.
|
|
409
|
+
* @throws If the URL contains credentials, fragments, or sensitive params,
|
|
410
|
+
* or if the digest is invalid, or the URL is not HTTPS.
|
|
411
|
+
*
|
|
412
|
+
* @public
|
|
413
|
+
*/
|
|
414
|
+
declare function buildNpxRef(sourceUri: string, digest: string): string;
|
|
415
|
+
/**
|
|
416
|
+
* Parses an npx skill reference.
|
|
417
|
+
*
|
|
418
|
+
* Splits at the single literal `#` separator. Validates that the URL is
|
|
419
|
+
* HTTPS, contains no credentials or fragments, and that the digest is a
|
|
420
|
+
* valid SHA-256 digest.
|
|
421
|
+
*
|
|
422
|
+
* @param ref - The serialized npx reference (`<sourceUri>#<digest>`).
|
|
423
|
+
* @returns The parsed npx reference.
|
|
424
|
+
* @throws If the reference is malformed or the URL is sensitive.
|
|
425
|
+
*
|
|
426
|
+
* @public
|
|
427
|
+
*/
|
|
428
|
+
declare function parseNpxRef(ref: string): NpxRef;
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Sorts skill records by stable `key` in ascending Unicode code-point order.
|
|
440
|
+
*
|
|
441
|
+
* This is the deterministic ordering required by design D2: before applying
|
|
442
|
+
* count or serialized-size limits, connectors sort records by stable `key`
|
|
443
|
+
* and include the longest prefix that fits.
|
|
444
|
+
*
|
|
445
|
+
* @public
|
|
446
|
+
*/
|
|
447
|
+
declare function sortRecordsByKey<T extends OciSkillRecord | NpxSkillRecord>(records: T[]): T[];
|
|
448
|
+
/**
|
|
449
|
+
* Options for creating a bounded snapshot.
|
|
450
|
+
*
|
|
451
|
+
* @public
|
|
452
|
+
*/
|
|
453
|
+
interface BoundSnapshotOptions {
|
|
454
|
+
/** Source identity. */
|
|
455
|
+
source: SnapshotSource;
|
|
456
|
+
/** All successfully normalized records (will be sorted and bounded). */
|
|
457
|
+
records: Array<OciSkillRecord | NpxSkillRecord>;
|
|
458
|
+
/** Stable keys of skills that failed processing. */
|
|
459
|
+
failedSkillKeys: string[];
|
|
460
|
+
/**
|
|
461
|
+
* Whether discovery completed without failures or limits.
|
|
462
|
+
* When `true` and no failed keys, status is `ready`.
|
|
463
|
+
* When `false`, status is `partial`.
|
|
464
|
+
*/
|
|
465
|
+
discoveryComplete: boolean;
|
|
466
|
+
/** UTC observation time. */
|
|
467
|
+
observedAt: string;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Creates a bounded v1 skill snapshot with deterministic ordering.
|
|
471
|
+
*
|
|
472
|
+
* Sorts records by stable key in ascending Unicode code-point order,
|
|
473
|
+
* then selects the longest prefix that fits within:
|
|
474
|
+
* - {@link MAX_SNAPSHOT_RECORDS} (1,000) records
|
|
475
|
+
* - {@link MAX_SNAPSHOT_BYTES} (5 MiB) serialized JSON
|
|
476
|
+
*
|
|
477
|
+
* If bounding removes records, the status becomes `partial` — a
|
|
478
|
+
* truncated `ready` response is never produced per design D2.
|
|
479
|
+
*
|
|
480
|
+
* Failed keys are sorted in the same ascending order.
|
|
481
|
+
*
|
|
482
|
+
* @public
|
|
483
|
+
*/
|
|
484
|
+
declare function boundSnapshot(options: BoundSnapshotOptions): SkillSnapshot;
|
|
485
|
+
/**
|
|
486
|
+
* Creates a `loading` snapshot for a source that has not yet completed
|
|
487
|
+
* its first acquisition.
|
|
488
|
+
*
|
|
489
|
+
* @public
|
|
490
|
+
*/
|
|
491
|
+
declare function createLoadingSnapshot(source: SnapshotSource): SkillSnapshot;
|
|
492
|
+
/**
|
|
493
|
+
* Creates a `failed` snapshot when no usable discovery result could
|
|
494
|
+
* be obtained.
|
|
495
|
+
*
|
|
496
|
+
* @public
|
|
497
|
+
*/
|
|
498
|
+
declare function createFailedSnapshot(source: SnapshotSource, observedAt: string): SkillSnapshot;
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Shared REST contract constants for skill connector endpoints.
|
|
502
|
+
*
|
|
503
|
+
* Each connector exposes `GET /skills/:sourceId` relative to its Backstage
|
|
504
|
+
* plugin base URL. The common catalog provider resolves the connector
|
|
505
|
+
* through Backstage discovery and authenticates with a service token whose
|
|
506
|
+
* `targetPluginId` matches the connector's registered plugin ID.
|
|
507
|
+
*
|
|
508
|
+
* ## Endpoint: GET /skills/:sourceId
|
|
509
|
+
*
|
|
510
|
+
* ### Path parameters
|
|
511
|
+
* - `sourceId` — the configured source identifier, encoded as one path
|
|
512
|
+
* segment.
|
|
513
|
+
*
|
|
514
|
+
* ### Authentication
|
|
515
|
+
* Uses Backstage's default backend service-to-service authentication.
|
|
516
|
+
* The endpoint is not public merely because upstream registries may be
|
|
517
|
+
* public.
|
|
518
|
+
*
|
|
519
|
+
* ### Responses
|
|
520
|
+
* - **200** — returns a `SkillSnapshot` v1 JSON body.
|
|
521
|
+
* - `Content-Type: application/json`
|
|
522
|
+
* - The response contains one bounded snapshot with at most 1,000
|
|
523
|
+
* records and 5 MiB of serialized JSON.
|
|
524
|
+
* - **404** — the `sourceId` is not configured on this connector.
|
|
525
|
+
*
|
|
526
|
+
* ### Consumer responsibilities
|
|
527
|
+
* The consumer bounds its response read and rejects an oversized,
|
|
528
|
+
* malformed, unsupported-version, or source-mismatched snapshot without
|
|
529
|
+
* changing that source's catalog state.
|
|
530
|
+
*
|
|
531
|
+
* @packageDocumentation
|
|
532
|
+
* @public
|
|
533
|
+
*/
|
|
534
|
+
/**
|
|
535
|
+
* Base path for the skills endpoint on each connector.
|
|
536
|
+
*
|
|
537
|
+
* @public
|
|
538
|
+
*/
|
|
539
|
+
declare const SKILLS_ENDPOINT_BASE = "/skills";
|
|
540
|
+
/**
|
|
541
|
+
* Maximum response read size in bytes that consumers should accept.
|
|
542
|
+
* Matches the 5 MiB snapshot serialized-size bound.
|
|
543
|
+
*
|
|
544
|
+
* @public
|
|
545
|
+
*/
|
|
546
|
+
declare const MAX_RESPONSE_BYTES: number;
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Reusable OCI and npx contract fixtures for connector and provider tests.
|
|
550
|
+
*
|
|
551
|
+
* @packageDocumentation
|
|
552
|
+
*/
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* OCI source fixture for contract tests.
|
|
563
|
+
*
|
|
564
|
+
* @public
|
|
565
|
+
*/
|
|
566
|
+
declare const ociSource: SnapshotSource;
|
|
567
|
+
/**
|
|
568
|
+
* npx source fixture for contract tests.
|
|
569
|
+
*
|
|
570
|
+
* @public
|
|
571
|
+
*/
|
|
572
|
+
declare const npxSource: SnapshotSource;
|
|
573
|
+
/**
|
|
574
|
+
* A valid OCI skill record with full metadata.
|
|
575
|
+
*
|
|
576
|
+
* @public
|
|
577
|
+
*/
|
|
578
|
+
declare const validOciRecordFull: OciSkillRecord;
|
|
579
|
+
/**
|
|
580
|
+
* A valid OCI record with only required fields.
|
|
581
|
+
*
|
|
582
|
+
* @public
|
|
583
|
+
*/
|
|
584
|
+
declare const validOciRecordMinimal: OciSkillRecord;
|
|
585
|
+
/**
|
|
586
|
+
* A valid OCI record with empty extensions object.
|
|
587
|
+
*
|
|
588
|
+
* @public
|
|
589
|
+
*/
|
|
590
|
+
declare const validOciRecordEmptyExtensions: OciSkillRecord;
|
|
591
|
+
/**
|
|
592
|
+
* A valid npx skill record with full metadata.
|
|
593
|
+
*
|
|
594
|
+
* @public
|
|
595
|
+
*/
|
|
596
|
+
declare const validNpxRecordFull: NpxSkillRecord;
|
|
597
|
+
/**
|
|
598
|
+
* A valid npx record with only required fields.
|
|
599
|
+
*
|
|
600
|
+
* @public
|
|
601
|
+
*/
|
|
602
|
+
declare const validNpxRecordMinimal: NpxSkillRecord;
|
|
603
|
+
/**
|
|
604
|
+
* A valid npx record with a query-string-bearing source URI.
|
|
605
|
+
*
|
|
606
|
+
* @public
|
|
607
|
+
*/
|
|
608
|
+
declare const validNpxRecordWithQuery: NpxSkillRecord;
|
|
609
|
+
/**
|
|
610
|
+
* A valid ready OCI snapshot.
|
|
611
|
+
*
|
|
612
|
+
* @public
|
|
613
|
+
*/
|
|
614
|
+
declare const validOciSnapshotReady: SkillSnapshot;
|
|
615
|
+
/**
|
|
616
|
+
* A valid ready npx snapshot.
|
|
617
|
+
*
|
|
618
|
+
* @public
|
|
619
|
+
*/
|
|
620
|
+
declare const validNpxSnapshotReady: SkillSnapshot;
|
|
621
|
+
/**
|
|
622
|
+
* A valid loading snapshot.
|
|
623
|
+
*
|
|
624
|
+
* @public
|
|
625
|
+
*/
|
|
626
|
+
declare const validLoadingSnapshot: SkillSnapshot;
|
|
627
|
+
/**
|
|
628
|
+
* A valid partial snapshot with failed keys.
|
|
629
|
+
*
|
|
630
|
+
* @public
|
|
631
|
+
*/
|
|
632
|
+
declare const validPartialSnapshot: SkillSnapshot;
|
|
633
|
+
/**
|
|
634
|
+
* A valid failed snapshot.
|
|
635
|
+
*
|
|
636
|
+
* @public
|
|
637
|
+
*/
|
|
638
|
+
declare const validFailedSnapshot: SkillSnapshot;
|
|
639
|
+
/**
|
|
640
|
+
* A valid partial snapshot with no records and no failed keys.
|
|
641
|
+
*
|
|
642
|
+
* @public
|
|
643
|
+
*/
|
|
644
|
+
declare const validPartialEmptySnapshot: SkillSnapshot;
|
|
645
|
+
/**
|
|
646
|
+
* A valid ready snapshot with zero records (successful empty discovery).
|
|
647
|
+
*
|
|
648
|
+
* @public
|
|
649
|
+
*/
|
|
650
|
+
declare const validReadyEmptySnapshot: SkillSnapshot;
|
|
651
|
+
/**
|
|
652
|
+
* Record with empty key.
|
|
653
|
+
*
|
|
654
|
+
* @public
|
|
655
|
+
*/
|
|
656
|
+
declare const invalidRecordEmptyKey: OciSkillRecord;
|
|
657
|
+
/**
|
|
658
|
+
* Record with malformed digest (uppercase).
|
|
659
|
+
*
|
|
660
|
+
* @public
|
|
661
|
+
*/
|
|
662
|
+
declare const invalidRecordBadDigest: OciSkillRecord;
|
|
663
|
+
/**
|
|
664
|
+
* Record with truncated digest.
|
|
665
|
+
*
|
|
666
|
+
* @public
|
|
667
|
+
*/
|
|
668
|
+
declare const invalidRecordShortDigest: OciSkillRecord;
|
|
669
|
+
/**
|
|
670
|
+
* npx record with OCI extension (source mismatch).
|
|
671
|
+
*
|
|
672
|
+
* @public
|
|
673
|
+
*/
|
|
674
|
+
declare const invalidNpxRecordWithOciExtension: NpxSkillRecord;
|
|
675
|
+
/**
|
|
676
|
+
* OCI record with npx extension (source mismatch).
|
|
677
|
+
*
|
|
678
|
+
* @public
|
|
679
|
+
*/
|
|
680
|
+
declare const invalidOciRecordWithNpxExtension: OciSkillRecord;
|
|
681
|
+
/**
|
|
682
|
+
* OCI record with unknown extension key.
|
|
683
|
+
*
|
|
684
|
+
* @public
|
|
685
|
+
*/
|
|
686
|
+
declare const invalidOciRecordUnknownExtKey: OciSkillRecord;
|
|
687
|
+
/**
|
|
688
|
+
* Snapshot with unsupported schema version.
|
|
689
|
+
*
|
|
690
|
+
* @public
|
|
691
|
+
*/
|
|
692
|
+
declare const invalidSnapshotBadVersion: unknown;
|
|
693
|
+
/**
|
|
694
|
+
* Snapshot claiming ready with failed keys.
|
|
695
|
+
*
|
|
696
|
+
* @public
|
|
697
|
+
*/
|
|
698
|
+
declare const invalidSnapshotReadyWithFailedKeys: unknown;
|
|
699
|
+
/**
|
|
700
|
+
* Snapshot with duplicate skill keys.
|
|
701
|
+
*
|
|
702
|
+
* @public
|
|
703
|
+
*/
|
|
704
|
+
declare const invalidSnapshotDuplicateKeys: unknown;
|
|
705
|
+
/**
|
|
706
|
+
* Snapshot with overlapping skill and failed keys.
|
|
707
|
+
*
|
|
708
|
+
* @public
|
|
709
|
+
*/
|
|
710
|
+
declare const invalidSnapshotOverlappingKeys: unknown;
|
|
711
|
+
/**
|
|
712
|
+
* Loading snapshot with non-null observedAt.
|
|
713
|
+
*
|
|
714
|
+
* @public
|
|
715
|
+
*/
|
|
716
|
+
declare const invalidLoadingWithObservedAt: unknown;
|
|
717
|
+
/**
|
|
718
|
+
* Loading snapshot with skills.
|
|
719
|
+
*
|
|
720
|
+
* @public
|
|
721
|
+
*/
|
|
722
|
+
declare const invalidLoadingWithSkills: unknown;
|
|
723
|
+
/**
|
|
724
|
+
* Failed snapshot with skills.
|
|
725
|
+
*
|
|
726
|
+
* @public
|
|
727
|
+
*/
|
|
728
|
+
declare const invalidFailedWithSkills: unknown;
|
|
729
|
+
/**
|
|
730
|
+
* Snapshot with non-UTC timestamp.
|
|
731
|
+
*
|
|
732
|
+
* @public
|
|
733
|
+
*/
|
|
734
|
+
declare const invalidSnapshotNonUtcTimestamp: unknown;
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Shared v1 skill record and snapshot contract for skill connectors
|
|
738
|
+
* and the common catalog provider.
|
|
739
|
+
*
|
|
740
|
+
* This library owns schemas, validation, and pure helpers. It performs
|
|
741
|
+
* no network, scheduler, database, or catalog operations.
|
|
742
|
+
*
|
|
743
|
+
* @packageDocumentation
|
|
744
|
+
*/
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
export { MAX_RESPONSE_BYTES, MAX_SNAPSHOT_BYTES, MAX_SNAPSHOT_RECORDS, SKILLS_ENDPOINT_BASE, SUPPORTED_SCHEMA_VERSION, boundSnapshot, buildNpxRef, buildOciRef, computeCatalogName, createFailedSnapshot, createLoadingSnapshot, invalidFailedWithSkills, invalidLoadingWithObservedAt, invalidLoadingWithSkills, invalidNpxRecordWithOciExtension, invalidOciRecordUnknownExtKey, invalidOciRecordWithNpxExtension, invalidRecordBadDigest, invalidRecordEmptyKey, invalidRecordShortDigest, invalidSnapshotBadVersion, invalidSnapshotDuplicateKeys, invalidSnapshotNonUtcTimestamp, invalidSnapshotOverlappingKeys, invalidSnapshotReadyWithFailedKeys, isNpxSkillRecord, isOciSkillRecord, isValidDigest, isValidUtcTimestamp, normalizeTags, npxSource, ociSource, parseNpxRef, parseOciRef, resolveVersion, sortRecordsByKey, validFailedSnapshot, validLoadingSnapshot, validNpxRecordFull, validNpxRecordMinimal, validNpxRecordWithQuery, validNpxSnapshotReady, validOciRecordEmptyExtensions, validOciRecordFull, validOciRecordMinimal, validOciSnapshotReady, validPartialEmptySnapshot, validPartialSnapshot, validReadyEmptySnapshot, validateSnapshot, validateSnapshotSize };
|
|
764
|
+
export type { BoundSnapshotOptions, IdentityTuple, NormalizeTagsResult, NpxExtensions, NpxRef, NpxSkillRecord, OciExtensions, OciRef, OciSkillRecord, SkillAuthor, SkillRecord, SkillSnapshot, SkillSnapshotV1, SkillSourceType, SnapshotSource, SnapshotStatus, ValidationResult };
|