@neurcode-ai/contracts 0.1.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.
@@ -0,0 +1,137 @@
1
+ export declare const CLI_JSON_CONTRACT_VERSION = "2026-04-04";
2
+ export declare const RUNTIME_COMPATIBILITY_CONTRACT_ID = "neurcode-runtime-compatibility";
3
+ export declare const RUNTIME_COMPATIBILITY_CONTRACT_VERSION = "2026-04-04";
4
+ export declare const RUNTIME_COMPATIBILITY_MANIFEST_VERSION = "2026-04-04.1";
5
+ export declare const RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION = 1;
6
+ export type RuntimeComponent = 'cli' | 'action' | 'api';
7
+ export type RuntimeMinimumPeerVersions = Partial<Record<RuntimeComponent, string>>;
8
+ export interface RuntimeCompatibilityTriplet {
9
+ id: string;
10
+ channel: 'current' | 'support-floor' | 'compat-canary';
11
+ versions: Record<RuntimeComponent, string>;
12
+ notes?: string;
13
+ }
14
+ export interface RuntimeCompatibilityManifest {
15
+ schemaVersion: number;
16
+ manifestVersion: string;
17
+ contractId: string;
18
+ runtimeContractVersion: string;
19
+ cliJsonContractVersion: string;
20
+ minimumPeerVersions: Record<RuntimeComponent, RuntimeMinimumPeerVersions>;
21
+ validatedTriplets: RuntimeCompatibilityTriplet[];
22
+ }
23
+ export declare function getRuntimeCompatibilityManifest(): RuntimeCompatibilityManifest;
24
+ export interface RuntimeCompatibilityDescriptor {
25
+ contractId: string;
26
+ runtimeContractVersion: string;
27
+ cliJsonContractVersion: string;
28
+ manifestVersion?: string;
29
+ component: RuntimeComponent;
30
+ componentVersion: string;
31
+ minimumPeerVersions: RuntimeMinimumPeerVersions;
32
+ }
33
+ export interface CliContractBase {
34
+ contractVersion?: string;
35
+ [key: string]: unknown;
36
+ }
37
+ export interface CliPlanJsonPayload extends CliContractBase {
38
+ success: boolean;
39
+ cached: boolean;
40
+ mode: string;
41
+ planId: string | null;
42
+ sessionId: string | null;
43
+ timestamp: string;
44
+ message: string;
45
+ }
46
+ export interface CliApplyJsonPayload extends CliContractBase {
47
+ success: boolean;
48
+ planId: string;
49
+ filesGenerated: number;
50
+ files: unknown[];
51
+ writtenFiles: unknown[];
52
+ message: string;
53
+ }
54
+ export interface CliVerifyJsonPayload extends CliContractBase {
55
+ grade: string;
56
+ score: number;
57
+ verdict: string;
58
+ violations: unknown[];
59
+ message: string;
60
+ scopeGuardPassed: boolean;
61
+ verificationSource?: 'api' | 'local_fallback' | 'policy_only' | string;
62
+ policyCompilation?: Record<string, unknown>;
63
+ changeContract?: Record<string, unknown>;
64
+ }
65
+ export interface CliPromptJsonPayload extends CliContractBase {
66
+ success: boolean;
67
+ planId: string | null;
68
+ intent: string | null;
69
+ prompt: string | null;
70
+ copied: boolean;
71
+ outputPath: string | null;
72
+ message: string;
73
+ }
74
+ export interface CliContractImportJsonPayload extends CliContractBase {
75
+ success: boolean;
76
+ provider: string | null;
77
+ planId: string | null;
78
+ sessionId: string | null;
79
+ projectId: string | null;
80
+ parseMode: 'json' | 'text' | null;
81
+ importedFiles: number;
82
+ warnings: unknown[];
83
+ changeContract?: Record<string, unknown> | null;
84
+ message: string;
85
+ timestamp: string;
86
+ }
87
+ export interface CliShipJsonPayload extends CliContractBase {
88
+ success: boolean;
89
+ status: string;
90
+ finalPlanId: string | null;
91
+ audit?: Record<string, unknown>;
92
+ error?: Record<string, unknown>;
93
+ }
94
+ export interface CliShipRunsJsonPayload extends CliContractBase {
95
+ runs: unknown[];
96
+ }
97
+ export interface CliShipResumeJsonPayload extends CliContractBase {
98
+ success: boolean;
99
+ status: string;
100
+ error?: Record<string, unknown>;
101
+ }
102
+ export interface CliShipAttestationVerifyJsonPayload extends CliContractBase {
103
+ pass: boolean;
104
+ message?: string;
105
+ digest?: Record<string, unknown>;
106
+ }
107
+ export interface CliCompatJsonPayload extends CliContractBase {
108
+ success: boolean;
109
+ timestamp: string;
110
+ component: 'cli';
111
+ componentVersion: string;
112
+ compatibility: RuntimeCompatibilityDescriptor;
113
+ }
114
+ export declare function compareSemver(left: string, right: string): number | null;
115
+ export declare function isSemverAtLeast(actual: string, minimum: string): boolean | null;
116
+ export declare function getMinimumCompatiblePeerVersion(component: RuntimeComponent, peer: RuntimeComponent): string | undefined;
117
+ export declare function getRuntimeMinimumPeerVersionMatrix(): Record<RuntimeComponent, RuntimeMinimumPeerVersions>;
118
+ export declare function buildRuntimeCompatibilityDescriptor(component: RuntimeComponent, componentVersion: string): RuntimeCompatibilityDescriptor;
119
+ export interface RuntimePeerCompatibilityIssue {
120
+ component: RuntimeComponent;
121
+ peer: RuntimeComponent;
122
+ required: string;
123
+ actual: string;
124
+ code: 'UNPARSABLE_VERSION' | 'VERSION_BELOW_MINIMUM';
125
+ }
126
+ export declare function evaluateRuntimePeerCompatibility(versions: Record<RuntimeComponent, string>): RuntimePeerCompatibilityIssue[];
127
+ export declare function parseCliPlanJsonPayload(value: unknown, label?: string): CliPlanJsonPayload;
128
+ export declare function parseCliApplyJsonPayload(value: unknown, label?: string): CliApplyJsonPayload;
129
+ export declare function parseCliVerifyJsonPayload(value: unknown, label?: string): CliVerifyJsonPayload;
130
+ export declare function parseCliPromptJsonPayload(value: unknown, label?: string): CliPromptJsonPayload;
131
+ export declare function parseCliContractImportJsonPayload(value: unknown, label?: string): CliContractImportJsonPayload;
132
+ export declare function parseCliShipJsonPayload(value: unknown, label?: string): CliShipJsonPayload;
133
+ export declare function parseCliShipRunsJsonPayload(value: unknown, label?: string): CliShipRunsJsonPayload;
134
+ export declare function parseCliShipResumeJsonPayload(value: unknown, label?: string): CliShipResumeJsonPayload;
135
+ export declare function parseCliShipAttestationVerifyJsonPayload(value: unknown, label?: string): CliShipAttestationVerifyJsonPayload;
136
+ export declare function parseCliCompatJsonPayload(value: unknown, label?: string): CliCompatJsonPayload;
137
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,419 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION = exports.RUNTIME_COMPATIBILITY_MANIFEST_VERSION = exports.RUNTIME_COMPATIBILITY_CONTRACT_VERSION = exports.RUNTIME_COMPATIBILITY_CONTRACT_ID = exports.CLI_JSON_CONTRACT_VERSION = void 0;
4
+ exports.getRuntimeCompatibilityManifest = getRuntimeCompatibilityManifest;
5
+ exports.compareSemver = compareSemver;
6
+ exports.isSemverAtLeast = isSemverAtLeast;
7
+ exports.getMinimumCompatiblePeerVersion = getMinimumCompatiblePeerVersion;
8
+ exports.getRuntimeMinimumPeerVersionMatrix = getRuntimeMinimumPeerVersionMatrix;
9
+ exports.buildRuntimeCompatibilityDescriptor = buildRuntimeCompatibilityDescriptor;
10
+ exports.evaluateRuntimePeerCompatibility = evaluateRuntimePeerCompatibility;
11
+ exports.parseCliPlanJsonPayload = parseCliPlanJsonPayload;
12
+ exports.parseCliApplyJsonPayload = parseCliApplyJsonPayload;
13
+ exports.parseCliVerifyJsonPayload = parseCliVerifyJsonPayload;
14
+ exports.parseCliPromptJsonPayload = parseCliPromptJsonPayload;
15
+ exports.parseCliContractImportJsonPayload = parseCliContractImportJsonPayload;
16
+ exports.parseCliShipJsonPayload = parseCliShipJsonPayload;
17
+ exports.parseCliShipRunsJsonPayload = parseCliShipRunsJsonPayload;
18
+ exports.parseCliShipResumeJsonPayload = parseCliShipResumeJsonPayload;
19
+ exports.parseCliShipAttestationVerifyJsonPayload = parseCliShipAttestationVerifyJsonPayload;
20
+ exports.parseCliCompatJsonPayload = parseCliCompatJsonPayload;
21
+ exports.CLI_JSON_CONTRACT_VERSION = '2026-04-04';
22
+ exports.RUNTIME_COMPATIBILITY_CONTRACT_ID = 'neurcode-runtime-compatibility';
23
+ exports.RUNTIME_COMPATIBILITY_CONTRACT_VERSION = '2026-04-04';
24
+ exports.RUNTIME_COMPATIBILITY_MANIFEST_VERSION = '2026-04-04.1';
25
+ exports.RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION = 1;
26
+ const RUNTIME_COMPATIBILITY_MANIFEST = {
27
+ schemaVersion: exports.RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION,
28
+ manifestVersion: exports.RUNTIME_COMPATIBILITY_MANIFEST_VERSION,
29
+ contractId: exports.RUNTIME_COMPATIBILITY_CONTRACT_ID,
30
+ runtimeContractVersion: exports.RUNTIME_COMPATIBILITY_CONTRACT_VERSION,
31
+ cliJsonContractVersion: exports.CLI_JSON_CONTRACT_VERSION,
32
+ minimumPeerVersions: {
33
+ cli: {
34
+ action: '0.2.1',
35
+ api: '0.2.0',
36
+ },
37
+ action: {
38
+ cli: '0.9.35',
39
+ api: '0.2.0',
40
+ },
41
+ api: {
42
+ cli: '0.9.35',
43
+ action: '0.2.1',
44
+ },
45
+ },
46
+ validatedTriplets: [
47
+ {
48
+ id: 'current',
49
+ channel: 'current',
50
+ versions: {
51
+ cli: '0.9.36',
52
+ action: '0.2.2',
53
+ api: '0.2.0',
54
+ },
55
+ notes: 'Current release train validated in monorepo CI.',
56
+ },
57
+ {
58
+ id: 'support-floor',
59
+ channel: 'support-floor',
60
+ versions: {
61
+ cli: '0.9.35',
62
+ action: '0.2.1',
63
+ api: '0.2.0',
64
+ },
65
+ notes: 'Minimum supported compatibility floor for enterprise rollout.',
66
+ },
67
+ ],
68
+ };
69
+ const RUNTIME_MINIMUM_PEER_VERSIONS = RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions;
70
+ function getRuntimeCompatibilityManifest() {
71
+ return {
72
+ ...RUNTIME_COMPATIBILITY_MANIFEST,
73
+ minimumPeerVersions: {
74
+ cli: { ...RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions.cli },
75
+ action: { ...RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions.action },
76
+ api: { ...RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions.api },
77
+ },
78
+ validatedTriplets: RUNTIME_COMPATIBILITY_MANIFEST.validatedTriplets.map((triplet) => ({
79
+ ...triplet,
80
+ versions: { ...triplet.versions },
81
+ })),
82
+ };
83
+ }
84
+ function asRecord(value, label) {
85
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
86
+ throw new Error(`${label}: expected object`);
87
+ }
88
+ return value;
89
+ }
90
+ function asBoolean(record, key, label) {
91
+ if (typeof record[key] !== 'boolean') {
92
+ throw new Error(`${label}: expected ${key}:boolean`);
93
+ }
94
+ return record[key];
95
+ }
96
+ function asNumber(record, key, label) {
97
+ if (typeof record[key] !== 'number' || Number.isNaN(record[key])) {
98
+ throw new Error(`${label}: expected ${key}:number`);
99
+ }
100
+ return record[key];
101
+ }
102
+ function asString(record, key, label) {
103
+ if (typeof record[key] !== 'string') {
104
+ throw new Error(`${label}: expected ${key}:string`);
105
+ }
106
+ return record[key];
107
+ }
108
+ function asNullableString(record, key, label) {
109
+ const value = record[key];
110
+ if (value === null || typeof value === 'string') {
111
+ return value;
112
+ }
113
+ throw new Error(`${label}: expected ${key}:string|null`);
114
+ }
115
+ function asArray(record, key, label) {
116
+ if (!Array.isArray(record[key])) {
117
+ throw new Error(`${label}: expected ${key}:array`);
118
+ }
119
+ return record[key];
120
+ }
121
+ function asOptionalRecord(record, key, label) {
122
+ const value = record[key];
123
+ if (value === undefined)
124
+ return undefined;
125
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
126
+ throw new Error(`${label}: expected ${key}:object`);
127
+ }
128
+ return value;
129
+ }
130
+ function asOptionalString(record, key, label) {
131
+ const value = record[key];
132
+ if (value === undefined)
133
+ return undefined;
134
+ if (typeof value !== 'string') {
135
+ throw new Error(`${label}: expected ${key}:string`);
136
+ }
137
+ return value;
138
+ }
139
+ function asContractVersion(record) {
140
+ const value = record.contractVersion;
141
+ if (value === undefined)
142
+ return undefined;
143
+ if (typeof value !== 'string') {
144
+ throw new Error('contractVersion: expected string when present');
145
+ }
146
+ return value;
147
+ }
148
+ function asRuntimeComponent(record, key, label) {
149
+ const value = asString(record, key, label);
150
+ if (value === 'cli' || value === 'action' || value === 'api') {
151
+ return value;
152
+ }
153
+ throw new Error(`${label}: expected ${key}:("cli"|"action"|"api")`);
154
+ }
155
+ function parseRuntimeMinimumPeerVersions(value, label) {
156
+ if (value === undefined || value === null)
157
+ return {};
158
+ const record = asRecord(value, `${label}.minimumPeerVersions`);
159
+ const next = {};
160
+ for (const component of ['cli', 'action', 'api']) {
161
+ const componentValue = record[component];
162
+ if (componentValue === undefined)
163
+ continue;
164
+ if (typeof componentValue !== 'string' || !componentValue.trim()) {
165
+ throw new Error(`${label}.minimumPeerVersions: expected ${component}:string`);
166
+ }
167
+ next[component] = componentValue.trim();
168
+ }
169
+ return next;
170
+ }
171
+ function parseRuntimeCompatibilityDescriptor(value, label) {
172
+ const record = asRecord(value, `${label}.compatibility`);
173
+ return {
174
+ contractId: asString(record, 'contractId', `${label}.compatibility`),
175
+ runtimeContractVersion: asString(record, 'runtimeContractVersion', `${label}.compatibility`),
176
+ cliJsonContractVersion: asString(record, 'cliJsonContractVersion', `${label}.compatibility`),
177
+ manifestVersion: asOptionalString(record, 'manifestVersion', `${label}.compatibility`),
178
+ component: asRuntimeComponent(record, 'component', `${label}.compatibility`),
179
+ componentVersion: asString(record, 'componentVersion', `${label}.compatibility`),
180
+ minimumPeerVersions: parseRuntimeMinimumPeerVersions(record.minimumPeerVersions, `${label}.compatibility`),
181
+ };
182
+ }
183
+ function parseSemver(value) {
184
+ const normalized = value.trim().replace(/^v/i, '').split('+')[0].split('-')[0];
185
+ const match = normalized.match(/^(\d+)\.(\d+)\.(\d+)$/);
186
+ if (!match)
187
+ return null;
188
+ const major = Number(match[1]);
189
+ const minor = Number(match[2]);
190
+ const patch = Number(match[3]);
191
+ if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(patch)) {
192
+ return null;
193
+ }
194
+ return [major, minor, patch];
195
+ }
196
+ function compareSemver(left, right) {
197
+ const l = parseSemver(left);
198
+ const r = parseSemver(right);
199
+ if (!l || !r)
200
+ return null;
201
+ for (let idx = 0; idx < 3; idx += 1) {
202
+ if (l[idx] > r[idx])
203
+ return 1;
204
+ if (l[idx] < r[idx])
205
+ return -1;
206
+ }
207
+ return 0;
208
+ }
209
+ function isSemverAtLeast(actual, minimum) {
210
+ const compare = compareSemver(actual, minimum);
211
+ if (compare === null)
212
+ return null;
213
+ return compare >= 0;
214
+ }
215
+ function getMinimumCompatiblePeerVersion(component, peer) {
216
+ return RUNTIME_MINIMUM_PEER_VERSIONS[component][peer];
217
+ }
218
+ function getRuntimeMinimumPeerVersionMatrix() {
219
+ return {
220
+ cli: { ...RUNTIME_MINIMUM_PEER_VERSIONS.cli },
221
+ action: { ...RUNTIME_MINIMUM_PEER_VERSIONS.action },
222
+ api: { ...RUNTIME_MINIMUM_PEER_VERSIONS.api },
223
+ };
224
+ }
225
+ function buildRuntimeCompatibilityDescriptor(component, componentVersion) {
226
+ return {
227
+ contractId: exports.RUNTIME_COMPATIBILITY_CONTRACT_ID,
228
+ runtimeContractVersion: exports.RUNTIME_COMPATIBILITY_CONTRACT_VERSION,
229
+ cliJsonContractVersion: exports.CLI_JSON_CONTRACT_VERSION,
230
+ manifestVersion: exports.RUNTIME_COMPATIBILITY_MANIFEST_VERSION,
231
+ component,
232
+ componentVersion,
233
+ minimumPeerVersions: { ...RUNTIME_MINIMUM_PEER_VERSIONS[component] },
234
+ };
235
+ }
236
+ function evaluateRuntimePeerCompatibility(versions) {
237
+ const issues = [];
238
+ for (const component of ['cli', 'action', 'api']) {
239
+ for (const peer of ['cli', 'action', 'api']) {
240
+ if (peer === component)
241
+ continue;
242
+ const required = getMinimumCompatiblePeerVersion(component, peer);
243
+ if (!required)
244
+ continue;
245
+ const actual = versions[peer];
246
+ const compatible = isSemverAtLeast(actual, required);
247
+ if (compatible === null) {
248
+ issues.push({
249
+ component,
250
+ peer,
251
+ required,
252
+ actual,
253
+ code: 'UNPARSABLE_VERSION',
254
+ });
255
+ }
256
+ else if (!compatible) {
257
+ issues.push({
258
+ component,
259
+ peer,
260
+ required,
261
+ actual,
262
+ code: 'VERSION_BELOW_MINIMUM',
263
+ });
264
+ }
265
+ }
266
+ }
267
+ return issues;
268
+ }
269
+ function parseCliPlanJsonPayload(value, label = 'plan') {
270
+ const record = asRecord(value, label);
271
+ return {
272
+ ...record,
273
+ contractVersion: asContractVersion(record),
274
+ success: asBoolean(record, 'success', label),
275
+ cached: asBoolean(record, 'cached', label),
276
+ mode: asString(record, 'mode', label),
277
+ planId: asNullableString(record, 'planId', label),
278
+ sessionId: asNullableString(record, 'sessionId', label),
279
+ timestamp: asString(record, 'timestamp', label),
280
+ message: asString(record, 'message', label),
281
+ };
282
+ }
283
+ function parseCliApplyJsonPayload(value, label = 'apply') {
284
+ const record = asRecord(value, label);
285
+ return {
286
+ ...record,
287
+ contractVersion: asContractVersion(record),
288
+ success: asBoolean(record, 'success', label),
289
+ planId: asString(record, 'planId', label),
290
+ filesGenerated: asNumber(record, 'filesGenerated', label),
291
+ files: asArray(record, 'files', label),
292
+ writtenFiles: asArray(record, 'writtenFiles', label),
293
+ message: asString(record, 'message', label),
294
+ };
295
+ }
296
+ function parseCliVerifyJsonPayload(value, label = 'verify') {
297
+ const record = asRecord(value, label);
298
+ const verificationSourceRaw = record.verificationSource;
299
+ const verificationSource = verificationSourceRaw === undefined
300
+ ? undefined
301
+ : asString(record, 'verificationSource', label);
302
+ return {
303
+ ...record,
304
+ contractVersion: asContractVersion(record),
305
+ grade: asString(record, 'grade', label),
306
+ score: asNumber(record, 'score', label),
307
+ verdict: asString(record, 'verdict', label),
308
+ violations: asArray(record, 'violations', label),
309
+ message: asString(record, 'message', label),
310
+ scopeGuardPassed: asBoolean(record, 'scopeGuardPassed', label),
311
+ verificationSource,
312
+ };
313
+ }
314
+ function parseCliPromptJsonPayload(value, label = 'prompt') {
315
+ const record = asRecord(value, label);
316
+ return {
317
+ ...record,
318
+ contractVersion: asContractVersion(record),
319
+ success: asBoolean(record, 'success', label),
320
+ planId: asNullableString(record, 'planId', label),
321
+ intent: asNullableString(record, 'intent', label),
322
+ prompt: asNullableString(record, 'prompt', label),
323
+ copied: asBoolean(record, 'copied', label),
324
+ outputPath: asNullableString(record, 'outputPath', label),
325
+ message: asString(record, 'message', label),
326
+ };
327
+ }
328
+ function parseCliContractImportJsonPayload(value, label = 'contract-import') {
329
+ const record = asRecord(value, label);
330
+ const parseModeRaw = record.parseMode;
331
+ let parseMode = null;
332
+ if (parseModeRaw !== undefined && parseModeRaw !== null) {
333
+ const parseModeValue = asString(record, 'parseMode', label);
334
+ if (parseModeValue !== 'json' && parseModeValue !== 'text') {
335
+ throw new Error(`${label}: expected parseMode:"json"|"text"|null`);
336
+ }
337
+ parseMode = parseModeValue;
338
+ }
339
+ const changeContractValue = record.changeContract;
340
+ let changeContract;
341
+ if (changeContractValue === null) {
342
+ changeContract = null;
343
+ }
344
+ else if (changeContractValue !== undefined) {
345
+ changeContract = asOptionalRecord(record, 'changeContract', label);
346
+ }
347
+ return {
348
+ ...record,
349
+ contractVersion: asContractVersion(record),
350
+ success: asBoolean(record, 'success', label),
351
+ provider: asNullableString(record, 'provider', label),
352
+ planId: asNullableString(record, 'planId', label),
353
+ sessionId: asNullableString(record, 'sessionId', label),
354
+ projectId: asNullableString(record, 'projectId', label),
355
+ parseMode,
356
+ importedFiles: asNumber(record, 'importedFiles', label),
357
+ warnings: asArray(record, 'warnings', label),
358
+ changeContract,
359
+ message: asString(record, 'message', label),
360
+ timestamp: asString(record, 'timestamp', label),
361
+ };
362
+ }
363
+ function parseCliShipJsonPayload(value, label = 'ship') {
364
+ const record = asRecord(value, label);
365
+ return {
366
+ ...record,
367
+ contractVersion: asContractVersion(record),
368
+ success: asBoolean(record, 'success', label),
369
+ status: asString(record, 'status', label),
370
+ finalPlanId: asNullableString(record, 'finalPlanId', label),
371
+ audit: asOptionalRecord(record, 'audit', label),
372
+ error: asOptionalRecord(record, 'error', label),
373
+ };
374
+ }
375
+ function parseCliShipRunsJsonPayload(value, label = 'ship-runs') {
376
+ const record = asRecord(value, label);
377
+ return {
378
+ ...record,
379
+ contractVersion: asContractVersion(record),
380
+ runs: asArray(record, 'runs', label),
381
+ };
382
+ }
383
+ function parseCliShipResumeJsonPayload(value, label = 'ship-resume') {
384
+ const record = asRecord(value, label);
385
+ return {
386
+ ...record,
387
+ contractVersion: asContractVersion(record),
388
+ success: asBoolean(record, 'success', label),
389
+ status: asString(record, 'status', label),
390
+ error: asOptionalRecord(record, 'error', label),
391
+ };
392
+ }
393
+ function parseCliShipAttestationVerifyJsonPayload(value, label = 'ship-attestation-verify') {
394
+ const record = asRecord(value, label);
395
+ return {
396
+ ...record,
397
+ contractVersion: asContractVersion(record),
398
+ pass: asBoolean(record, 'pass', label),
399
+ message: record.message === undefined ? undefined : asString(record, 'message', label),
400
+ digest: asOptionalRecord(record, 'digest', label),
401
+ };
402
+ }
403
+ function parseCliCompatJsonPayload(value, label = 'compat') {
404
+ const record = asRecord(value, label);
405
+ const component = asString(record, 'component', label);
406
+ if (component !== 'cli') {
407
+ throw new Error(`${label}: expected component:"cli"`);
408
+ }
409
+ return {
410
+ ...record,
411
+ contractVersion: asContractVersion(record),
412
+ success: asBoolean(record, 'success', label),
413
+ timestamp: asString(record, 'timestamp', label),
414
+ component: 'cli',
415
+ componentVersion: asString(record, 'componentVersion', label),
416
+ compatibility: parseRuntimeCompatibilityDescriptor(record.compatibility, label),
417
+ };
418
+ }
419
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@neurcode-ai/contracts",
3
+ "version": "0.1.0",
4
+ "description": "Shared JSON contracts for Neurcode CLI, API, action, IDE, and MCP surfaces",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "test": "tsx --test src/*.test.ts",
11
+ "prepare": "npm run build"
12
+ },
13
+ "license": "MIT",
14
+ "dependencies": {},
15
+ "devDependencies": {
16
+ "@types/node": "^20.10.0",
17
+ "tsx": "^4.20.6",
18
+ "typescript": "^5.3.0"
19
+ }
20
+ }
package/src/index.ts ADDED
@@ -0,0 +1,566 @@
1
+ export const CLI_JSON_CONTRACT_VERSION = '2026-04-04';
2
+ export const RUNTIME_COMPATIBILITY_CONTRACT_ID = 'neurcode-runtime-compatibility';
3
+ export const RUNTIME_COMPATIBILITY_CONTRACT_VERSION = '2026-04-04';
4
+ export const RUNTIME_COMPATIBILITY_MANIFEST_VERSION = '2026-04-04.1';
5
+ export const RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION = 1;
6
+
7
+ export type RuntimeComponent = 'cli' | 'action' | 'api';
8
+
9
+ export type RuntimeMinimumPeerVersions = Partial<Record<RuntimeComponent, string>>;
10
+
11
+ export interface RuntimeCompatibilityTriplet {
12
+ id: string;
13
+ channel: 'current' | 'support-floor' | 'compat-canary';
14
+ versions: Record<RuntimeComponent, string>;
15
+ notes?: string;
16
+ }
17
+
18
+ export interface RuntimeCompatibilityManifest {
19
+ schemaVersion: number;
20
+ manifestVersion: string;
21
+ contractId: string;
22
+ runtimeContractVersion: string;
23
+ cliJsonContractVersion: string;
24
+ minimumPeerVersions: Record<RuntimeComponent, RuntimeMinimumPeerVersions>;
25
+ validatedTriplets: RuntimeCompatibilityTriplet[];
26
+ }
27
+
28
+ const RUNTIME_COMPATIBILITY_MANIFEST: RuntimeCompatibilityManifest = {
29
+ schemaVersion: RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION,
30
+ manifestVersion: RUNTIME_COMPATIBILITY_MANIFEST_VERSION,
31
+ contractId: RUNTIME_COMPATIBILITY_CONTRACT_ID,
32
+ runtimeContractVersion: RUNTIME_COMPATIBILITY_CONTRACT_VERSION,
33
+ cliJsonContractVersion: CLI_JSON_CONTRACT_VERSION,
34
+ minimumPeerVersions: {
35
+ cli: {
36
+ action: '0.2.1',
37
+ api: '0.2.0',
38
+ },
39
+ action: {
40
+ cli: '0.9.35',
41
+ api: '0.2.0',
42
+ },
43
+ api: {
44
+ cli: '0.9.35',
45
+ action: '0.2.1',
46
+ },
47
+ },
48
+ validatedTriplets: [
49
+ {
50
+ id: 'current',
51
+ channel: 'current',
52
+ versions: {
53
+ cli: '0.9.36',
54
+ action: '0.2.2',
55
+ api: '0.2.0',
56
+ },
57
+ notes: 'Current release train validated in monorepo CI.',
58
+ },
59
+ {
60
+ id: 'support-floor',
61
+ channel: 'support-floor',
62
+ versions: {
63
+ cli: '0.9.35',
64
+ action: '0.2.1',
65
+ api: '0.2.0',
66
+ },
67
+ notes: 'Minimum supported compatibility floor for enterprise rollout.',
68
+ },
69
+ ],
70
+ };
71
+
72
+ const RUNTIME_MINIMUM_PEER_VERSIONS: Record<RuntimeComponent, RuntimeMinimumPeerVersions> =
73
+ RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions;
74
+
75
+ export function getRuntimeCompatibilityManifest(): RuntimeCompatibilityManifest {
76
+ return {
77
+ ...RUNTIME_COMPATIBILITY_MANIFEST,
78
+ minimumPeerVersions: {
79
+ cli: { ...RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions.cli },
80
+ action: { ...RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions.action },
81
+ api: { ...RUNTIME_COMPATIBILITY_MANIFEST.minimumPeerVersions.api },
82
+ },
83
+ validatedTriplets: RUNTIME_COMPATIBILITY_MANIFEST.validatedTriplets.map((triplet) => ({
84
+ ...triplet,
85
+ versions: { ...triplet.versions },
86
+ })),
87
+ };
88
+ }
89
+
90
+ export interface RuntimeCompatibilityDescriptor {
91
+ contractId: string;
92
+ runtimeContractVersion: string;
93
+ cliJsonContractVersion: string;
94
+ manifestVersion?: string;
95
+ component: RuntimeComponent;
96
+ componentVersion: string;
97
+ minimumPeerVersions: RuntimeMinimumPeerVersions;
98
+ }
99
+
100
+ export interface CliContractBase {
101
+ contractVersion?: string;
102
+ [key: string]: unknown;
103
+ }
104
+
105
+ export interface CliPlanJsonPayload extends CliContractBase {
106
+ success: boolean;
107
+ cached: boolean;
108
+ mode: string;
109
+ planId: string | null;
110
+ sessionId: string | null;
111
+ timestamp: string;
112
+ message: string;
113
+ }
114
+
115
+ export interface CliApplyJsonPayload extends CliContractBase {
116
+ success: boolean;
117
+ planId: string;
118
+ filesGenerated: number;
119
+ files: unknown[];
120
+ writtenFiles: unknown[];
121
+ message: string;
122
+ }
123
+
124
+ export interface CliVerifyJsonPayload extends CliContractBase {
125
+ grade: string;
126
+ score: number;
127
+ verdict: string;
128
+ violations: unknown[];
129
+ message: string;
130
+ scopeGuardPassed: boolean;
131
+ verificationSource?: 'api' | 'local_fallback' | 'policy_only' | string;
132
+ policyCompilation?: Record<string, unknown>;
133
+ changeContract?: Record<string, unknown>;
134
+ }
135
+
136
+ export interface CliPromptJsonPayload extends CliContractBase {
137
+ success: boolean;
138
+ planId: string | null;
139
+ intent: string | null;
140
+ prompt: string | null;
141
+ copied: boolean;
142
+ outputPath: string | null;
143
+ message: string;
144
+ }
145
+
146
+ export interface CliContractImportJsonPayload extends CliContractBase {
147
+ success: boolean;
148
+ provider: string | null;
149
+ planId: string | null;
150
+ sessionId: string | null;
151
+ projectId: string | null;
152
+ parseMode: 'json' | 'text' | null;
153
+ importedFiles: number;
154
+ warnings: unknown[];
155
+ changeContract?: Record<string, unknown> | null;
156
+ message: string;
157
+ timestamp: string;
158
+ }
159
+
160
+ export interface CliShipJsonPayload extends CliContractBase {
161
+ success: boolean;
162
+ status: string;
163
+ finalPlanId: string | null;
164
+ audit?: Record<string, unknown>;
165
+ error?: Record<string, unknown>;
166
+ }
167
+
168
+ export interface CliShipRunsJsonPayload extends CliContractBase {
169
+ runs: unknown[];
170
+ }
171
+
172
+ export interface CliShipResumeJsonPayload extends CliContractBase {
173
+ success: boolean;
174
+ status: string;
175
+ error?: Record<string, unknown>;
176
+ }
177
+
178
+ export interface CliShipAttestationVerifyJsonPayload extends CliContractBase {
179
+ pass: boolean;
180
+ message?: string;
181
+ digest?: Record<string, unknown>;
182
+ }
183
+
184
+ export interface CliCompatJsonPayload extends CliContractBase {
185
+ success: boolean;
186
+ timestamp: string;
187
+ component: 'cli';
188
+ componentVersion: string;
189
+ compatibility: RuntimeCompatibilityDescriptor;
190
+ }
191
+
192
+ function asRecord(value: unknown, label: string): Record<string, unknown> {
193
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
194
+ throw new Error(`${label}: expected object`);
195
+ }
196
+ return value as Record<string, unknown>;
197
+ }
198
+
199
+ function asBoolean(record: Record<string, unknown>, key: string, label: string): boolean {
200
+ if (typeof record[key] !== 'boolean') {
201
+ throw new Error(`${label}: expected ${key}:boolean`);
202
+ }
203
+ return record[key] as boolean;
204
+ }
205
+
206
+ function asNumber(record: Record<string, unknown>, key: string, label: string): number {
207
+ if (typeof record[key] !== 'number' || Number.isNaN(record[key])) {
208
+ throw new Error(`${label}: expected ${key}:number`);
209
+ }
210
+ return record[key] as number;
211
+ }
212
+
213
+ function asString(record: Record<string, unknown>, key: string, label: string): string {
214
+ if (typeof record[key] !== 'string') {
215
+ throw new Error(`${label}: expected ${key}:string`);
216
+ }
217
+ return record[key] as string;
218
+ }
219
+
220
+ function asNullableString(record: Record<string, unknown>, key: string, label: string): string | null {
221
+ const value = record[key];
222
+ if (value === null || typeof value === 'string') {
223
+ return value as string | null;
224
+ }
225
+ throw new Error(`${label}: expected ${key}:string|null`);
226
+ }
227
+
228
+ function asArray(record: Record<string, unknown>, key: string, label: string): unknown[] {
229
+ if (!Array.isArray(record[key])) {
230
+ throw new Error(`${label}: expected ${key}:array`);
231
+ }
232
+ return record[key] as unknown[];
233
+ }
234
+
235
+ function asOptionalRecord(record: Record<string, unknown>, key: string, label: string): Record<string, unknown> | undefined {
236
+ const value = record[key];
237
+ if (value === undefined) return undefined;
238
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
239
+ throw new Error(`${label}: expected ${key}:object`);
240
+ }
241
+ return value as Record<string, unknown>;
242
+ }
243
+
244
+ function asOptionalString(record: Record<string, unknown>, key: string, label: string): string | undefined {
245
+ const value = record[key];
246
+ if (value === undefined) return undefined;
247
+ if (typeof value !== 'string') {
248
+ throw new Error(`${label}: expected ${key}:string`);
249
+ }
250
+ return value;
251
+ }
252
+
253
+ function asContractVersion(record: Record<string, unknown>): string | undefined {
254
+ const value = record.contractVersion;
255
+ if (value === undefined) return undefined;
256
+ if (typeof value !== 'string') {
257
+ throw new Error('contractVersion: expected string when present');
258
+ }
259
+ return value;
260
+ }
261
+
262
+ function asRuntimeComponent(record: Record<string, unknown>, key: string, label: string): RuntimeComponent {
263
+ const value = asString(record, key, label);
264
+ if (value === 'cli' || value === 'action' || value === 'api') {
265
+ return value;
266
+ }
267
+ throw new Error(`${label}: expected ${key}:("cli"|"action"|"api")`);
268
+ }
269
+
270
+ function parseRuntimeMinimumPeerVersions(
271
+ value: unknown,
272
+ label: string
273
+ ): RuntimeMinimumPeerVersions {
274
+ if (value === undefined || value === null) return {};
275
+ const record = asRecord(value, `${label}.minimumPeerVersions`);
276
+ const next: RuntimeMinimumPeerVersions = {};
277
+ for (const component of ['cli', 'action', 'api'] as const) {
278
+ const componentValue = record[component];
279
+ if (componentValue === undefined) continue;
280
+ if (typeof componentValue !== 'string' || !componentValue.trim()) {
281
+ throw new Error(`${label}.minimumPeerVersions: expected ${component}:string`);
282
+ }
283
+ next[component] = componentValue.trim();
284
+ }
285
+ return next;
286
+ }
287
+
288
+ function parseRuntimeCompatibilityDescriptor(
289
+ value: unknown,
290
+ label: string
291
+ ): RuntimeCompatibilityDescriptor {
292
+ const record = asRecord(value, `${label}.compatibility`);
293
+ return {
294
+ contractId: asString(record, 'contractId', `${label}.compatibility`),
295
+ runtimeContractVersion: asString(record, 'runtimeContractVersion', `${label}.compatibility`),
296
+ cliJsonContractVersion: asString(record, 'cliJsonContractVersion', `${label}.compatibility`),
297
+ manifestVersion: asOptionalString(record, 'manifestVersion', `${label}.compatibility`),
298
+ component: asRuntimeComponent(record, 'component', `${label}.compatibility`),
299
+ componentVersion: asString(record, 'componentVersion', `${label}.compatibility`),
300
+ minimumPeerVersions: parseRuntimeMinimumPeerVersions(record.minimumPeerVersions, `${label}.compatibility`),
301
+ };
302
+ }
303
+
304
+ function parseSemver(value: string): [number, number, number] | null {
305
+ const normalized = value.trim().replace(/^v/i, '').split('+')[0].split('-')[0];
306
+ const match = normalized.match(/^(\d+)\.(\d+)\.(\d+)$/);
307
+ if (!match) return null;
308
+ const major = Number(match[1]);
309
+ const minor = Number(match[2]);
310
+ const patch = Number(match[3]);
311
+ if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(patch)) {
312
+ return null;
313
+ }
314
+ return [major, minor, patch];
315
+ }
316
+
317
+ export function compareSemver(left: string, right: string): number | null {
318
+ const l = parseSemver(left);
319
+ const r = parseSemver(right);
320
+ if (!l || !r) return null;
321
+ for (let idx = 0; idx < 3; idx += 1) {
322
+ if (l[idx] > r[idx]) return 1;
323
+ if (l[idx] < r[idx]) return -1;
324
+ }
325
+ return 0;
326
+ }
327
+
328
+ export function isSemverAtLeast(actual: string, minimum: string): boolean | null {
329
+ const compare = compareSemver(actual, minimum);
330
+ if (compare === null) return null;
331
+ return compare >= 0;
332
+ }
333
+
334
+ export function getMinimumCompatiblePeerVersion(
335
+ component: RuntimeComponent,
336
+ peer: RuntimeComponent
337
+ ): string | undefined {
338
+ return RUNTIME_MINIMUM_PEER_VERSIONS[component][peer];
339
+ }
340
+
341
+ export function getRuntimeMinimumPeerVersionMatrix(): Record<RuntimeComponent, RuntimeMinimumPeerVersions> {
342
+ return {
343
+ cli: { ...RUNTIME_MINIMUM_PEER_VERSIONS.cli },
344
+ action: { ...RUNTIME_MINIMUM_PEER_VERSIONS.action },
345
+ api: { ...RUNTIME_MINIMUM_PEER_VERSIONS.api },
346
+ };
347
+ }
348
+
349
+ export function buildRuntimeCompatibilityDescriptor(
350
+ component: RuntimeComponent,
351
+ componentVersion: string
352
+ ): RuntimeCompatibilityDescriptor {
353
+ return {
354
+ contractId: RUNTIME_COMPATIBILITY_CONTRACT_ID,
355
+ runtimeContractVersion: RUNTIME_COMPATIBILITY_CONTRACT_VERSION,
356
+ cliJsonContractVersion: CLI_JSON_CONTRACT_VERSION,
357
+ manifestVersion: RUNTIME_COMPATIBILITY_MANIFEST_VERSION,
358
+ component,
359
+ componentVersion,
360
+ minimumPeerVersions: { ...RUNTIME_MINIMUM_PEER_VERSIONS[component] },
361
+ };
362
+ }
363
+
364
+ export interface RuntimePeerCompatibilityIssue {
365
+ component: RuntimeComponent;
366
+ peer: RuntimeComponent;
367
+ required: string;
368
+ actual: string;
369
+ code: 'UNPARSABLE_VERSION' | 'VERSION_BELOW_MINIMUM';
370
+ }
371
+
372
+ export function evaluateRuntimePeerCompatibility(versions: Record<RuntimeComponent, string>): RuntimePeerCompatibilityIssue[] {
373
+ const issues: RuntimePeerCompatibilityIssue[] = [];
374
+ for (const component of ['cli', 'action', 'api'] as const) {
375
+ for (const peer of ['cli', 'action', 'api'] as const) {
376
+ if (peer === component) continue;
377
+ const required = getMinimumCompatiblePeerVersion(component, peer);
378
+ if (!required) continue;
379
+ const actual = versions[peer];
380
+ const compatible = isSemverAtLeast(actual, required);
381
+ if (compatible === null) {
382
+ issues.push({
383
+ component,
384
+ peer,
385
+ required,
386
+ actual,
387
+ code: 'UNPARSABLE_VERSION',
388
+ });
389
+ } else if (!compatible) {
390
+ issues.push({
391
+ component,
392
+ peer,
393
+ required,
394
+ actual,
395
+ code: 'VERSION_BELOW_MINIMUM',
396
+ });
397
+ }
398
+ }
399
+ }
400
+ return issues;
401
+ }
402
+
403
+ export function parseCliPlanJsonPayload(value: unknown, label = 'plan'): CliPlanJsonPayload {
404
+ const record = asRecord(value, label);
405
+ return {
406
+ ...record,
407
+ contractVersion: asContractVersion(record),
408
+ success: asBoolean(record, 'success', label),
409
+ cached: asBoolean(record, 'cached', label),
410
+ mode: asString(record, 'mode', label),
411
+ planId: asNullableString(record, 'planId', label),
412
+ sessionId: asNullableString(record, 'sessionId', label),
413
+ timestamp: asString(record, 'timestamp', label),
414
+ message: asString(record, 'message', label),
415
+ };
416
+ }
417
+
418
+ export function parseCliApplyJsonPayload(value: unknown, label = 'apply'): CliApplyJsonPayload {
419
+ const record = asRecord(value, label);
420
+ return {
421
+ ...record,
422
+ contractVersion: asContractVersion(record),
423
+ success: asBoolean(record, 'success', label),
424
+ planId: asString(record, 'planId', label),
425
+ filesGenerated: asNumber(record, 'filesGenerated', label),
426
+ files: asArray(record, 'files', label),
427
+ writtenFiles: asArray(record, 'writtenFiles', label),
428
+ message: asString(record, 'message', label),
429
+ };
430
+ }
431
+
432
+ export function parseCliVerifyJsonPayload(value: unknown, label = 'verify'): CliVerifyJsonPayload {
433
+ const record = asRecord(value, label);
434
+ const verificationSourceRaw = record.verificationSource;
435
+ const verificationSource = verificationSourceRaw === undefined
436
+ ? undefined
437
+ : asString(record, 'verificationSource', label);
438
+ return {
439
+ ...record,
440
+ contractVersion: asContractVersion(record),
441
+ grade: asString(record, 'grade', label),
442
+ score: asNumber(record, 'score', label),
443
+ verdict: asString(record, 'verdict', label),
444
+ violations: asArray(record, 'violations', label),
445
+ message: asString(record, 'message', label),
446
+ scopeGuardPassed: asBoolean(record, 'scopeGuardPassed', label),
447
+ verificationSource,
448
+ };
449
+ }
450
+
451
+ export function parseCliPromptJsonPayload(value: unknown, label = 'prompt'): CliPromptJsonPayload {
452
+ const record = asRecord(value, label);
453
+ return {
454
+ ...record,
455
+ contractVersion: asContractVersion(record),
456
+ success: asBoolean(record, 'success', label),
457
+ planId: asNullableString(record, 'planId', label),
458
+ intent: asNullableString(record, 'intent', label),
459
+ prompt: asNullableString(record, 'prompt', label),
460
+ copied: asBoolean(record, 'copied', label),
461
+ outputPath: asNullableString(record, 'outputPath', label),
462
+ message: asString(record, 'message', label),
463
+ };
464
+ }
465
+
466
+ export function parseCliContractImportJsonPayload(
467
+ value: unknown,
468
+ label = 'contract-import'
469
+ ): CliContractImportJsonPayload {
470
+ const record = asRecord(value, label);
471
+ const parseModeRaw = record.parseMode;
472
+ let parseMode: 'json' | 'text' | null = null;
473
+ if (parseModeRaw !== undefined && parseModeRaw !== null) {
474
+ const parseModeValue = asString(record, 'parseMode', label);
475
+ if (parseModeValue !== 'json' && parseModeValue !== 'text') {
476
+ throw new Error(`${label}: expected parseMode:"json"|"text"|null`);
477
+ }
478
+ parseMode = parseModeValue;
479
+ }
480
+ const changeContractValue = record.changeContract;
481
+ let changeContract: Record<string, unknown> | null | undefined;
482
+ if (changeContractValue === null) {
483
+ changeContract = null;
484
+ } else if (changeContractValue !== undefined) {
485
+ changeContract = asOptionalRecord(record, 'changeContract', label);
486
+ }
487
+ return {
488
+ ...record,
489
+ contractVersion: asContractVersion(record),
490
+ success: asBoolean(record, 'success', label),
491
+ provider: asNullableString(record, 'provider', label),
492
+ planId: asNullableString(record, 'planId', label),
493
+ sessionId: asNullableString(record, 'sessionId', label),
494
+ projectId: asNullableString(record, 'projectId', label),
495
+ parseMode,
496
+ importedFiles: asNumber(record, 'importedFiles', label),
497
+ warnings: asArray(record, 'warnings', label),
498
+ changeContract,
499
+ message: asString(record, 'message', label),
500
+ timestamp: asString(record, 'timestamp', label),
501
+ };
502
+ }
503
+
504
+ export function parseCliShipJsonPayload(value: unknown, label = 'ship'): CliShipJsonPayload {
505
+ const record = asRecord(value, label);
506
+ return {
507
+ ...record,
508
+ contractVersion: asContractVersion(record),
509
+ success: asBoolean(record, 'success', label),
510
+ status: asString(record, 'status', label),
511
+ finalPlanId: asNullableString(record, 'finalPlanId', label),
512
+ audit: asOptionalRecord(record, 'audit', label),
513
+ error: asOptionalRecord(record, 'error', label),
514
+ };
515
+ }
516
+
517
+ export function parseCliShipRunsJsonPayload(value: unknown, label = 'ship-runs'): CliShipRunsJsonPayload {
518
+ const record = asRecord(value, label);
519
+ return {
520
+ ...record,
521
+ contractVersion: asContractVersion(record),
522
+ runs: asArray(record, 'runs', label),
523
+ };
524
+ }
525
+
526
+ export function parseCliShipResumeJsonPayload(value: unknown, label = 'ship-resume'): CliShipResumeJsonPayload {
527
+ const record = asRecord(value, label);
528
+ return {
529
+ ...record,
530
+ contractVersion: asContractVersion(record),
531
+ success: asBoolean(record, 'success', label),
532
+ status: asString(record, 'status', label),
533
+ error: asOptionalRecord(record, 'error', label),
534
+ };
535
+ }
536
+
537
+ export function parseCliShipAttestationVerifyJsonPayload(
538
+ value: unknown,
539
+ label = 'ship-attestation-verify'
540
+ ): CliShipAttestationVerifyJsonPayload {
541
+ const record = asRecord(value, label);
542
+ return {
543
+ ...record,
544
+ contractVersion: asContractVersion(record),
545
+ pass: asBoolean(record, 'pass', label),
546
+ message: record.message === undefined ? undefined : asString(record, 'message', label),
547
+ digest: asOptionalRecord(record, 'digest', label),
548
+ };
549
+ }
550
+
551
+ export function parseCliCompatJsonPayload(value: unknown, label = 'compat'): CliCompatJsonPayload {
552
+ const record = asRecord(value, label);
553
+ const component = asString(record, 'component', label);
554
+ if (component !== 'cli') {
555
+ throw new Error(`${label}: expected component:"cli"`);
556
+ }
557
+ return {
558
+ ...record,
559
+ contractVersion: asContractVersion(record),
560
+ success: asBoolean(record, 'success', label),
561
+ timestamp: asString(record, 'timestamp', label),
562
+ component: 'cli',
563
+ componentVersion: asString(record, 'componentVersion', label),
564
+ compatibility: parseRuntimeCompatibilityDescriptor(record.compatibility, label),
565
+ };
566
+ }
@@ -0,0 +1,43 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import {
5
+ buildRuntimeCompatibilityDescriptor,
6
+ CLI_JSON_CONTRACT_VERSION,
7
+ evaluateRuntimePeerCompatibility,
8
+ getRuntimeCompatibilityManifest,
9
+ RUNTIME_COMPATIBILITY_CONTRACT_ID,
10
+ RUNTIME_COMPATIBILITY_CONTRACT_VERSION,
11
+ RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION,
12
+ } from './index';
13
+
14
+ test('runtime compatibility manifest envelope is aligned', () => {
15
+ const manifest = getRuntimeCompatibilityManifest();
16
+
17
+ assert.equal(manifest.schemaVersion, RUNTIME_COMPATIBILITY_MANIFEST_SCHEMA_VERSION);
18
+ assert.equal(manifest.contractId, RUNTIME_COMPATIBILITY_CONTRACT_ID);
19
+ assert.equal(manifest.runtimeContractVersion, RUNTIME_COMPATIBILITY_CONTRACT_VERSION);
20
+ assert.equal(manifest.cliJsonContractVersion, CLI_JSON_CONTRACT_VERSION);
21
+ assert.equal(typeof manifest.manifestVersion, 'string');
22
+ assert.equal(manifest.manifestVersion.length > 0, true);
23
+ });
24
+
25
+ test('validated runtime triplets are internally compatible', () => {
26
+ const manifest = getRuntimeCompatibilityManifest();
27
+ assert.equal(manifest.validatedTriplets.length > 0, true);
28
+
29
+ for (const triplet of manifest.validatedTriplets) {
30
+ const issues = evaluateRuntimePeerCompatibility(triplet.versions);
31
+ assert.deepEqual(
32
+ issues,
33
+ [],
34
+ `Triplet ${triplet.id} should be compatible but has issues: ${JSON.stringify(issues)}`
35
+ );
36
+ }
37
+ });
38
+
39
+ test('runtime compatibility descriptor includes manifest version', () => {
40
+ const manifest = getRuntimeCompatibilityManifest();
41
+ const descriptor = buildRuntimeCompatibilityDescriptor('cli', '0.9.36');
42
+ assert.equal(descriptor.manifestVersion, manifest.manifestVersion);
43
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "commonjs",
5
+ "lib": ["ES2022"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true,
15
+ "resolveJsonModule": true
16
+ },
17
+ "include": ["src/**/*"],
18
+ "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
19
+ }