@nekro-nxt/contracts 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export * from './domain.js'
2
+ export * from './config-schema.js'
3
+ export * from './extension-ui.js'
4
+ export * from './host-api.js'
5
+ export * from './management-api.js'
6
+ export * from './runtime-compatibility.js'
7
+ export * from './extension-capabilities.js'
8
+ export * from './community.js'
@@ -0,0 +1,168 @@
1
+ import { z } from 'zod'
2
+
3
+ const NonEmptyStringSchema = z.string().trim().min(1)
4
+ const Base64UrlSchema = z.string().regex(/^[A-Za-z0-9_-]+$/u)
5
+
6
+ export const ServerInstanceIdSchema = z
7
+ .string()
8
+ .regex(/^nxt_instance_[0-9A-HJKMNP-TV-Z]{26}$/u)
9
+ .brand<'ServerInstanceId'>()
10
+ export type ServerInstanceId = z.output<typeof ServerInstanceIdSchema>
11
+
12
+ export const ManagementDeviceIdSchema = z
13
+ .string()
14
+ .regex(/^nxt_device_[0-9A-HJKMNP-TV-Z]{26}$/u)
15
+ .brand<'ManagementDeviceId'>()
16
+ export type ManagementDeviceId = z.output<typeof ManagementDeviceIdSchema>
17
+
18
+ export const InstanceDescriptorWireSchema = z
19
+ .object({
20
+ format: z.literal('nxt.instance-descriptor'),
21
+ descriptorVersion: z.number().int().positive(),
22
+ instanceId: ServerInstanceIdSchema,
23
+ releaseId: NonEmptyStringSchema.max(256),
24
+ productVersion: NonEmptyStringSchema.max(64),
25
+ managementProtocol: z.number().int().positive(),
26
+ desktopChromeProtocol: z.number().int().positive(),
27
+ transport: NonEmptyStringSchema.max(80),
28
+ })
29
+ .passthrough()
30
+ export type InstanceDescriptorWire = z.output<typeof InstanceDescriptorWireSchema>
31
+
32
+ export const InstanceDescriptorSchema = z
33
+ .object({
34
+ format: z.literal('nxt.instance-descriptor'),
35
+ descriptorVersion: z.literal(1),
36
+ instanceId: ServerInstanceIdSchema,
37
+ releaseId: NonEmptyStringSchema.max(256),
38
+ productVersion: NonEmptyStringSchema.max(64),
39
+ managementProtocol: z.union([z.literal(1), z.literal(2)]),
40
+ desktopChromeProtocol: z.literal(1),
41
+ transport: z.enum(['loopback-http', 'auto-tls-pinned-v1', 'explicit-http-v1']),
42
+ })
43
+ .strict()
44
+ .superRefine((value, context) => {
45
+ const valid =
46
+ (value.managementProtocol === 1 &&
47
+ (value.transport === 'loopback-http' || value.transport === 'auto-tls-pinned-v1')) ||
48
+ (value.managementProtocol === 2 && value.transport === 'explicit-http-v1')
49
+ if (!valid) context.addIssue({ code: 'custom', message: 'management protocol 与 transport 不匹配。' })
50
+ })
51
+ export type InstanceDescriptor = z.output<typeof InstanceDescriptorSchema>
52
+
53
+ export const ManagementChallengeResponseSchema = z
54
+ .object({
55
+ challengeId: Base64UrlSchema,
56
+ serverNonce: Base64UrlSchema,
57
+ instanceId: ServerInstanceIdSchema,
58
+ spkiSha256: Base64UrlSchema,
59
+ expiresAt: z.number().int().positive(),
60
+ })
61
+ .strict()
62
+ export type ManagementChallengeResponse = z.output<typeof ManagementChallengeResponseSchema>
63
+
64
+ export const InsecureHttpManagementChallengeResponseSchema = z
65
+ .object({
66
+ challengeId: Base64UrlSchema,
67
+ serverNonce: Base64UrlSchema,
68
+ instanceId: ServerInstanceIdSchema,
69
+ transportBinding: Base64UrlSchema,
70
+ expiresAt: z.number().int().positive(),
71
+ })
72
+ .strict()
73
+ export type InsecureHttpManagementChallengeResponse = z.output<typeof InsecureHttpManagementChallengeResponseSchema>
74
+
75
+ export const ManagementDeviceEnrollmentRequestSchema = z
76
+ .object({
77
+ challengeId: Base64UrlSchema,
78
+ clientNonce: Base64UrlSchema,
79
+ proof: Base64UrlSchema,
80
+ label: z.string().trim().min(1).max(80),
81
+ clientReleaseId: NonEmptyStringSchema.max(256),
82
+ })
83
+ .strict()
84
+ export type ManagementDeviceEnrollmentRequest = z.input<typeof ManagementDeviceEnrollmentRequestSchema>
85
+
86
+ export const ManagementDeviceEnrollmentResponseSchema = z
87
+ .object({
88
+ deviceId: ManagementDeviceIdSchema,
89
+ deviceSecret: Base64UrlSchema,
90
+ })
91
+ .strict()
92
+ export type ManagementDeviceEnrollmentResponse = z.output<typeof ManagementDeviceEnrollmentResponseSchema>
93
+
94
+ export const ManagementSessionRequestSchema = z
95
+ .object({ deviceId: ManagementDeviceIdSchema, deviceSecret: Base64UrlSchema })
96
+ .strict()
97
+ export type ManagementSessionRequest = z.input<typeof ManagementSessionRequestSchema>
98
+
99
+ export const ManagementSessionResponseSchema = z
100
+ .object({ authenticated: z.literal(true), deviceId: ManagementDeviceIdSchema, csrfToken: Base64UrlSchema })
101
+ .strict()
102
+ export type ManagementSessionResponse = z.output<typeof ManagementSessionResponseSchema>
103
+
104
+ export const ManagementDeviceViewSchema = z
105
+ .object({
106
+ id: ManagementDeviceIdSchema,
107
+ label: z.string().trim().min(1).max(80),
108
+ createdAt: z.number().int().nonnegative(),
109
+ lastUsedAt: z.number().int().nonnegative().optional(),
110
+ revokedAt: z.number().int().nonnegative().optional(),
111
+ /** The device this request is signed in with. */
112
+ current: z.boolean().optional(),
113
+ })
114
+ .strict()
115
+ export type ManagementDeviceView = z.output<typeof ManagementDeviceViewSchema>
116
+
117
+ export const ClientNotificationSchema = z
118
+ .object({
119
+ id: z.string().trim().min(1).max(160),
120
+ kind: z.enum(['action-required']),
121
+ title: z.string().trim().min(1).max(80),
122
+ body: z.string().trim().min(1).max(240),
123
+ occurredAt: z.number().int().nonnegative(),
124
+ route: z
125
+ .string()
126
+ .regex(
127
+ /^\/(?:(?:live|channels|agents|workshop|wiring|settings|apps|work|connections|users|extensions)(?:\/[^?#]*)?)?$/u,
128
+ )
129
+ .optional(),
130
+ })
131
+ .strict()
132
+ export type ClientNotification = z.output<typeof ClientNotificationSchema>
133
+
134
+ export const MANAGEMENT_PAIR_PROOF_PREFIX = 'nxt-management-pair-v1' as const
135
+
136
+ export const managementPairProofMessage = (input: {
137
+ readonly challengeId: string
138
+ readonly serverNonce: string
139
+ readonly clientNonce: string
140
+ readonly instanceId: ServerInstanceId
141
+ readonly spkiSha256: string
142
+ }): string =>
143
+ [
144
+ MANAGEMENT_PAIR_PROOF_PREFIX,
145
+ input.challengeId,
146
+ input.serverNonce,
147
+ input.clientNonce,
148
+ input.instanceId,
149
+ input.spkiSha256,
150
+ ].join('\n')
151
+
152
+ export const INSECURE_HTTP_MANAGEMENT_PAIR_PROOF_PREFIX = 'nxt-management-pair-insecure-http-v1' as const
153
+
154
+ export const insecureHttpManagementPairProofMessage = (input: {
155
+ readonly challengeId: string
156
+ readonly serverNonce: string
157
+ readonly clientNonce: string
158
+ readonly instanceId: ServerInstanceId
159
+ readonly transportBinding: string
160
+ }): string =>
161
+ [
162
+ INSECURE_HTTP_MANAGEMENT_PAIR_PROOF_PREFIX,
163
+ input.challengeId,
164
+ input.serverNonce,
165
+ input.clientNonce,
166
+ input.instanceId,
167
+ input.transportBinding,
168
+ ].join('\n')
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod'
2
+
3
+ export const RuntimeCompatibilityDiagnosticSchema = z
4
+ .object({
5
+ objectKind: z.enum(['agent', 'model-provider', 'extension', 'dsh-plugin', 'adapter', 'client-page']),
6
+ objectId: z.string().min(1),
7
+ objectVersion: z.string().min(1),
8
+ configurationRevision: z.string(),
9
+ runtimeFingerprint: z.string().min(1),
10
+ status: z.enum(['checking', 'compatible', 'isolated']),
11
+ phase: z.enum(['configuration', 'dependency', 'build', 'load', 'render', 'restore', 'dispose']),
12
+ reason: z.string().max(2048).optional(),
13
+ retryable: z.boolean(),
14
+ checkedAt: z.number().int().nonnegative(),
15
+ })
16
+ .strict()
17
+ export type RuntimeCompatibilityDiagnostic = z.infer<typeof RuntimeCompatibilityDiagnosticSchema>
18
+
19
+ export const HostUpgradeSummarySchema = z
20
+ .object({
21
+ runtimeVersion: z.string().min(1),
22
+ sessionCompatibilityId: z.string().min(1),
23
+ backupId: z.string().optional(),
24
+ resetContexts: z.boolean(),
25
+ diagnostics: z.array(RuntimeCompatibilityDiagnosticSchema),
26
+ })
27
+ .strict()
28
+ export type HostUpgradeSummary = z.infer<typeof HostUpgradeSummarySchema>