@sdd-method/author-cli 0.6.0 → 0.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.
@@ -46,13 +46,18 @@ const KIND_SPECS = [
46
46
  // and it stayed invisible for the same reason: an unreachable value is emitted
47
47
  // for nothing and so never complains.
48
48
  //
49
- // NOT zero-delta, unlike spicedb: the reverse estate already holds 7 `.graphql`
50
- // files under the conventional `docs/domains/<domain>/contracts/graphql/` layout
51
- // (vehicle 5, applications 2), invisible to the catalogue until now. An author
49
+ // NOT zero-delta, unlike spicedb: an estate already held `.graphql` files under
50
+ // the conventional `docs/domains/<domain>/contracts/graphql/` layout, invisible
51
+ // to the catalogue until then. An author
52
52
  // whose GraphQL surface could not be keyed documented the wall in their own
53
53
  // manifest — naming the schema lines that blocked them — and wrote the only
54
54
  // token left in `contracts.status`.
55
55
  { subdir: "graphql", extensions: [".graphql", ".graphqls"], kind: "graphql" },
56
+ // `cli` — a command-line interface's command manifest (schema 4.1.0). A command-line tool often serves no
57
+ // REST, RPC, event or authorization contract, so without this kind its behaviour baselines had nothing to
58
+ // name as their surface (M-ADR 0222 §4.4). Reachable from every path at once, unlike graphql above: discovered here, mapped from a
59
+ // traceability manifest's `cli:` block (DECLARED_KINDS), loaded (CONTRACT_LIST_KEYS) and keyed by repo-config.
60
+ { subdir: "cli", extensions: [".yaml", ".yml"], kind: "cli" },
56
61
  ];
