@cleocode/contracts 2026.6.6 → 2026.6.7
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/dist/__tests__/operation-def.test.js.map +1 -1
- package/dist/dispatch/operation-def.d.ts +42 -0
- package/dist/dispatch/operation-def.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/provider-profile.d.ts +54 -0
- package/dist/llm/provider-profile.d.ts.map +1 -1
- package/dist/operations/__tests__/output-contracts.test.d.ts +16 -0
- package/dist/operations/__tests__/output-contracts.test.d.ts.map +1 -0
- package/dist/operations/__tests__/output-contracts.test.js +103 -0
- package/dist/operations/__tests__/output-contracts.test.js.map +1 -0
- package/dist/operations/output-contract.d.ts +127 -0
- package/dist/operations/output-contract.d.ts.map +1 -0
- package/dist/operations/output-contract.js +41 -0
- package/dist/operations/output-contract.js.map +1 -0
- package/dist/operations/output-contracts-data.d.ts +35 -0
- package/dist/operations/output-contracts-data.d.ts.map +1 -0
- package/dist/operations/output-contracts-data.js +328 -0
- package/dist/operations/output-contracts-data.js.map +1 -0
- package/dist/operations/tasks.d.ts +14 -4
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/operation-def.test.ts +5 -0
- package/src/dispatch/operation-def.ts +44 -0
- package/src/index.ts +9 -0
- package/src/llm/provider-profile.ts +59 -0
- package/src/operations/__tests__/output-contracts.test.ts +125 -0
- package/src/operations/output-contract.ts +140 -0
- package/src/operations/output-contracts-data.ts +356 -0
- package/src/operations/tasks.ts +14 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/operations/tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/operations/tasks.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/contracts",
|
|
3
|
-
"version": "2026.6.
|
|
3
|
+
"version": "2026.6.7",
|
|
4
4
|
"description": "Domain types, interfaces, and contracts for the CLEO ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
"dependencies": {
|
|
183
183
|
"zod": "^4.3.6",
|
|
184
184
|
"zod-to-json-schema": "^3.25.2",
|
|
185
|
-
"@cleocode/lafs": "2026.6.
|
|
185
|
+
"@cleocode/lafs": "2026.6.7"
|
|
186
186
|
},
|
|
187
187
|
"scripts": {
|
|
188
188
|
"build": "tsc -b --force && node scripts/copy-assets.mjs && node scripts/emit-schemas.mjs",
|
|
@@ -21,6 +21,8 @@ import { describe, expect, it } from 'vitest';
|
|
|
21
21
|
import type { CanonicalDomain, Gateway, Tier } from '../dispatch/identity.js';
|
|
22
22
|
import { CANONICAL_DOMAINS } from '../dispatch/identity.js';
|
|
23
23
|
import type { OperationDef, Resolution } from '../dispatch/operation-def.js';
|
|
24
|
+
import type { OperationInputContract } from '../operations/input-contract.js';
|
|
25
|
+
import type { OperationOutputContract } from '../operations/output-contract.js';
|
|
24
26
|
import type { ParamDef } from '../operations/params.js';
|
|
25
27
|
|
|
26
28
|
// ─── Compile-time structural-equality helpers ───────────────────────
|
|
@@ -66,6 +68,9 @@ type _OperationDefShape = {
|
|
|
66
68
|
requiredParams: string[];
|
|
67
69
|
params?: ParamDef[];
|
|
68
70
|
mcpExposed?: boolean;
|
|
71
|
+
// T11692 (DHQ-033 / DHQ-057) — optional schema-first input/output contracts.
|
|
72
|
+
inputSchema?: OperationInputContract<unknown>;
|
|
73
|
+
outputSchema?: OperationOutputContract;
|
|
69
74
|
};
|
|
70
75
|
|
|
71
76
|
type _AssertOperationDefPinned = AssertEquals1<Equals<OperationDef, _OperationDefShape>>;
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
* @since SG-ARCH-SOLID Saga T9831 · E-CONTRACTS-FOUNDATION T9832 · T9954 (Phase 0b)
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
+
import type { OperationInputContract } from '../operations/input-contract.js';
|
|
32
|
+
import type { OperationOutputContract } from '../operations/output-contract.js';
|
|
31
33
|
import type { ParamDef } from '../operations/params.js';
|
|
32
34
|
import type { CanonicalDomain, Gateway, Tier } from './identity.js';
|
|
33
35
|
|
|
@@ -92,6 +94,48 @@ export interface OperationDef {
|
|
|
92
94
|
* @task T11448
|
|
93
95
|
*/
|
|
94
96
|
mcpExposed?: boolean;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Schema-first INPUT contract for this operation (DHQ-033 / T11692).
|
|
100
|
+
*
|
|
101
|
+
* Declares the accepted request payload shape as a JSON Schema draft-07
|
|
102
|
+
* document with worked examples. When present, the dispatch/CLI layer
|
|
103
|
+
* validates the incoming payload against `inputSchema.schema` and rejects
|
|
104
|
+
* unknown keys LOUDLY (the schemas set `additionalProperties: false`), so a
|
|
105
|
+
* typo'd or unsupported field — e.g. passing `relates` to `tasks.add-batch`,
|
|
106
|
+
* which only accepts `depends` — fails fast with a typed {@link ValidationError}
|
|
107
|
+
* instead of being silently dropped.
|
|
108
|
+
*
|
|
109
|
+
* **Optional / incremental**: absent means "no declared input contract yet".
|
|
110
|
+
* The canonical SSoT registry of contracts is keyed by `<domain>.<operation>`
|
|
111
|
+
* (INPUT_CONTRACTS in core); this inline field lets a definition carry its
|
|
112
|
+
* own contract and is resolved by the SDK `describeOperation` when set.
|
|
113
|
+
*
|
|
114
|
+
* @see OperationInputContract
|
|
115
|
+
* @task T11692 — DHQ-033 input shape SSoT
|
|
116
|
+
*/
|
|
117
|
+
inputSchema?: OperationInputContract<unknown>;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Schema-first OUTPUT contract for this operation (DHQ-057 / T11692).
|
|
121
|
+
*
|
|
122
|
+
* Declares the shape of the LAFS envelope's `data` payload as a JSON Schema
|
|
123
|
+
* draft-07 document, PLUS the curated list of valid `--field` JSON pointers.
|
|
124
|
+
* This is the SSoT that lets an agent predict the result shape instead of
|
|
125
|
+
* hand-sniffing it per verb — e.g. it encodes that `tasks.show` returns the
|
|
126
|
+
* task under `task`, so the correct pointer is `/data/task/title` and NOT
|
|
127
|
+
* `/data/title` (the latter is the exact `E_FIELD_NOT_FOUND` failure this
|
|
128
|
+
* field exists to prevent).
|
|
129
|
+
*
|
|
130
|
+
* **Optional / incremental**: absent means "no declared output contract yet".
|
|
131
|
+
* The canonical SSoT registry is keyed by `<domain>.<operation>`
|
|
132
|
+
* (OUTPUT_CONTRACTS in contracts); this inline field lets a definition carry
|
|
133
|
+
* its own contract and is resolved by the SDK `describeOperation` when set.
|
|
134
|
+
*
|
|
135
|
+
* @see OperationOutputContract
|
|
136
|
+
* @task T11692 — DHQ-057 output shape SSoT
|
|
137
|
+
*/
|
|
138
|
+
outputSchema?: OperationOutputContract;
|
|
95
139
|
}
|
|
96
140
|
|
|
97
141
|
// ── Resolution ───────────────────────────────────────────────────────
|
package/src/index.ts
CHANGED
|
@@ -1318,6 +1318,15 @@ export type {
|
|
|
1318
1318
|
OrchestrateReportGroup,
|
|
1319
1319
|
OrchestrateReportParams,
|
|
1320
1320
|
} from './operations/orchestrate.js';
|
|
1321
|
+
// === Operation Output Contracts (T11692 / DHQ-057 — per-op result shape SSoT) ===
|
|
1322
|
+
// OUTPUT-side mirror of the input contracts. Surfaces the LAFS envelope `data`
|
|
1323
|
+
// shape + valid --field JSON pointers so agents stop guessing (e.g. the real
|
|
1324
|
+
// pointer is /data/task/title, not /data/title).
|
|
1325
|
+
export type {
|
|
1326
|
+
OperationOutputContract,
|
|
1327
|
+
OperationOutputContractRegistry,
|
|
1328
|
+
} from './operations/output-contract.js';
|
|
1329
|
+
export { OUTPUT_CONTRACTS } from './operations/output-contracts-data.js';
|
|
1321
1330
|
// ParamDef contract — re-exported at top level (SSoT for all operation param descriptors)
|
|
1322
1331
|
export type {
|
|
1323
1332
|
CittyArgDef,
|
|
@@ -14,6 +14,17 @@ import type { ModelTransport, StoredAuthTypeWire } from '../operations/llm.js';
|
|
|
14
14
|
import type { TransportMessage, TransportTool } from './normalized-response.js';
|
|
15
15
|
import type { ProviderOAuthConfig } from './oauth.js';
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Coarse provider capability tier used by the system-of-use router (E9).
|
|
19
|
+
*
|
|
20
|
+
* Ordered most→least capable: `frontier` (flagship reasoning), `standard`
|
|
21
|
+
* (general-purpose), `fast` (cheap/low-latency aux), `local` (on-device, e.g.
|
|
22
|
+
* Ollama). Sourced from the models.dev catalog (E8) when generated.
|
|
23
|
+
*
|
|
24
|
+
* @task T11756
|
|
25
|
+
*/
|
|
26
|
+
export type ProviderTier = 'frontier' | 'standard' | 'fast' | 'local';
|
|
27
|
+
|
|
17
28
|
/**
|
|
18
29
|
* Describes a single LLM provider — its auth capabilities, base URL,
|
|
19
30
|
* default model, and optional live model-discovery hook.
|
|
@@ -54,9 +65,57 @@ export interface ProviderProfile {
|
|
|
54
65
|
* Alternate names that resolve to this profile. Resolution is
|
|
55
66
|
* case-insensitive. Alias conflicts with another profile's primary name
|
|
56
67
|
* cause a `TypeError` at registration time.
|
|
68
|
+
*
|
|
69
|
+
* The canonical alias map (`codex`→`openai`, `google`→`gemini`, …) is declared
|
|
70
|
+
* here as DATA so the resolver never branches on provider name in code
|
|
71
|
+
* (T11756 AC2 · hermes `ProviderProfile.aliases` parity).
|
|
57
72
|
*/
|
|
58
73
|
aliases?: ReadonlyArray<string>;
|
|
59
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Coarse capability tier for system-of-use routing (E9). Sourced from the
|
|
77
|
+
* models.dev catalog capabilities when generated (E8 join), hand-set for
|
|
78
|
+
* builtins. Absent = unknown (the router treats it as `standard`).
|
|
79
|
+
*
|
|
80
|
+
* Hermes derives this from `model_metadata`; CLEO carries it as profile DATA
|
|
81
|
+
* so `resolveLLMForSystem` can pick the right tier without a code branch.
|
|
82
|
+
*
|
|
83
|
+
* @task T11756
|
|
84
|
+
*/
|
|
85
|
+
readonly tier?: ProviderTier;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Cheap/fast auxiliary model for low-stakes calls (title generation, summaries,
|
|
89
|
+
* the warm/aux tier). Hermes `ProviderProfile.default_aux_model` parity. Absent
|
|
90
|
+
* (or empty) → fall back to {@link defaultModel}.
|
|
91
|
+
*
|
|
92
|
+
* @task T11756
|
|
93
|
+
*/
|
|
94
|
+
readonly defaultAuxModel?: string;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Default `maxTokens` for this provider when the caller omits it. Hermes
|
|
98
|
+
* `ProviderProfile.default_max_tokens` parity. Absent → the transport's own
|
|
99
|
+
* default applies.
|
|
100
|
+
*
|
|
101
|
+
* @task T11756
|
|
102
|
+
*/
|
|
103
|
+
readonly defaultMaxTokens?: number;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Temperature handling this provider REQUIRES. Hermes
|
|
107
|
+
* `ProviderProfile.fixed_temperature` parity:
|
|
108
|
+
* - a `number` — the provider only accepts this exact temperature (e.g. the
|
|
109
|
+
* OpenAI o-series require `1`); the transport MUST send it and ignore the
|
|
110
|
+
* caller's override.
|
|
111
|
+
* - `'omit'` — the provider rejects a `temperature` field entirely; the
|
|
112
|
+
* transport MUST NOT send one.
|
|
113
|
+
* - absent — the caller's temperature (or the transport default) applies.
|
|
114
|
+
*
|
|
115
|
+
* @task T11756
|
|
116
|
+
*/
|
|
117
|
+
readonly fixedTemperature?: number | 'omit';
|
|
118
|
+
|
|
60
119
|
/**
|
|
61
120
|
* HTTP headers sent with every request to this provider.
|
|
62
121
|
* Merged into the SDK client's `defaultHeaders`.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the per-operation OUTPUT contract SSoT (T11692 / DHQ-057).
|
|
3
|
+
*
|
|
4
|
+
* Pins the proof-set of OUTPUT contracts and — critically — encodes the exact
|
|
5
|
+
* shape fact that produced the bug: `tasks.show` returns the task under `task`,
|
|
6
|
+
* so the canonical pointer is `/data/task/title`, NOT `/data/title`.
|
|
7
|
+
*
|
|
8
|
+
* Also validates that mutation contracts reflect the MinimalMutateEnvelope
|
|
9
|
+
* shape (string[] ids, NOT object arrays) and that tasks.find uses the
|
|
10
|
+
* { results, total } wrapper (NOT a bare array).
|
|
11
|
+
*
|
|
12
|
+
* @task T11692
|
|
13
|
+
* @epic T11679
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { describe, expect, it } from 'vitest';
|
|
17
|
+
import type { OperationOutputContract } from '../output-contract.js';
|
|
18
|
+
import { OUTPUT_CONTRACTS } from '../output-contracts-data.js';
|
|
19
|
+
|
|
20
|
+
describe('operations/output-contracts (T11692 · DHQ-057)', () => {
|
|
21
|
+
it('registers the high-traffic proof-set operations', () => {
|
|
22
|
+
for (const op of [
|
|
23
|
+
'tasks.show',
|
|
24
|
+
'tasks.list',
|
|
25
|
+
'tasks.find',
|
|
26
|
+
'tasks.add',
|
|
27
|
+
'tasks.add-batch',
|
|
28
|
+
'tasks.update',
|
|
29
|
+
'tasks.complete',
|
|
30
|
+
]) {
|
|
31
|
+
expect(OUTPUT_CONTRACTS[op], `missing output contract for ${op}`).toBeDefined();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('keys every entry by its own operation id', () => {
|
|
36
|
+
for (const [key, contract] of Object.entries(OUTPUT_CONTRACTS)) {
|
|
37
|
+
expect(contract.operation).toBe(key);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('tasks.show — the operation that bit us', () => {
|
|
42
|
+
const show = OUTPUT_CONTRACTS['tasks.show'] as OperationOutputContract;
|
|
43
|
+
|
|
44
|
+
it('encodes that the task is nested under `task` (data schema)', () => {
|
|
45
|
+
const schema = show.dataSchema as {
|
|
46
|
+
required?: string[];
|
|
47
|
+
properties?: Record<string, { properties?: Record<string, unknown> }>;
|
|
48
|
+
};
|
|
49
|
+
expect(schema.required).toContain('task');
|
|
50
|
+
// The title lives under task.properties.title — NOT at the data root.
|
|
51
|
+
expect(schema.properties?.task?.properties).toHaveProperty('title');
|
|
52
|
+
expect(schema.properties).not.toHaveProperty('title');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('lists /data/task/title as a valid --field pointer and NOT /data/title', () => {
|
|
56
|
+
expect(show.fieldPointers).toContain('/data/task/title');
|
|
57
|
+
expect(show.fieldPointers).not.toContain('/data/title');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('carries a shapeNote steering agents away from /data/<field>', () => {
|
|
61
|
+
expect(show.shapeNote).toBeTruthy();
|
|
62
|
+
expect(show.shapeNote).toContain('/data/task/');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('notes that view may be null', () => {
|
|
66
|
+
expect(show.shapeNote).toContain('null');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('mutation envelopes — MinimalMutateEnvelope (string[] ids, T9931)', () => {
|
|
71
|
+
it('tasks.add surfaces the created task ID as a bare string at /data/created/0', () => {
|
|
72
|
+
const add = OUTPUT_CONTRACTS['tasks.add'] as OperationOutputContract;
|
|
73
|
+
// Correct: /data/created/0 → "T11692" (string), NOT /data/created/0/id
|
|
74
|
+
expect(add.fieldPointers).toContain('/data/created/0');
|
|
75
|
+
expect(add.fieldPointers).not.toContain('/data/created/0/id');
|
|
76
|
+
// Schema must reflect string[] items, not object[]
|
|
77
|
+
const schema = add.dataSchema as {
|
|
78
|
+
required?: string[];
|
|
79
|
+
properties?: Record<string, { items?: { type?: string } }>;
|
|
80
|
+
};
|
|
81
|
+
expect(schema.required).toEqual(
|
|
82
|
+
expect.arrayContaining(['count', 'created', 'updated', 'deleted']),
|
|
83
|
+
);
|
|
84
|
+
expect(schema.properties?.created?.items?.type).toBe('string');
|
|
85
|
+
expect(schema.properties?.updated?.items?.type).toBe('string');
|
|
86
|
+
expect(schema.properties?.deleted?.items?.type).toBe('string');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('tasks.update / tasks.complete surface the changed task ID at /data/updated/0 (string)', () => {
|
|
90
|
+
for (const op of ['tasks.update', 'tasks.complete']) {
|
|
91
|
+
const c = OUTPUT_CONTRACTS[op] as OperationOutputContract;
|
|
92
|
+
// Correct: /data/updated/0 → "T11692" (string), NOT /data/updated/0/id
|
|
93
|
+
expect(c.fieldPointers).toContain('/data/updated/0');
|
|
94
|
+
expect(c.fieldPointers).not.toContain('/data/updated/0/id');
|
|
95
|
+
const schema = c.dataSchema as {
|
|
96
|
+
properties?: Record<string, { items?: { type?: string } }>;
|
|
97
|
+
};
|
|
98
|
+
expect(schema.properties?.updated?.items?.type).toBe('string');
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('tasks.add-batch dry-run pointers point to root /data/wouldCreate and /data/insertedCount', () => {
|
|
103
|
+
const batch = OUTPUT_CONTRACTS['tasks.add-batch'] as OperationOutputContract;
|
|
104
|
+
// Correct: root-level, NOT /data/dryRunSummary/wouldCreate
|
|
105
|
+
expect(batch.fieldPointers).toContain('/data/wouldCreate');
|
|
106
|
+
expect(batch.fieldPointers).toContain('/data/insertedCount');
|
|
107
|
+
expect(batch.fieldPointers).not.toContain('/data/dryRunSummary/wouldCreate');
|
|
108
|
+
expect(batch.fieldPointers).not.toContain('/data/dryRunSummary/insertedCount');
|
|
109
|
+
// shapeNote should clarify they are NOT under dryRunSummary
|
|
110
|
+
expect(batch.shapeNote).toContain('/data/wouldCreate');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('tasks.find data is a wrapper object with /data/results (array) and /data/total', () => {
|
|
115
|
+
const find = OUTPUT_CONTRACTS['tasks.find'] as OperationOutputContract;
|
|
116
|
+
// Correct: wrapper object, NOT a bare array
|
|
117
|
+
expect((find.dataSchema as { type?: string }).type).toBe('object');
|
|
118
|
+
// Correct pointers
|
|
119
|
+
expect(find.fieldPointers).toContain('/data/results/0/id');
|
|
120
|
+
expect(find.fieldPointers).toContain('/data/total');
|
|
121
|
+
// Wrong pointers must NOT appear
|
|
122
|
+
expect(find.fieldPointers).not.toContain('/data/0/id');
|
|
123
|
+
expect(find.shapeNote).toContain('/data/results');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OperationOutputContract — schema-first OUTPUT contract for CLEO operations.
|
|
3
|
+
*
|
|
4
|
+
* This module is the SINGLE SOURCE OF TRUTH for the per-operation OUTPUT
|
|
5
|
+
* (result) shape introspection surface (DHQ-057 · T11692 · EP-DHQ-CORE-FIXES
|
|
6
|
+
* T11679 · SG-CORE-SELF-TOOLING T11480). It is the OUTPUT-side mirror of
|
|
7
|
+
* {@link OperationInputContract}.
|
|
8
|
+
*
|
|
9
|
+
* ## Why this exists
|
|
10
|
+
*
|
|
11
|
+
* Before this contract, {@link OperationDef} declared INPUT (`params`) but had
|
|
12
|
+
* NO machine-readable description of the OUTPUT envelope's `data` payload.
|
|
13
|
+
* Consequently:
|
|
14
|
+
*
|
|
15
|
+
* - `cleo show T123 --field /data/title` returned `E_FIELD_NOT_FOUND` because
|
|
16
|
+
* the real shape is `/data/task/title` — agents had no way to predict the
|
|
17
|
+
* envelope `data` shape and `--field` JSON pointers were guesswork.
|
|
18
|
+
* - Every consumer (CLI `--field`, REST clients, the SDK) hand-sniffed the
|
|
19
|
+
* result per verb instead of resolving against a declared contract.
|
|
20
|
+
*
|
|
21
|
+
* An {@link OperationOutputContract} pairs a stable operation identifier with
|
|
22
|
+
* the JSON Schema (draft-07) document describing the envelope's `data` payload
|
|
23
|
+
* AND the curated set of valid `--field` JSON pointers (rooted at `/data`) that
|
|
24
|
+
* an agent can use without trial and error.
|
|
25
|
+
*
|
|
26
|
+
* ZERO runtime dependencies: `contracts` is a leaf package. JSON Schema
|
|
27
|
+
* documents are modeled as the loose {@link JsonSchema} alias (re-used from the
|
|
28
|
+
* input-contract module) so this module does not pull in a JSON Schema typings
|
|
29
|
+
* package.
|
|
30
|
+
*
|
|
31
|
+
* @packageDocumentation
|
|
32
|
+
* @module @cleocode/contracts/operations/output-contract
|
|
33
|
+
*
|
|
34
|
+
* @see {@link https://json-schema.org/draft-07/schema}
|
|
35
|
+
* @see OperationInputContract — the INPUT-side mirror of this contract
|
|
36
|
+
*
|
|
37
|
+
* @epic T11679
|
|
38
|
+
* @task T11692 — DHQ-057: per-operation output schema SSoT
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
import type { JsonSchema } from './input-contract.js';
|
|
42
|
+
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// OperationOutputContract
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Schema-first OUTPUT (result) contract for a single CLEO operation.
|
|
49
|
+
*
|
|
50
|
+
* Pairs a stable operation identifier with the JSON Schema draft-07 document
|
|
51
|
+
* that describes the LAFS envelope's `data` payload, plus the curated list of
|
|
52
|
+
* valid `--field` JSON pointers an agent can rely on.
|
|
53
|
+
*
|
|
54
|
+
* The `dataSchema` describes the shape of `envelope.data` — i.e. the value the
|
|
55
|
+
* dispatch handler returns, BEFORE the LAFS `{ success, data, meta }` wrapper
|
|
56
|
+
* is applied. For example, `tasks.show` returns
|
|
57
|
+
* `{ task, view, attachments, acRows?, relations? }`, so its `dataSchema` has
|
|
58
|
+
* `task` as a required property and `/data/task/title` is the canonical pointer
|
|
59
|
+
* for the task title — NOT `/data/title`.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* const showOutput: OperationOutputContract = {
|
|
64
|
+
* operation: 'tasks.show',
|
|
65
|
+
* dataSchema: {
|
|
66
|
+
* type: 'object',
|
|
67
|
+
* required: ['task'],
|
|
68
|
+
* properties: {
|
|
69
|
+
* task: { type: 'object', description: 'Full task record' },
|
|
70
|
+
* view: { type: ['object', 'null'] },
|
|
71
|
+
* attachments: { type: 'array' },
|
|
72
|
+
* },
|
|
73
|
+
* },
|
|
74
|
+
* fieldPointers: ['/data/task/id', '/data/task/title', '/data/task/status'],
|
|
75
|
+
* };
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export interface OperationOutputContract {
|
|
79
|
+
/**
|
|
80
|
+
* Stable, fully-qualified operation identifier in `<domain>.<verb>` form
|
|
81
|
+
* (e.g. `'tasks.show'`, `'tasks.add-batch'`). Used as the registry key in
|
|
82
|
+
* {@link OperationOutputContractRegistry}.
|
|
83
|
+
*/
|
|
84
|
+
operation: string;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* JSON Schema draft-07 document describing the shape of the LAFS envelope's
|
|
88
|
+
* `data` payload returned by this operation.
|
|
89
|
+
*
|
|
90
|
+
* This is the shape of `envelope.data` — the dispatch handler's return value
|
|
91
|
+
* BEFORE the `{ success, data, meta }` wrapper. Pointers used by `--field`
|
|
92
|
+
* are therefore rooted at `/data` (e.g. `/data/task/title` resolves against
|
|
93
|
+
* `dataSchema.properties.task.properties.title`).
|
|
94
|
+
*/
|
|
95
|
+
dataSchema: JsonSchema;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Curated, copy-pasteable list of valid `--field` JSON pointers an agent can
|
|
99
|
+
* use without trial and error. Each pointer is rooted at the envelope root
|
|
100
|
+
* (`/data/...`), matching the resolution semantics of `cleo <op> --field`.
|
|
101
|
+
*
|
|
102
|
+
* This is the direct remediation for the `--field /data/title` →
|
|
103
|
+
* `E_FIELD_NOT_FOUND` class of failures: instead of guessing, an agent runs
|
|
104
|
+
* `cleo show --describe` and reads the exact pointers that resolve.
|
|
105
|
+
*
|
|
106
|
+
* Conventionally lists the high-value scalar/leaf pointers (ids, titles,
|
|
107
|
+
* statuses, counts) — not every possible deep pointer.
|
|
108
|
+
*/
|
|
109
|
+
fieldPointers: string[];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Optional one-line note clarifying non-obvious shape facts (e.g. "task body
|
|
113
|
+
* is nested under `task`, not the root"). Surfaced in `--describe` output to
|
|
114
|
+
* pre-empt the exact mistakes this contract is designed to prevent.
|
|
115
|
+
*/
|
|
116
|
+
shapeNote?: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Registry
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Registry of every {@link OperationOutputContract} known to the CLEO runtime,
|
|
125
|
+
* keyed by the contract's `operation` identifier (e.g. `'tasks.show'`).
|
|
126
|
+
*
|
|
127
|
+
* The OUTPUT-side mirror of `OperationInputContractRegistry`. Populated
|
|
128
|
+
* incrementally — high-traffic operations first. A `null` lookup (operation
|
|
129
|
+
* absent from the registry) is expected and MUST NOT error: callers render a
|
|
130
|
+
* structured "no output contract yet" payload instead.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* const registry: OperationOutputContractRegistry = {
|
|
135
|
+
* 'tasks.show': showOutputContract,
|
|
136
|
+
* 'tasks.list': listOutputContract,
|
|
137
|
+
* };
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export type OperationOutputContractRegistry = Record<string, OperationOutputContract>;
|