@opensoftware/contracts 2.5.0 → 2.7.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 +27 -1
- package/dist/cli.js +3 -6
- package/dist/cli.js.map +1 -1
- package/dist/formats.js +3 -0
- package/dist/formats.js.map +1 -1
- package/dist/generated/types.d.ts +136 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/sandbox.d.ts +17 -0
- package/dist/sandbox.js +23 -0
- package/dist/sandbox.js.map +1 -0
- package/factory-definition/factory-definition.schema.json +1 -1
- package/factory-lock/factory-lock.schema.json +32 -0
- package/openapi/openapi.json +330 -2
- package/package.json +2 -2
- package/person-keys/person-keys.schema.json +59 -0
- package/person-proof/person-proof.schema.json +75 -0
- package/skill-catalog/skill-catalog.schema.json +177 -0
- package/typespec/factory-definition.tsp +4 -1
- package/typespec/factory-lock.tsp +23 -0
- package/typespec/main.tsp +2 -0
- package/typespec/person-proof.tsp +79 -0
- package/typespec/skill-catalog.tsp +94 -0
package/README.md
CHANGED
|
@@ -28,6 +28,13 @@ const problems = validate("factory-definition", document); // [] when valid, els
|
|
|
28
28
|
`runSpans(record)` reads a run record as runlog writes it: each span with its decoded resource and attributes, or
|
|
29
29
|
`undefined` when the value is no OTLP/JSON trace export request ([ADR 0041](../docs/decisions/0041-run-record-reader.md)).
|
|
30
30
|
|
|
31
|
+
`readDocument(format, file)` reads a YAML or JSON file and gives `{ document, problems }`, the problems as
|
|
32
|
+
`validate` gives them; a file that cannot be read or parsed throws. The sandbox port's command line has two values
|
|
33
|
+
of its own ([ADR 0147](../docs/decisions/0147-sandbox-egress-is-the-egress-proxy.md)): `copyEnds(from, to)` gives the
|
|
34
|
+
ends of `copy <from> <to>`, `{ id, inSandbox, local, into }` with a relative path below `SANDBOX_WORKSPACE`
|
|
35
|
+
(`/workspace`), or `{ problem }` when not exactly one side is `<ID>:<path>`. Each gives a problem and throws no
|
|
36
|
+
usage error: the adapter turns it into its own.
|
|
37
|
+
|
|
31
38
|
The schema files are exported at the paths in the table below, for example
|
|
32
39
|
`@opensoftware/contracts/work-item/work-item.schema.json`, along with `events/asyncapi.yaml`, `openapi/*` and `typespec/*`.
|
|
33
40
|
|
|
@@ -44,8 +51,11 @@ Each format has one schema, generated from `typespec/`, and fixtures that CONTRA
|
|
|
44
51
|
| score | `score/score.schema.json` | `Score` | Subset of Langfuse's create-score request; factory fields in `metadata`. |
|
|
45
52
|
| gate record | `gate-record/gate-record.schema.json` | `GateRecord` | gatekeeper's signed approval record (ADR 0047). |
|
|
46
53
|
| sandbox spec | `sandbox-spec/sandbox-spec.schema.json` | `SandboxSpec` | The input of a sandbox adapter's `create` (ADR 0054). Closed objects: an unknown field is an error. |
|
|
47
|
-
| factory lock | `factory-lock/factory-lock.schema.json` | `FactoryLock` | `factory.lock` next to `factory.yaml`: the registry MCP servers and the
|
|
54
|
+
| factory lock | `factory-lock/factory-lock.schema.json` | `FactoryLock` | `factory.lock` next to `factory.yaml`: the registry MCP servers, the adapters and the skills of other Git repositories that `factory plan` pinned, a skill with its commit and the hash of its files (ADR 0020, ADR 0125, ADR 0146). factory-spec writes it, the foreman reads the adapter pins and the skill pins. |
|
|
48
55
|
| access | `access/access.schema.json` | `Access` | `access.yaml` next to `factory.yaml`: the people who may sign in to the factory UI, each by email with one role, `member`, `factory-engineer` or `admin` (ADR 0134). The console reads it at each request. |
|
|
56
|
+
| skill catalog | `skill-catalog/skill-catalog.schema.json` | `SkillCatalog` | What `factory skills` prints: every skill the factory's agents use, with its needs, its agents and what each lacks, its files, the Markdown of its `SKILL.md` and its problems, and for a skill of another Git repository its URL and commit (ADR 0141, ADR 0143, ADR 0146). factory-spec writes it, the console reads it for `/skills`. |
|
|
57
|
+
| person proof | `person-proof/person-proof.schema.json` | `PersonProof` | The claims of the JSON Web Token in the header `OSF-Person` that the console signs for one call of a module API in a person's name: the issuer, the person and their role, the module as the audience, 30 seconds from its issue, and the request's method, path and the SHA-256 of its body (ADR 0151). foreman, intake and gatekeeper check it. Open: a reader ignores a claim it does not know. |
|
|
58
|
+
| person keys | `person-keys/person-keys.schema.json` | `PersonKeys` | The JSON Web Key Set of an issuer of person proofs, as the console publishes it at `/.well-known/jwks.json`: Ed25519 public keys, each with its thumbprint as `kid` (ADR 0151). Closed: a key with a private part is invalid. |
|
|
49
59
|
| events | `events/<event>/<event>.schema.json`, `events/asyncapi.yaml` | `WorkReceived`, `WorkRetryRequested`, `RunStarted`, `RunCompleted`, `RunBlocked`, `DoctorPing` … `IssueLabeled` | CloudEvents 1.0, structured JSON. |
|
|
50
60
|
|
|
51
61
|
## HTTP APIs
|
|
@@ -158,3 +168,19 @@ None. The CLI reads no environment variables.
|
|
|
158
168
|
| SCN-CTR-012 | implemented | A factory definition with an unknown effort is rejected with the allowed levels |
|
|
159
169
|
| SCN-CTR-013 | implemented | An access file with an admin and a member validates |
|
|
160
170
|
| SCN-CTR-014 | implemented | An access file with an unknown role is rejected with the roles it allows |
|
|
171
|
+
| SCN-CTR-015 | implemented | A skill catalog with a skill that one agent lacks the secret of validates |
|
|
172
|
+
| SCN-CTR-016 | implemented | A skill catalog whose skill has no body is rejected with its path |
|
|
173
|
+
| SCN-CTR-017 | implemented | readDocument gives a file's document and each problem with its path |
|
|
174
|
+
| SCN-CTR-018 | implemented | A copy into a sandbox names a path below its working folder |
|
|
175
|
+
| SCN-CTR-019 | implemented | A copy out of a sandbox keeps an absolute path |
|
|
176
|
+
| SCN-CTR-020 | implemented | A copy that names a sandbox on both sides gives its problem |
|
|
177
|
+
| SCN-CTR-021 | implemented | A factory lock with a pinned skill of another repository validates |
|
|
178
|
+
| SCN-CTR-022 | implemented | A pinned skill with a short commit is rejected with its path |
|
|
179
|
+
| SCN-CTR-023 | implemented | The pins of skills in factory.lock are no breaking change |
|
|
180
|
+
| SCN-CTR-024 | implemented | A skill catalog with a skill of another repository at its commit validates |
|
|
181
|
+
| SCN-CTR-025 | implemented | A person proof for one call of the foreman validates |
|
|
182
|
+
| SCN-CTR-026 | implemented | A person proof without claims is rejected with the path of each required claim |
|
|
183
|
+
| SCN-CTR-027 | implemented | A person proof with an unknown role, a method in lower case and a short body digest is rejected with their paths |
|
|
184
|
+
| SCN-CTR-028 | implemented | A key set with one Ed25519 public key validates |
|
|
185
|
+
| SCN-CTR-029 | implemented | A key set whose key holds its private part is rejected with its path |
|
|
186
|
+
| SCN-CTR-030 | implemented | The person proof and its key set are no breaking change |
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// osf-contracts: validate documents against the shared formats, check schema compatibility with the last release,
|
|
3
3
|
// and round-trip the fixtures through the generated clients.
|
|
4
|
-
import { readFileSync } from "node:fs";
|
|
5
|
-
import { parse } from "yaml";
|
|
6
4
|
import { breaking } from "./breaking.js";
|
|
7
5
|
import { FORMATS, formatNamed } from "./formats.js";
|
|
8
|
-
import {
|
|
6
|
+
import { readDocument } from "./index.js";
|
|
9
7
|
import { CLIENTS, roundtrip } from "./roundtrip.js";
|
|
10
8
|
const USAGE = `Usage: osf-contracts <command>
|
|
11
9
|
|
|
@@ -45,15 +43,14 @@ function validateCommand([name, file]) {
|
|
|
45
43
|
const format = name ? formatNamed(name) : undefined;
|
|
46
44
|
if (!format || !file)
|
|
47
45
|
return usage(name && !format ? `Unknown format: ${name}` : "Give a format and a file");
|
|
48
|
-
let
|
|
46
|
+
let problems;
|
|
49
47
|
try {
|
|
50
|
-
|
|
48
|
+
({ problems } = readDocument(format, file));
|
|
51
49
|
}
|
|
52
50
|
catch (error) {
|
|
53
51
|
process.stdout.write(`${file}: not readable as YAML or JSON: ${error.message}\n`);
|
|
54
52
|
return 1;
|
|
55
53
|
}
|
|
56
|
-
const problems = validate(format, document);
|
|
57
54
|
for (const problem of problems)
|
|
58
55
|
process.stdout.write(`${file} ${problem.path}: ${problem.message}\n`);
|
|
59
56
|
if (problems.length > 0)
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,kHAAkH;AAClH,6DAA6D;AAC7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/formats.js
CHANGED
|
@@ -10,6 +10,9 @@ export const FORMATS = [
|
|
|
10
10
|
format("sandbox-spec", "SandboxSpec"),
|
|
11
11
|
format("factory-lock", "FactoryLock"),
|
|
12
12
|
format("access", "Access"),
|
|
13
|
+
format("skill-catalog", "SkillCatalog"),
|
|
14
|
+
format("person-proof", "PersonProof"),
|
|
15
|
+
format("person-keys", "PersonKeys"),
|
|
13
16
|
format("events/work-received", "WorkReceived"),
|
|
14
17
|
format("events/work-retry-requested", "WorkRetryRequested"),
|
|
15
18
|
format("events/run-started", "RunStarted"),
|
package/dist/formats.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../src/formats.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAW3G,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAEjH,MAAM,CAAC,MAAM,OAAO,GAAsB;IACxC,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IACjD,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC;IAC/B,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC;IACjC,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;IAC7C,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC;IACrC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC;IACrC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC1B,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,6BAA6B,EAAE,oBAAoB,CAAC;IAC3D,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;IAC5C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;IACtC,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;IACtC,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;CAC/C,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../src/formats.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAW3G,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAEjH,MAAM,CAAC,MAAM,OAAO,GAAsB;IACxC,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;IACjD,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC;IAC/B,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC;IACjC,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;IAC7C,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC;IACrC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC;IACrC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC1B,MAAM,CAAC,eAAe,EAAE,cAAc,CAAC;IACvC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC;IACrC,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC;IACnC,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,6BAA6B,EAAE,oBAAoB,CAAC;IAC3D,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;IAC5C,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC;IAChD,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;IACtC,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAC1C,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;IACtC,MAAM,CAAC,sBAAsB,EAAE,cAAc,CAAC;CAC/C,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -294,7 +294,10 @@ export type components = {
|
|
|
294
294
|
repositories?: string[];
|
|
295
295
|
/** @description MCP servers: `registry:<name>@<version>` or `<name>@<version>`. */
|
|
296
296
|
mcp?: string[];
|
|
297
|
-
/**
|
|
297
|
+
/**
|
|
298
|
+
* @description The agent's skills: each a path to a skill folder, or a folder of another Git repository at a ref,
|
|
299
|
+
* `git+<url>#<ref>:<path>`, which `factory plan` pins in factory.lock (ADR 0146).
|
|
300
|
+
*/
|
|
298
301
|
skills?: string[];
|
|
299
302
|
secrets?: components["schemas"]["SecretReference"][];
|
|
300
303
|
/** @description Runtime of the agent. */
|
|
@@ -331,6 +334,8 @@ export type components = {
|
|
|
331
334
|
/** @description Job to run. Required with `cron`; without it an event starts the workflow. */
|
|
332
335
|
run?: components["schemas"]["Name"];
|
|
333
336
|
} & (unknown | unknown);
|
|
337
|
+
/** @description 43 characters of base64url without padding: 32 bytes, like a SHA-256 or an Ed25519 public key. */
|
|
338
|
+
Base64url32: string;
|
|
334
339
|
Benchmark: {
|
|
335
340
|
/** @description Path to the Harbor task suite. */
|
|
336
341
|
suite: string;
|
|
@@ -344,6 +349,53 @@ export type components = {
|
|
|
344
349
|
BlockedOn: "checks";
|
|
345
350
|
/** @description A path inside the bundle: relative, forward slashes, no "..". */
|
|
346
351
|
BundlePath: string;
|
|
352
|
+
/** @description One skill, also one that lint refuses: then `problems` names why. */
|
|
353
|
+
CatalogSkill: {
|
|
354
|
+
/** @description The last segment of the skill's folder. */
|
|
355
|
+
name: string;
|
|
356
|
+
/** @description The description of its front matter; null without one. */
|
|
357
|
+
description: string | null;
|
|
358
|
+
/** @description Where the skill comes from. */
|
|
359
|
+
source: components["schemas"]["CatalogSkillSource"];
|
|
360
|
+
/** @description What it needs, from the `metadata` of its front matter. */
|
|
361
|
+
needs: components["schemas"]["SkillNeeds"];
|
|
362
|
+
/** @description Each agent that uses it, sorted by name. */
|
|
363
|
+
agents: components["schemas"]["CatalogSkillAgent"][];
|
|
364
|
+
/** @description The files of its folder, by their path below it, sorted. */
|
|
365
|
+
files: string[];
|
|
366
|
+
/**
|
|
367
|
+
* @description The text of SKILL.md below the line that ends its front matter, all of it without front matter; null without a
|
|
368
|
+
* SKILL.md that is UTF-8 text.
|
|
369
|
+
*/
|
|
370
|
+
body: string | null;
|
|
371
|
+
/**
|
|
372
|
+
* @description The problems of its own files as `factory lint` prints them, relative to the folder of factory.yaml, and a folder
|
|
373
|
+
* without a SKILL.md.
|
|
374
|
+
*/
|
|
375
|
+
problems: string[];
|
|
376
|
+
};
|
|
377
|
+
/** @description An agent that uses a skill. */
|
|
378
|
+
CatalogSkillAgent: {
|
|
379
|
+
name: string;
|
|
380
|
+
/** @description The agent's reference whose variable is each secret the skill needs, by the variable. */
|
|
381
|
+
secrets: {
|
|
382
|
+
[key: string]: components["schemas"]["SecretReference"];
|
|
383
|
+
};
|
|
384
|
+
/** @description Each needed secret the agent does not declare, and each needed host its sandbox does not allow. */
|
|
385
|
+
lacks: components["schemas"]["SkillNeeds"];
|
|
386
|
+
};
|
|
387
|
+
/**
|
|
388
|
+
* @description A folder of the factory's repository, relative to the folder of factory.yaml, like "skills/release-notes"; or, for a
|
|
389
|
+
* skill of another Git repository, its folder there with the repository's URL and the commit factory.lock pins
|
|
390
|
+
* (ADR 0146).
|
|
391
|
+
*/
|
|
392
|
+
CatalogSkillSource: {
|
|
393
|
+
folder: string;
|
|
394
|
+
/** @description The URL of the other Git repository, as the entry `git+<url>#<ref>:<path>` names it. */
|
|
395
|
+
repository?: string;
|
|
396
|
+
/** @description The commit of the other repository that factory.lock pins; none while factory.lock has no pin. */
|
|
397
|
+
commit?: string;
|
|
398
|
+
};
|
|
347
399
|
/** @description The name of a check on the forge: a commit status context. */
|
|
348
400
|
CheckName: string;
|
|
349
401
|
/**
|
|
@@ -487,6 +539,14 @@ export type components = {
|
|
|
487
539
|
[key: string]: components["schemas"]["FactoryLockAdapterPin"];
|
|
488
540
|
};
|
|
489
541
|
};
|
|
542
|
+
/**
|
|
543
|
+
* @description The skills of other Git repositories that `factory plan` pinned, by the skill's name (ADR 0146). A pin counts only
|
|
544
|
+
* while its `source` is the entry factory.yaml declares; the foreman and `factory render` fetch its commit and check
|
|
545
|
+
* its hash.
|
|
546
|
+
*/
|
|
547
|
+
skills?: {
|
|
548
|
+
[key: string]: components["schemas"]["FactoryLockSkillPin"];
|
|
549
|
+
};
|
|
490
550
|
};
|
|
491
551
|
/** @description One adapter's npm package `@opensoftware/<port>-<name>` at the newest version inside its range. */
|
|
492
552
|
FactoryLockAdapterPin: {
|
|
@@ -510,6 +570,15 @@ export type components = {
|
|
|
510
570
|
url: string;
|
|
511
571
|
};
|
|
512
572
|
};
|
|
573
|
+
/** @description One skill of another Git repository at the commit its ref had when `factory plan` pinned it. */
|
|
574
|
+
FactoryLockSkillPin: {
|
|
575
|
+
/** @description The entry of `skills` in factory.yaml that the pin was resolved from, `git+<url>#<ref>:<path>`. */
|
|
576
|
+
source: string;
|
|
577
|
+
/** @description The full commit, 40 hexadecimal characters, or 64 in a repository of SHA-256. */
|
|
578
|
+
commit: string;
|
|
579
|
+
/** @description The hash of the skill folder's files in the form of Go's modules: "h1:" and the base64 of a SHA-256. */
|
|
580
|
+
hash: string;
|
|
581
|
+
};
|
|
513
582
|
/**
|
|
514
583
|
* @description The version of a format inside its documents. Only 1 exists; a new major version of a format adds the next.
|
|
515
584
|
* @constant
|
|
@@ -760,6 +829,55 @@ export type components = {
|
|
|
760
829
|
/** @description ID in the source system. */
|
|
761
830
|
externalId?: string;
|
|
762
831
|
};
|
|
832
|
+
/** @description One Ed25519 public key. Closed: a key with its private part `d` or any other member is invalid. */
|
|
833
|
+
PersonKey: {
|
|
834
|
+
/** @constant */
|
|
835
|
+
kty: "OKP";
|
|
836
|
+
/** @constant */
|
|
837
|
+
crv: "Ed25519";
|
|
838
|
+
/** @constant */
|
|
839
|
+
alg: "Ed25519";
|
|
840
|
+
/** @constant */
|
|
841
|
+
use: "sig";
|
|
842
|
+
/** @description The key's JWK thumbprint (RFC 7638) with SHA-256; a proof names it in its `kid`. */
|
|
843
|
+
kid: components["schemas"]["Base64url32"];
|
|
844
|
+
/** @description The public key. */
|
|
845
|
+
x: components["schemas"]["Base64url32"];
|
|
846
|
+
};
|
|
847
|
+
/**
|
|
848
|
+
* @description The public keys of an issuer of person proofs (ADR 0151): a JSON Web Key Set (RFC 7517), as the console publishes it
|
|
849
|
+
* at `/.well-known/jwks.json`. The first key of the issuer's setting signs; every key here verifies.
|
|
850
|
+
*/
|
|
851
|
+
PersonKeys: {
|
|
852
|
+
keys: components["schemas"]["PersonKey"][];
|
|
853
|
+
};
|
|
854
|
+
/**
|
|
855
|
+
* @description The claims of a person proof (ADR 0151): the JSON Web Token that the console signs for one call of a module API in
|
|
856
|
+
* the name of a person, sent in the header `OSF-Person`, signed with `alg` "Ed25519" and `typ` "osf-person+jwt". It is
|
|
857
|
+
* bound to one module, one request and 30 seconds. Open: a module ignores a claim it does not know.
|
|
858
|
+
*/
|
|
859
|
+
PersonProof: {
|
|
860
|
+
/** @description The issuer: "console" for the console, or the name a team gives its own tool in the modules' setting. */
|
|
861
|
+
iss: components["schemas"]["Name"];
|
|
862
|
+
/** @description The person, as the module records the actor's `id`: an email in lower case, or the sign-in proxy's value. */
|
|
863
|
+
sub: string;
|
|
864
|
+
/** @description The name to show, recorded as the actor's `displayName`. */
|
|
865
|
+
name?: string;
|
|
866
|
+
/** @description The person's role from the access file at the time of the call. */
|
|
867
|
+
role: components["schemas"]["AccessRole"];
|
|
868
|
+
/** @description The module the call goes to: "foreman", "intake" or "gatekeeper". */
|
|
869
|
+
aud: components["schemas"]["Name"];
|
|
870
|
+
/** @description When it was signed, in seconds since 1970-01-01T00:00:00Z. */
|
|
871
|
+
iat: number;
|
|
872
|
+
/** @description When it ends, in seconds since 1970-01-01T00:00:00Z; at most 60 seconds after `iat`. */
|
|
873
|
+
exp: number;
|
|
874
|
+
/** @description The request's method in upper case. */
|
|
875
|
+
method: string;
|
|
876
|
+
/** @description The request's path as sent in the request line, without the query. */
|
|
877
|
+
path: string;
|
|
878
|
+
/** @description The SHA-256 of the request's body bytes as sent, in base64url without padding. */
|
|
879
|
+
bodyDigest: components["schemas"]["Base64url32"];
|
|
880
|
+
};
|
|
763
881
|
/** @description forge adapters: a pull request was merged or closed without a merge. */
|
|
764
882
|
PrClosed: {
|
|
765
883
|
/** @constant */
|
|
@@ -1304,6 +1422,23 @@ export type components = {
|
|
|
1304
1422
|
/** @description A reference to a secret, resolved at the egress proxy, never in the sandbox: "ref:<provider>/<name>". */
|
|
1305
1423
|
SecretReference: string;
|
|
1306
1424
|
Sha256: string;
|
|
1425
|
+
/**
|
|
1426
|
+
* @description What `factory skills` of factory-spec prints (ADR 0141, ADR 0143): every skill the factory's agents use, read with
|
|
1427
|
+
* the rules of `factory lint` (ADR 0140), sorted by name. The console reads it for its pages `/skills` and
|
|
1428
|
+
* `/skills/<name>`, so it never parses a SKILL.md itself.
|
|
1429
|
+
*/
|
|
1430
|
+
SkillCatalog: {
|
|
1431
|
+
skills: components["schemas"]["CatalogSkill"][];
|
|
1432
|
+
};
|
|
1433
|
+
/** @description A host as an entry of `sandbox.egress`, like "api.linear.app". */
|
|
1434
|
+
SkillHost: string;
|
|
1435
|
+
/** @description The secrets a skill needs, by the variable that holds each in a sandbox, and the hosts it reaches (ADR 0140). */
|
|
1436
|
+
SkillNeeds: {
|
|
1437
|
+
secrets: components["schemas"]["SkillSecretName"][];
|
|
1438
|
+
hosts: components["schemas"]["SkillHost"][];
|
|
1439
|
+
};
|
|
1440
|
+
/** @description The variable of a secret in a sandbox (ADR 0068), like "LINEAR_TOKEN". */
|
|
1441
|
+
SkillSecretName: string;
|
|
1307
1442
|
Stage: {
|
|
1308
1443
|
stage: components["schemas"]["Name"];
|
|
1309
1444
|
/** @description Agent that runs the stage. Defaults to the agent with the stage's name. */
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { diff as breakingChanges, type Schema } from "./breaking.ts";
|
|
|
4
4
|
export { FORMATS, type Format, formatNamed } from "./formats.ts";
|
|
5
5
|
export type { components, paths } from "./generated/types.ts";
|
|
6
6
|
export { type AttributeValue, type RunSpan, runSpans, type SpanAttributes } from "./run-record.ts";
|
|
7
|
+
export { type CopyEnds, copyEnds, SANDBOX_WORKSPACE } from "./sandbox.ts";
|
|
7
8
|
type Schemas = components["schemas"];
|
|
8
9
|
export type FactoryDefinition = Schemas["FactoryDefinition"];
|
|
9
10
|
export type WorkItem = Schemas["WorkItem"];
|
|
@@ -45,6 +46,13 @@ export type FactoryLock = Schemas["FactoryLock"];
|
|
|
45
46
|
export type Access = Schemas["Access"];
|
|
46
47
|
export type AccessPerson = Schemas["AccessPerson"];
|
|
47
48
|
export type AccessRole = Schemas["AccessRole"];
|
|
49
|
+
export type SkillCatalog = Schemas["SkillCatalog"];
|
|
50
|
+
export type CatalogSkill = Schemas["CatalogSkill"];
|
|
51
|
+
export type CatalogSkillAgent = Schemas["CatalogSkillAgent"];
|
|
52
|
+
export type SkillNeeds = Schemas["SkillNeeds"];
|
|
53
|
+
export type PersonProof = Schemas["PersonProof"];
|
|
54
|
+
export type PersonKeys = Schemas["PersonKeys"];
|
|
55
|
+
export type PersonKey = Schemas["PersonKey"];
|
|
48
56
|
export type Health = Schemas["Health"];
|
|
49
57
|
export type HealthCheck = Schemas["HealthCheck"];
|
|
50
58
|
/** One reason a document does not match its format. `path` is a JSON Pointer into the document. */
|
|
@@ -56,5 +64,13 @@ export interface Problem {
|
|
|
56
64
|
export declare function schemaOf(format: Format | string): Record<string, unknown>;
|
|
57
65
|
/** Every problem of the document; empty when it matches the format. */
|
|
58
66
|
export declare function validate(format: Format | string, document: unknown): Problem[];
|
|
67
|
+
/**
|
|
68
|
+
* The document of a YAML or JSON file and every problem of it against the format; JSON is YAML. A file that cannot
|
|
69
|
+
* be read or parsed throws.
|
|
70
|
+
*/
|
|
71
|
+
export declare function readDocument<T = unknown>(format: Format | string, file: string): {
|
|
72
|
+
document: T;
|
|
73
|
+
problems: Problem[];
|
|
74
|
+
};
|
|
59
75
|
/** True when the document matches the format, with its type narrowed. */
|
|
60
76
|
export declare function isValid<T>(format: Format | string, document: unknown): document is T;
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,12 @@ import { dirname, join } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import Ajv2020, {} from "ajv/dist/2020.js";
|
|
6
6
|
import addFormats from "ajv-formats";
|
|
7
|
+
import { parse } from "yaml";
|
|
7
8
|
import { formatNamed } from "./formats.js";
|
|
8
9
|
export { diff as breakingChanges } from "./breaking.js";
|
|
9
10
|
export { FORMATS, formatNamed } from "./formats.js";
|
|
10
11
|
export { runSpans } from "./run-record.js";
|
|
12
|
+
export { copyEnds, SANDBOX_WORKSPACE } from "./sandbox.js";
|
|
11
13
|
/** The package root: dist/ and src/ both sit one level below it, next to the schema folders. */
|
|
12
14
|
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
13
15
|
const validators = new Map();
|
|
@@ -31,6 +33,14 @@ export function validate(format, document) {
|
|
|
31
33
|
}
|
|
32
34
|
return check(document) ? [] : problems(check.errors ?? []);
|
|
33
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* The document of a YAML or JSON file and every problem of it against the format; JSON is YAML. A file that cannot
|
|
38
|
+
* be read or parsed throws.
|
|
39
|
+
*/
|
|
40
|
+
export function readDocument(format, file) {
|
|
41
|
+
const document = parse(readFileSync(file, "utf8"));
|
|
42
|
+
return { document, problems: validate(format, document) };
|
|
43
|
+
}
|
|
34
44
|
/** True when the document matches the format, with its type narrowed. */
|
|
35
45
|
export function isValid(format, document) {
|
|
36
46
|
return validate(format, document).length === 0;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,OAAO,EAAE,EAA2C,MAAM,kBAAkB,CAAC;AACpF,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,EAAe,WAAW,EAAE,MAAM,cAAc,CAAC;AAGxD,OAAO,EAAE,IAAI,IAAI,eAAe,EAAe,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,OAAO,EAAe,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjE,OAAO,EAAqC,QAAQ,EAAuB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The working folder of every command in a sandbox. */
|
|
2
|
+
export declare const SANDBOX_WORKSPACE = "/workspace";
|
|
3
|
+
/** The two ends of a copy. */
|
|
4
|
+
export interface CopyEnds {
|
|
5
|
+
/** The sandbox's ID. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** The absolute path in the sandbox; a relative path is below the working folder. */
|
|
8
|
+
inSandbox: string;
|
|
9
|
+
/** The path on the client's side, as given. */
|
|
10
|
+
local: string;
|
|
11
|
+
/** Whether the copy goes into the sandbox. */
|
|
12
|
+
into: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** The ends of `copy <from> <to>`, or the problem when not exactly one side names a sandbox. */
|
|
15
|
+
export declare function copyEnds(from: string | undefined, to: string | undefined): CopyEnds | {
|
|
16
|
+
problem: string;
|
|
17
|
+
};
|
package/dist/sandbox.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// The sandbox port's command line as its adapters and clients share it (ADR 0054, ADR 0147): the working folder of
|
|
2
|
+
// every sandbox, and the two ends of `copy <from> <to>`, whose sandbox side is `<ID>:<path>`.
|
|
3
|
+
import { posix } from "node:path";
|
|
4
|
+
/** The working folder of every command in a sandbox. */
|
|
5
|
+
export const SANDBOX_WORKSPACE = "/workspace";
|
|
6
|
+
const IN_SANDBOX = /^([0-9a-f]{12}):(.+)$/;
|
|
7
|
+
/** The ends of `copy <from> <to>`, or the problem when not exactly one side names a sandbox. */
|
|
8
|
+
export function copyEnds(from, to) {
|
|
9
|
+
if (!from || !to)
|
|
10
|
+
return { problem: "name what to copy and where to, like copy notes.md <ID>:notes.md" };
|
|
11
|
+
const source = IN_SANDBOX.exec(from);
|
|
12
|
+
const target = IN_SANDBOX.exec(to);
|
|
13
|
+
if (Boolean(source) === Boolean(target))
|
|
14
|
+
return { problem: "name the sandbox on one side only, as <ID>:<path>" };
|
|
15
|
+
const [, id, path] = (source ?? target);
|
|
16
|
+
return {
|
|
17
|
+
id: id,
|
|
18
|
+
inSandbox: posix.resolve(SANDBOX_WORKSPACE, path),
|
|
19
|
+
local: source ? to : from,
|
|
20
|
+
into: !source,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,8FAA8F;AAC9F,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElC,wDAAwD;AACxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAc9C,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAE3C,gGAAgG;AAChG,MAAM,UAAU,QAAQ,CAAC,IAAwB,EAAE,EAAsB;IACvE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,EAAE,kEAAkE,EAAE,CAAC;IACzG,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnC,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC;IACjH,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAoB,CAAC;IAC3D,OAAO;QACL,EAAE,EAAE,EAAY;QAChB,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAc,CAAC;QAC3D,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;QACzB,IAAI,EAAE,CAAC,MAAM;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
"items": {
|
|
187
187
|
"type": "string"
|
|
188
188
|
},
|
|
189
|
-
"description": "
|
|
189
|
+
"description": "The agent's skills: each a path to a skill folder, or a folder of another Git repository at a ref,\n`git+<url>#<ref>:<path>`, which `factory plan` pins in factory.lock (ADR 0146)."
|
|
190
190
|
},
|
|
191
191
|
"secrets": {
|
|
192
192
|
"type": "array",
|
|
@@ -101,6 +101,38 @@
|
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
103
|
"description": "The adapters under `providers` that `factory plan --adapters` pinned, per port and adapter name (ADR 0125). A pin\ncounts only while its `range` is the range factory.yaml declares."
|
|
104
|
+
},
|
|
105
|
+
"skills": {
|
|
106
|
+
"type": "object",
|
|
107
|
+
"properties": {},
|
|
108
|
+
"unevaluatedProperties": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"properties": {
|
|
111
|
+
"source": {
|
|
112
|
+
"type": "string",
|
|
113
|
+
"pattern": "^git\\+.+#[^:]+:.+$",
|
|
114
|
+
"description": "The entry of `skills` in factory.yaml that the pin was resolved from, `git+<url>#<ref>:<path>`."
|
|
115
|
+
},
|
|
116
|
+
"commit": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$",
|
|
119
|
+
"description": "The full commit, 40 hexadecimal characters, or 64 in a repository of SHA-256."
|
|
120
|
+
},
|
|
121
|
+
"hash": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"pattern": "^h1:[A-Za-z0-9+/]{43}=$",
|
|
124
|
+
"description": "The hash of the skill folder's files in the form of Go's modules: \"h1:\" and the base64 of a SHA-256."
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"required": [
|
|
128
|
+
"source",
|
|
129
|
+
"commit",
|
|
130
|
+
"hash"
|
|
131
|
+
],
|
|
132
|
+
"description": "One skill of another Git repository at the commit its ref had when `factory plan` pinned it.",
|
|
133
|
+
"additionalProperties": false
|
|
134
|
+
},
|
|
135
|
+
"description": "The skills of other Git repositories that `factory plan` pinned, by the skill's name (ADR 0146). A pin counts only\nwhile its `source` is the entry factory.yaml declares; the foreman and `factory render` fetch its commit and check\nits hash."
|
|
104
136
|
}
|
|
105
137
|
},
|
|
106
138
|
"required": [
|