57
62
  export async function buildContracts(inputs) {
58
63
  const rows = [];
@@ -319,6 +324,7 @@ const DECLARED_KINDS = {
319
324
  avro: "event",
320
325
  spicedb: "authz",
321
326
  graphql: "graphql",
327
+ cli: "cli",
322
328
  };
323
329
  export function buildDeclaredExternalContracts(inputs) {
324
330
  const rows = [];
@@ -33,16 +33,17 @@ const LOC_REPORT_REL = join("docs", "platform", "reference", "loc-report.csv");
33
33
  const REPOS_DIR_REL = "repos";
34
34
  const REVERSE_METADATA_BASENAME = "reverse-metadata.yaml";
35
35
  // The contract kinds a repo-config `contracts:` block keys, under `contracts/<kind>/`. The sdd-index reader
36
- // accepts the same four; `spicedb` (an `authz` contract) was once missing here, and zod strips an unknown key,
37
- // so a declared `.zed` schema vanished without a finding. GraphQL is not keyed in repo-config: that is its own
38
- // question, on this schema.
39
- export const REPO_CONFIG_CONTRACT_KINDS = ["openapi", "proto", "avro", "spicedb"];
36
+ // accepts the same five; `spicedb` (an `authz` contract) was once missing here, and zod strips an unknown key,
37
+ // so a declared `.zed` schema vanished without a finding. `cli` (schema 4.1.0) declares the command manifest a
38
+ // command-line repository serves. GraphQL is not keyed in repo-config: that is its own question, on this schema.
39
+ export const REPO_CONFIG_CONTRACT_KINDS = ["openapi", "proto", "avro", "spicedb", "cli"];
40
40
  const ContractsBlockSchema = z
41
41
  .object({
42
42
  openapi: z.array(z.string()).optional(),
43
43
  proto: z.array(z.string()).optional(),
44
44
  avro: z.array(z.string()).optional(),
45
45
  spicedb: z.array(z.string()).optional(),
46
+ cli: z.array(z.string()).optional(),
46
47
  })
47
48
  .optional();
48
49
  const EventEntrySchema = z.object({
@@ -7,7 +7,7 @@
7
7
  # Emitted by sdd-cli's YAML emitter with no line folding; the three header scalars are quoted for the
8
8
  # textual readers downstream. The one deliberate difference from the authored form is schema_status:
9
9
  # the authored form says canonical; a projection never does.
10
- schema_version: "4.0.0"
10
+ schema_version: "4.1.0"
11
11
  schema_owner: "sdd-method"
12
12
  schema_status: "generated"
13
13
  enums:
@@ -361,6 +361,7 @@ enums:
361
361
  - value: graphql
362
362
  - value: rpc
363
363
  - value: authz
364
+ - value: cli
364
365
  description: Contract kind. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
365
366
  contract_status:
366
367
  values:
@@ -1552,7 +1553,7 @@ catalogues:
1552
1553
  - name: kind
1553
1554
  type: string
1554
1555
  nullable: false
1555
- description: rest | graphql | rpc | event | authz. rpc covers Proto/gRPC; event covers Avro schemas; authz covers authorization/policy schemas (SpiceDB .zed and equivalents), added because an adopter contract agreement gate certified .zed schemas as contracts while no kind could represent them.
1556
+ description: rest | graphql | rpc | event | authz | cli. rpc covers Proto/gRPC; event covers Avro schemas; authz covers authorization/policy schemas (SpiceDB .zed and equivalents), added because an adopter contract agreement gate certified .zed schemas as contracts while no kind could represent them; cli covers a command-line interface's command manifest (its commands, options and exit codes), added at 4.1.0 because a command-line tool often serves no REST, RPC, event or authorization contract, so its behaviour baselines had nothing to name as their surface.
1556
1557
  - name: version
1557
1558
  type: string
1558
1559
  nullable: true
@@ -2,7 +2,7 @@
2
2
  // M-ADR 0203 §4.4, the cut's acid test.
3
3
  //
4
4
  // From 3.0.0 a contract id carries its KIND component: `{domain}-{stem}-{kind}`
5
- // (kind ∈ rest | graphql | rpc | event | authz). The kindless 2.x form made one
5
+ // (kind ∈ rest | graphql | rpc | event | authz | cli). The kindless 2.x form made one
6
6
  // measured collision class unrepresentable: a service published as two contract
7
7
  // families (`calendar-service.yaml` + `calendar_service.proto`) minted one id,
8
8
  // costing a live estate one row and two edges permanently, and mislabelling
@@ -47,6 +47,7 @@ export const CONTRACT_LIST_KEYS = [
47
47
  "avro",
48
48
  "spicedb",
49
49
  "graphql",
50
+ "cli",
50
51
  ];
51
52
  /**
52
53
  * Every contract path a contracts block declares, across all kinds and both
@@ -279,6 +280,7 @@ function extractContracts(raw) {
279
280
  const avro = arr("avro");
280
281
  const spicedb = arr("spicedb");
281
282
  const graphql = arr("graphql");
283
+ const cli = arr("cli");
282
284
  // `provenance` (3.5.0) MUST be extracted here or the builder that reads it
283
285
  // sees nothing — this function reconstructs the block key-by-key rather than
284
286
  // passing the parsed object through, which is precisely the shape the
@@ -295,6 +297,7 @@ function extractContracts(raw) {
295
297
  ...(avro ? { avro } : {}),
296
298
  ...(spicedb ? { spicedb } : {}),
297
299
  ...(graphql ? { graphql } : {}),
300
+ ...(cli ? { cli } : {}),
298
301
  ...(provenance ? { provenance } : {}),
299
302
  };
300
303
  }
@@ -116,7 +116,7 @@ async function collectReferences(repo) {
116
116
  const block = m.traceability.contracts;
117
117
  if (!block)
118
118
  continue;
119
- for (const list of [block.openapi, block.proto, block.avro, block.spicedb]) {
119
+ for (const list of [block.openapi, block.proto, block.avro, block.spicedb, block.graphql, block.cli]) {
120
120
  if (!Array.isArray(list))
121
121
  continue;
122
122
  for (const entry of list) {
@@ -186,15 +186,21 @@ async function sourceCoordinate(abs) {
186
186
  return "unversioned";
187
187
  }
188
188
  }
189
- function inferKind(ref) {
189
+ export function inferKind(ref) {
190
190
  if (ref.endsWith(".avsc"))
191
191
  return "event";
192
192
  if (ref.endsWith(".proto"))
193
193
  return "rpc";
194
194
  if (ref.endsWith(".zed"))
195
195
  return "authz";
196
+ if (/\.graphqls?$/.test(ref))
197
+ return "graphql";
196
198
  if (/openapi/.test(ref) && /\.(ya?ml|json)$/.test(ref))
197
199
  return "rest";
200
+ // A command manifest lives under a `cli/` contracts folder. Tested after rest, so an OpenAPI file in a
201
+ // repository whose own name ends in -cli stays rest.
202
+ if (/(^|\/)cli\/.*\.ya?ml$/.test(ref))
203
+ return "cli";
198
204
  return undefined;
199
205
  }
200
206
  async function readManifest(abs) {
@@ -44,7 +44,7 @@ async function readRepoConfigFor(sddRoot, manifestAbsPath) {
44
44
  path: manifestAbsPath,
45
45
  aggregates: [],
46
46
  internalDependencies: [],
47
- contracts: { openapi: [], proto: [], avro: [], spicedb: [], graphql: [] },
47
+ contracts: { openapi: [], proto: [], avro: [], spicedb: [], graphql: [], cli: [] },
48
48
  };
49
49
  if (!(await fileExists(manifestAbsPath)))
50
50
  return empty;
@@ -62,6 +62,7 @@ function legacyShape(node, sourcePath) {
62
62
  proto: [],
63
63
  avro: [],
64
64
  spicedb: [],
65
+ cli: [],
65
66
  };
66
67
  for (const ref of node.contracts)
67
68
  byKind[ref.kind].push(ref.path);
@@ -16,6 +16,7 @@ const CONTRACT_KINDS = [
16
16
  "proto",
17
17
  "avro",
18
18
  "spicedb",
19
+ "cli",
19
20
  ];
20
21
  export function readAllRepoConfigs(reader) {
21
22
  const services = [];
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "0.7.0",
3
- "built_against_sdd_cli": "2.1.0"
2
+ "version": "0.8.0",
3
+ "built_against_sdd_cli": "2.2.0"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "2.1.0",
3
- "built_against_sdd_cli": "2.1.0"
2
+ "version": "2.2.0",
3
+ "built_against_sdd_cli": "2.2.0"
4
4
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sdd-method/author-cli",
3
- "version": "0.6.0",
4
- "sddCliVersion": "2.1.0",
3
+ "version": "0.7.0",
4
+ "sddCliVersion": "2.2.0",
5
5
  "description": "Re-author one SDD's content — scaffold, plan, contracts, conformance, api-surface, snapshots, briefings, catalogue check — plus every read-only verify verb. Ships only the code those verbs reach; it cannot sync the baseline or rebuild the catalogues. Maintenance is in @sdd-method/maintain-cli, administration in @sdd-method/sdd-cli.",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",