@tx5dr/contracts 2.0.0 → 2.5.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/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schema/__tests__/assisted-queue.schema.test.js +1 -0
- package/dist/schema/__tests__/assisted-queue.schema.test.js.map +1 -1
- package/dist/schema/__tests__/meter.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/meter.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/meter.schema.test.js +27 -0
- package/dist/schema/__tests__/meter.schema.test.js.map +1 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.js +70 -0
- package/dist/schema/__tests__/operator-context-report.schema.test.js.map +1 -0
- package/dist/schema/__tests__/plugin-market.schema.test.js +107 -3
- package/dist/schema/__tests__/plugin-market.schema.test.js.map +1 -1
- package/dist/schema/__tests__/qso.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/qso.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/qso.schema.test.js +70 -0
- package/dist/schema/__tests__/qso.schema.test.js.map +1 -0
- package/dist/schema/__tests__/radio-power-support.test.js +4 -1
- package/dist/schema/__tests__/radio-power-support.test.js.map +1 -1
- package/dist/schema/__tests__/radio.schema.test.js +52 -1
- package/dist/schema/__tests__/radio.schema.test.js.map +1 -1
- package/dist/schema/__tests__/remote-access.schema.test.js +1 -1
- package/dist/schema/__tests__/remote-access.schema.test.js.map +1 -1
- package/dist/schema/__tests__/spectrum.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/spectrum.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/spectrum.schema.test.js +107 -0
- package/dist/schema/__tests__/spectrum.schema.test.js.map +1 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.d.ts +2 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.d.ts.map +1 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.js +95 -0
- package/dist/schema/__tests__/strategy-transmission.schema.test.js.map +1 -0
- package/dist/schema/api-response.schema.d.ts +235 -0
- package/dist/schema/api-response.schema.d.ts.map +1 -1
- package/dist/schema/api-response.schema.js +9 -0
- package/dist/schema/api-response.schema.js.map +1 -1
- package/dist/schema/auth.schema.d.ts +2 -2
- package/dist/schema/cpu-profile.schema.d.ts +2 -2
- package/dist/schema/device-ui.schema.d.ts +10 -10
- package/dist/schema/image-radio.schema.d.ts +2597 -0
- package/dist/schema/image-radio.schema.d.ts.map +1 -0
- package/dist/schema/image-radio.schema.js +283 -0
- package/dist/schema/image-radio.schema.js.map +1 -0
- package/dist/schema/logbook.schema.d.ts +203 -15
- package/dist/schema/logbook.schema.d.ts.map +1 -1
- package/dist/schema/logbook.schema.js +1 -0
- package/dist/schema/logbook.schema.js.map +1 -1
- package/dist/schema/mode.schema.d.ts +2 -0
- package/dist/schema/mode.schema.d.ts.map +1 -1
- package/dist/schema/mode.schema.js +16 -0
- package/dist/schema/mode.schema.js.map +1 -1
- package/dist/schema/openwebrx.schema.d.ts +2 -2
- package/dist/schema/operator.schema.d.ts +2676 -0
- package/dist/schema/operator.schema.d.ts.map +1 -1
- package/dist/schema/operator.schema.js +4 -19
- package/dist/schema/operator.schema.js.map +1 -1
- package/dist/schema/plugin.schema.d.ts +1780 -475
- package/dist/schema/plugin.schema.d.ts.map +1 -1
- package/dist/schema/plugin.schema.js +108 -12
- package/dist/schema/plugin.schema.js.map +1 -1
- package/dist/schema/qso.schema.d.ts +239 -1
- package/dist/schema/qso.schema.d.ts.map +1 -1
- package/dist/schema/qso.schema.js +61 -0
- package/dist/schema/qso.schema.js.map +1 -1
- package/dist/schema/radio-capability.schema.d.ts +1 -1
- package/dist/schema/radio-capability.schema.d.ts.map +1 -1
- package/dist/schema/radio-capability.schema.js +1 -0
- package/dist/schema/radio-capability.schema.js.map +1 -1
- package/dist/schema/radio-power.schema.d.ts +15 -0
- package/dist/schema/radio-power.schema.d.ts.map +1 -1
- package/dist/schema/radio-profile.schema.d.ts +251 -0
- package/dist/schema/radio-profile.schema.d.ts.map +1 -1
- package/dist/schema/radio-profile.schema.js +7 -0
- package/dist/schema/radio-profile.schema.js.map +1 -1
- package/dist/schema/radio.schema.d.ts +174 -3
- package/dist/schema/radio.schema.d.ts.map +1 -1
- package/dist/schema/radio.schema.js +31 -2
- package/dist/schema/radio.schema.js.map +1 -1
- package/dist/schema/rigctld.schema.d.ts +6 -6
- package/dist/schema/slot-info.schema.d.ts +13 -0
- package/dist/schema/slot-info.schema.d.ts.map +1 -1
- package/dist/schema/slot-info.schema.js +2 -1
- package/dist/schema/slot-info.schema.js.map +1 -1
- package/dist/schema/spectrum-config.schema.d.ts +638 -0
- package/dist/schema/spectrum-config.schema.d.ts.map +1 -0
- package/dist/schema/spectrum-config.schema.js +129 -0
- package/dist/schema/spectrum-config.schema.js.map +1 -0
- package/dist/schema/spectrum.schema.d.ts +1313 -20
- package/dist/schema/spectrum.schema.d.ts.map +1 -1
- package/dist/schema/spectrum.schema.js +72 -0
- package/dist/schema/spectrum.schema.js.map +1 -1
- package/dist/schema/transmission.schema.d.ts +7 -0
- package/dist/schema/transmission.schema.d.ts.map +1 -1
- package/dist/schema/tx-audio-input.schema.d.ts +8 -0
- package/dist/schema/tx-audio-input.schema.d.ts.map +1 -0
- package/dist/schema/tx-audio-input.schema.js +19 -0
- package/dist/schema/tx-audio-input.schema.js.map +1 -0
- package/dist/schema/voice.schema.d.ts +1 -1
- package/dist/schema/voice.schema.d.ts.map +1 -1
- package/dist/schema/voice.schema.js +1 -1
- package/dist/schema/voice.schema.js.map +1 -1
- package/dist/schema/websocket.schema.d.ts +27480 -2525
- package/dist/schema/websocket.schema.d.ts.map +1 -1
- package/dist/schema/websocket.schema.js +298 -11
- package/dist/schema/websocket.schema.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/schema/__tests__/assisted-queue.schema.test.ts +1 -0
- package/src/schema/__tests__/meter.schema.test.ts +28 -0
- package/src/schema/__tests__/operator-context-report.schema.test.ts +77 -0
- package/src/schema/__tests__/plugin-market.schema.test.ts +116 -2
- package/src/schema/__tests__/qso.schema.test.ts +91 -0
- package/src/schema/__tests__/radio-power-support.test.ts +4 -1
- package/src/schema/__tests__/radio.schema.test.ts +60 -1
- package/src/schema/__tests__/remote-access.schema.test.ts +1 -1
- package/src/schema/__tests__/spectrum.schema.test.ts +119 -0
- package/src/schema/__tests__/strategy-transmission.schema.test.ts +106 -0
- package/src/schema/api-response.schema.ts +11 -0
- package/src/schema/image-radio.schema.ts +342 -0
- package/src/schema/logbook.schema.ts +1 -0
- package/src/schema/mode.schema.ts +16 -0
- package/src/schema/operator.schema.ts +4 -19
- package/src/schema/plugin.schema.ts +119 -13
- package/src/schema/qso.schema.ts +71 -0
- package/src/schema/radio-capability.schema.ts +1 -0
- package/src/schema/radio-profile.schema.ts +7 -0
- package/src/schema/radio.schema.ts +35 -2
- package/src/schema/slot-info.schema.ts +2 -1
- package/src/schema/spectrum-config.schema.ts +156 -0
- package/src/schema/spectrum.schema.ts +89 -0
- package/src/schema/tx-audio-input.schema.ts +22 -0
- package/src/schema/voice.schema.ts +1 -1
- package/src/schema/websocket.schema.ts +383 -12
- package/test/image-radio-schema.test.ts +107 -0
- package/test/plugin-slot-schema.test.ts +31 -0
- package/CLAUDE.md +0 -41
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { SlotPackSchema, SlotInfoSchema, SlotPackFrequencyContextSchema } from './slot-info.schema.js';
|
|
3
3
|
import { PluginDataPayloadSchema, PluginLogEntrySchema, PluginRuntimeLogEntrySchema, PluginRuntimeLogHistoryPayloadSchema, PluginSystemSnapshotSchema, PluginStatusSchema, PluginUserActionPayloadSchema, } from './plugin.schema.js';
|
|
4
4
|
import { ModeDescriptorSchema } from './mode.schema.js';
|
|
5
|
-
import { QSORecordSchema } from './qso.schema.js';
|
|
5
|
+
import { QSORecordSchema, } from './qso.schema.js';
|
|
6
6
|
import { LogBookStatisticsSchema, LogbookHealthSchema, LogbookOperationErrorCodeSchema, } from './logbook.schema.js';
|
|
7
7
|
import { RadioInfoSchema, HamlibConfigSchema, TunerCapabilitiesSchema, RadioConnectionStatusSchema, ReconnectProgressSchema, CoreRadioCapabilitiesSchema, CoreCapabilityDiagnosticsSchema } from './radio.schema.js';
|
|
8
8
|
import { UserRole } from './auth.schema.js';
|
|
@@ -10,8 +10,9 @@ import { CWDecoderEventSchema, CWDecoderStatusSchema } from './cw-decoder.schema
|
|
|
10
10
|
import { CapabilityListSchema, CapabilityStateSchema, WriteCapabilityPayloadSchema } from './radio-capability.schema.js';
|
|
11
11
|
import { RadioPowerStateEventSchema } from './radio-power.schema.js';
|
|
12
12
|
import { AudioSidecarStatusPayloadSchema } from './audio-sidecar.schema.js';
|
|
13
|
-
import { SpectrumCapabilitiesSchema, SpectrumFrameSchema, SpectrumKindSchema, SpectrumSessionControlActionSchema, SpectrumSessionControlIdSchema, SpectrumSessionStateSchema } from './spectrum.schema.js';
|
|
13
|
+
import { SpectrumCapabilitiesSchema, SpectrumFrameSchema, SpectrumKindSchema, SpectrumSessionControlActionSchema, SpectrumSessionControlIdSchema, SpectrumSessionStateSchema, SpectrumViewportSchema } from './spectrum.schema.js';
|
|
14
14
|
import { ClockStatusSummarySchema } from './system.schema.js';
|
|
15
|
+
import { ImageRadioStatusSchema, ImageRxEventSchema, ImageRxSubscriptionSchema, FaxCalibrationCommandResultSchema, FaxCalibrationResetCommandSchema, FaxCalibrationSetCommandSchema, SstvTxCancelCommandSchema, SstvTxCommandResultSchema, SstvTxStartCommandSchema, SstvTxStatusSchema, } from './image-radio.schema.js';
|
|
15
16
|
// WebSocket消息类型枚举
|
|
16
17
|
export var WSMessageType;
|
|
17
18
|
(function (WSMessageType) {
|
|
@@ -26,6 +27,16 @@ export var WSMessageType;
|
|
|
26
27
|
WSMessageType["STOP_ENGINE"] = "stopEngine";
|
|
27
28
|
WSMessageType["GET_STATUS"] = "getStatus";
|
|
28
29
|
WSMessageType["SET_MODE"] = "setMode";
|
|
30
|
+
WSMessageType["SUBSCRIBE_IMAGE_RX"] = "subscribeImageRx";
|
|
31
|
+
WSMessageType["IMAGE_RADIO_STATUS"] = "imageRadioStatus";
|
|
32
|
+
WSMessageType["IMAGE_RX_EVENT"] = "imageRxEvent";
|
|
33
|
+
WSMessageType["SSTV_TX_START"] = "sstvTxStart";
|
|
34
|
+
WSMessageType["SSTV_TX_CANCEL"] = "sstvTxCancel";
|
|
35
|
+
WSMessageType["SSTV_TX_STATUS"] = "sstvTxStatus";
|
|
36
|
+
WSMessageType["SSTV_TX_COMMAND_RESULT"] = "sstvTxCommandResult";
|
|
37
|
+
WSMessageType["FAX_CALIBRATION_SET"] = "faxCalibrationSet";
|
|
38
|
+
WSMessageType["FAX_CALIBRATION_RESET"] = "faxCalibrationReset";
|
|
39
|
+
WSMessageType["FAX_CALIBRATION_COMMAND_RESULT"] = "faxCalibrationCommandResult";
|
|
29
40
|
// ===== 引擎事件 =====
|
|
30
41
|
WSMessageType["MODE_CHANGED"] = "modeChanged";
|
|
31
42
|
WSMessageType["SLOT_START"] = "slotStart";
|
|
@@ -37,6 +48,7 @@ export var WSMessageType;
|
|
|
37
48
|
WSMessageType["SPECTRUM_FRAME"] = "spectrumFrame";
|
|
38
49
|
WSMessageType["SPECTRUM_SESSION_STATE_CHANGED"] = "spectrumSessionStateChanged";
|
|
39
50
|
WSMessageType["INVOKE_SPECTRUM_CONTROL"] = "invokeSpectrumControl";
|
|
51
|
+
WSMessageType["SPECTRUM_VIEWPORT_CHANGED"] = "spectrumViewportChanged";
|
|
40
52
|
WSMessageType["DECODE_ERROR"] = "decodeError";
|
|
41
53
|
WSMessageType["SYSTEM_STATUS"] = "systemStatus";
|
|
42
54
|
WSMessageType["BOOTSTRAP_STATUS_CHANGED"] = "bootstrapStatusChanged";
|
|
@@ -49,6 +61,8 @@ export var WSMessageType;
|
|
|
49
61
|
WSMessageType["OPERATOR_STATUS_UPDATE"] = "operatorStatusUpdate";
|
|
50
62
|
WSMessageType["SET_OPERATOR_CONTEXT"] = "setOperatorContext";
|
|
51
63
|
WSMessageType["SET_OPERATOR_RUNTIME_STATE"] = "setOperatorRuntimeState";
|
|
64
|
+
WSMessageType["SET_OPERATOR_STREAM_STATE"] = "setOperatorStreamState";
|
|
65
|
+
WSMessageType["INVOKE_OPERATOR_STRATEGY_ACTION"] = "invokeOperatorStrategyAction";
|
|
52
66
|
WSMessageType["SET_OPERATOR_RUNTIME_SLOT_CONTENT"] = "setOperatorRuntimeSlotContent";
|
|
53
67
|
WSMessageType["SET_OPERATOR_TRANSMIT_CYCLES"] = "setOperatorTransmitCycles";
|
|
54
68
|
WSMessageType["START_OPERATOR"] = "startOperator";
|
|
@@ -199,7 +213,7 @@ export const SystemStatusSchema = z.object({
|
|
|
199
213
|
connectionHealthy: z.boolean(),
|
|
200
214
|
}).optional(),
|
|
201
215
|
/** 引擎模式:digital(FT8/FT4)、voice(语音通联)或 cw(莫尔斯码) */
|
|
202
|
-
engineMode: z.enum(['digital', 'voice', 'cw']).default('digital'),
|
|
216
|
+
engineMode: z.enum(['digital', 'voice', 'cw', 'image']).default('digital'),
|
|
203
217
|
/** 当前电台调制模式(语音模式下使用,如 USB/LSB/FM/AM) */
|
|
204
218
|
currentRadioMode: z.string().optional(),
|
|
205
219
|
/** 引擎状态机当前状态 */
|
|
@@ -283,10 +297,11 @@ export const DecodeErrorInfoSchema = z.object({
|
|
|
283
297
|
/**
|
|
284
298
|
* Current dial-frequency projection broadcast to plugins and clients.
|
|
285
299
|
*
|
|
286
|
-
* `frequency` is RF dial
|
|
287
|
-
* `band` and `description` are display labels; `radioMode` is the
|
|
288
|
-
* modulation when known. `
|
|
289
|
-
*
|
|
300
|
+
* `frequency` is the logical RF dial target in hertz; `mode` is the TX-5DR
|
|
301
|
+
* engine mode; `band` and `description` are display labels; `radioMode` is the
|
|
302
|
+
* underlying modulation when known. `observedFrequency` is the latest physical
|
|
303
|
+
* readback. `source` distinguishes application changes from radio observations;
|
|
304
|
+
* `revision` and `connectionGeneration` reject stale events.
|
|
290
305
|
*/
|
|
291
306
|
export const FrequencyStateSchema = z.object({
|
|
292
307
|
frequency: z.number(),
|
|
@@ -296,6 +311,20 @@ export const FrequencyStateSchema = z.object({
|
|
|
296
311
|
radioMode: z.string().optional(),
|
|
297
312
|
radioConnected: z.boolean(),
|
|
298
313
|
source: z.enum(['program', 'radio']).optional(),
|
|
314
|
+
/** Monotonic operating-state revision for stale-event suppression. */
|
|
315
|
+
revision: z.number().int().nonnegative().optional(),
|
|
316
|
+
/** Physical CAT session identity associated with this snapshot. */
|
|
317
|
+
connectionGeneration: z.number().int().nonnegative().optional(),
|
|
318
|
+
/** Physical confirmation status for the requested operating state. */
|
|
319
|
+
confirmation: z.enum(['confirmed', 'pending', 'mismatch', 'offline']).optional(),
|
|
320
|
+
/** Last frequency read back from the physical radio, when available. */
|
|
321
|
+
observedFrequency: z.number().optional(),
|
|
322
|
+
/** Requested logical frequency when it differs from the observed value. */
|
|
323
|
+
requestedFrequency: z.number().optional(),
|
|
324
|
+
/** Correlates a snapshot with one programmatic operating-state mutation. */
|
|
325
|
+
operationId: z.string().optional(),
|
|
326
|
+
/** Physical radio-mode confirmation status. */
|
|
327
|
+
modeConfirmation: z.enum(['confirmed', 'unconfirmed', 'unknown']).optional(),
|
|
299
328
|
});
|
|
300
329
|
export const SpectrumControlInvocationSchema = z.object({
|
|
301
330
|
id: SpectrumSessionControlIdSchema,
|
|
@@ -307,7 +336,7 @@ export const PTTStatusSchema = z.object({
|
|
|
307
336
|
operatorIds: z.array(z.string()),
|
|
308
337
|
phase: z.enum(['idle', 'starting', 'on_air', 'draining', 'stopping', 'unknown']).optional(),
|
|
309
338
|
frameId: z.string().optional(),
|
|
310
|
-
source: z.enum(['digital', 'voice', 'voice-keyer', 'cw', 'tune-tone', 'manual', 'test']).optional(),
|
|
339
|
+
source: z.enum(['digital', 'voice', 'voice-keyer', 'cw', 'sstv', 'tune-tone', 'manual', 'test']).optional(),
|
|
311
340
|
});
|
|
312
341
|
export const TuneToneStartPayloadSchema = z.object({
|
|
313
342
|
operatorId: z.string().optional(),
|
|
@@ -335,8 +364,90 @@ export const StrategyRuntimeContextSchema = z.object({
|
|
|
335
364
|
reportReceived: z.number().optional(),
|
|
336
365
|
actualFrequency: z.number().optional(),
|
|
337
366
|
});
|
|
367
|
+
export const StrategyStateOptionSchema = z.object({
|
|
368
|
+
id: z.string().min(1),
|
|
369
|
+
label: z.string().min(1).optional(),
|
|
370
|
+
transmitText: z.string().optional(),
|
|
371
|
+
});
|
|
372
|
+
export const StrategyActionInputSchema = z.discriminatedUnion('kind', [
|
|
373
|
+
z.object({
|
|
374
|
+
kind: z.literal('text'),
|
|
375
|
+
label: z.string().optional(),
|
|
376
|
+
value: z.string().optional(),
|
|
377
|
+
placeholder: z.string().optional(),
|
|
378
|
+
maxLength: z.number().int().positive().optional(),
|
|
379
|
+
}),
|
|
380
|
+
z.object({
|
|
381
|
+
kind: z.enum(['number', 'audio-frequency']),
|
|
382
|
+
label: z.string().optional(),
|
|
383
|
+
value: z.number().optional(),
|
|
384
|
+
min: z.number().optional(),
|
|
385
|
+
max: z.number().optional(),
|
|
386
|
+
step: z.number().positive().optional(),
|
|
387
|
+
unit: z.string().optional(),
|
|
388
|
+
spectrumPick: z.boolean().optional(),
|
|
389
|
+
}),
|
|
390
|
+
]);
|
|
391
|
+
export const StrategyActionDescriptorSchema = z.object({
|
|
392
|
+
id: z.string().min(1),
|
|
393
|
+
label: z.string().min(1),
|
|
394
|
+
description: z.string().optional(),
|
|
395
|
+
icon: z.string().optional(),
|
|
396
|
+
tone: z.enum(['default', 'primary', 'success', 'warning', 'danger']).optional(),
|
|
397
|
+
presentation: z.enum(['primary', 'secondary', 'menu', 'segmented']).optional(),
|
|
398
|
+
groupId: z.string().optional(),
|
|
399
|
+
selected: z.boolean().optional(),
|
|
400
|
+
disabledReason: z.string().optional(),
|
|
401
|
+
previewText: z.string().optional(),
|
|
402
|
+
confirmation: z.object({
|
|
403
|
+
title: z.string().min(1),
|
|
404
|
+
description: z.string().optional(),
|
|
405
|
+
confirmLabel: z.string().optional(),
|
|
406
|
+
cancelLabel: z.string().optional(),
|
|
407
|
+
}).optional(),
|
|
408
|
+
input: StrategyActionInputSchema.optional(),
|
|
409
|
+
navigation: z.object({
|
|
410
|
+
kind: z.literal('plugin-page'),
|
|
411
|
+
pageId: z.string().min(1),
|
|
412
|
+
}).optional(),
|
|
413
|
+
});
|
|
414
|
+
export const StrategyAttentionSchema = z.object({
|
|
415
|
+
id: z.string().min(1),
|
|
416
|
+
tone: z.enum(['info', 'warning', 'danger', 'success']),
|
|
417
|
+
title: z.string().min(1),
|
|
418
|
+
description: z.string().optional(),
|
|
419
|
+
params: z.record(z.string(), z.union([z.string(), z.number()])).optional(),
|
|
420
|
+
notify: z.boolean().optional(),
|
|
421
|
+
expiresAt: z.number().optional(),
|
|
422
|
+
actionIds: z.array(z.string()).optional(),
|
|
423
|
+
});
|
|
424
|
+
export const StrategyCompletionProjectionSchema = z.object({
|
|
425
|
+
state: z.enum(['not-ready', 'ready', 'committing', 'committed', 'failed']),
|
|
426
|
+
label: z.string().optional(),
|
|
427
|
+
recordId: z.string().optional(),
|
|
428
|
+
});
|
|
429
|
+
export const StrategyStreamSnapshotSchema = z.object({
|
|
430
|
+
streamId: z.string().min(1),
|
|
431
|
+
currentState: z.string(),
|
|
432
|
+
targetCallsign: z.string().optional(),
|
|
433
|
+
targetGrid: z.string().optional(),
|
|
434
|
+
audioFrequencyHz: z.number().min(0).max(5000),
|
|
435
|
+
qsoLifecycleEpoch: z.number().int().nonnegative(),
|
|
436
|
+
stateOptions: z.array(StrategyStateOptionSchema).optional(),
|
|
437
|
+
actions: z.array(StrategyActionDescriptorSchema).optional(),
|
|
438
|
+
attentions: z.array(StrategyAttentionSchema).optional(),
|
|
439
|
+
completion: StrategyCompletionProjectionSchema.optional(),
|
|
440
|
+
lastReceivedText: z.string().optional(),
|
|
441
|
+
nextTransmitText: z.string().optional(),
|
|
442
|
+
});
|
|
443
|
+
export const StrategyTransmissionSchema = z.object({
|
|
444
|
+
streamId: z.string().min(1),
|
|
445
|
+
text: z.string().min(1),
|
|
446
|
+
audioFrequencyHz: z.number().min(0).max(5000),
|
|
447
|
+
});
|
|
338
448
|
export const AssistedQueueDisplayStateSchema = z.enum([
|
|
339
449
|
'TX1', 'TX2', 'TX3', 'TX4', 'TX5', 'engaged', 'closing', 'paused', 'no-response', 'later', 'review',
|
|
450
|
+
'candidate', 'authorized', 'dupe',
|
|
340
451
|
]);
|
|
341
452
|
export const AssistedQueuePauseReasonSchema = z.enum(['target-busy', 'stale']);
|
|
342
453
|
export const AssistedQueueToneSchema = z.enum(['neutral', 'active', 'success', 'warning', 'danger']);
|
|
@@ -356,12 +467,69 @@ export const AssistedQueueRowSchema = z.object({
|
|
|
356
467
|
targetGrid: z.string().optional(),
|
|
357
468
|
lastSnr: z.number().optional(),
|
|
358
469
|
lastHeardCyclesAgo: z.number().int().nonnegative().optional(),
|
|
470
|
+
lastHeardCycle: z.union([z.literal(0), z.literal(1)]).optional(),
|
|
471
|
+
streamId: z.string().optional(),
|
|
472
|
+
audioFrequencyHz: z.number().optional(),
|
|
473
|
+
authorizationId: z.string().optional(),
|
|
474
|
+
actions: z.array(StrategyActionDescriptorSchema).optional(),
|
|
359
475
|
});
|
|
360
476
|
export const AssistedQueueSnapshotSchema = z.object({
|
|
361
477
|
version: z.number().int().nonnegative(),
|
|
362
478
|
activeEntryId: z.string().optional(),
|
|
479
|
+
activeEntryIds: z.array(z.string()).optional(),
|
|
480
|
+
maxActiveStreams: z.number().int().min(1).max(5).optional(),
|
|
481
|
+
requestedMaxActiveStreams: z.number().int().min(1).max(5).optional(),
|
|
363
482
|
rows: z.array(AssistedQueueRowSchema),
|
|
364
483
|
});
|
|
484
|
+
/** Null clears an unsettable runtime report field over JSON/WebSocket. */
|
|
485
|
+
export const OperatorContextReportFieldSchema = z.number().nullish();
|
|
486
|
+
export const StrategyMessagePresentationToneSchema = z.enum([
|
|
487
|
+
'neutral', 'primary', 'secondary', 'success', 'warning', 'danger',
|
|
488
|
+
]);
|
|
489
|
+
export const StrategyMessagePresentationBadgeSchema = z.object({
|
|
490
|
+
label: z.string().min(1),
|
|
491
|
+
tone: StrategyMessagePresentationToneSchema,
|
|
492
|
+
});
|
|
493
|
+
export const StrategyMessagePresentationTokenMatchSchema = z.object({
|
|
494
|
+
firstTokenIn: z.array(z.string().min(1)).optional(),
|
|
495
|
+
anyTokenIn: z.array(z.string().min(1)).optional(),
|
|
496
|
+
});
|
|
497
|
+
export const StrategyMessagePresentationClassSchema = z.object({
|
|
498
|
+
badge: StrategyMessagePresentationBadgeSchema.optional(),
|
|
499
|
+
badges: z.array(StrategyMessagePresentationBadgeSchema).optional(),
|
|
500
|
+
row: z.object({
|
|
501
|
+
tone: StrategyMessagePresentationToneSchema,
|
|
502
|
+
background: z.enum(['none', 'soft']).optional(),
|
|
503
|
+
accent: z.boolean().optional(),
|
|
504
|
+
}).optional(),
|
|
505
|
+
emphasisWhen: z.array(StrategyMessagePresentationTokenMatchSchema).min(1).optional(),
|
|
506
|
+
textDecoration: z.literal('line-through').optional(),
|
|
507
|
+
opacity: z.enum(['normal', 'muted']).optional(),
|
|
508
|
+
});
|
|
509
|
+
export const StrategyMessagePresentationProjectionSchema = z.object({
|
|
510
|
+
revision: z.number().int().nonnegative(),
|
|
511
|
+
mode: z.enum(['replace-logbook', 'augment']),
|
|
512
|
+
subject: z.literal('sender-callsign'),
|
|
513
|
+
partitionBy: z.enum(['band', 'mode', 'none']),
|
|
514
|
+
eligiblePartitions: z.array(z.string()).optional(),
|
|
515
|
+
defaultClass: z.string().optional(),
|
|
516
|
+
classes: z.record(z.string(), StrategyMessagePresentationClassSchema),
|
|
517
|
+
assignments: z.array(z.object({
|
|
518
|
+
subject: z.string().min(1),
|
|
519
|
+
partition: z.string().optional(),
|
|
520
|
+
classId: z.string().min(1),
|
|
521
|
+
})),
|
|
522
|
+
noveltyRules: z.array(z.object({
|
|
523
|
+
fact: z.literal('grid-field-2'),
|
|
524
|
+
knownValuesByPartition: z.record(z.string(), z.array(z.string().min(1))),
|
|
525
|
+
classId: z.string().min(1),
|
|
526
|
+
})).optional(),
|
|
527
|
+
tagRules: z.array(z.object({
|
|
528
|
+
id: z.string().min(1),
|
|
529
|
+
match: StrategyMessagePresentationTokenMatchSchema,
|
|
530
|
+
badge: StrategyMessagePresentationBadgeSchema,
|
|
531
|
+
})).optional(),
|
|
532
|
+
});
|
|
365
533
|
export const StrategyRuntimeSnapshotSchema = z.object({
|
|
366
534
|
currentState: z.string(),
|
|
367
535
|
slots: z.object({
|
|
@@ -375,8 +543,30 @@ export const StrategyRuntimeSnapshotSchema = z.object({
|
|
|
375
543
|
context: StrategyRuntimeContextSchema.optional(),
|
|
376
544
|
availableSlots: z.array(z.string()).optional(),
|
|
377
545
|
qsoLifecycleEpoch: z.number().int().nonnegative().optional(),
|
|
546
|
+
streams: z.array(StrategyStreamSnapshotSchema).optional(),
|
|
378
547
|
queue: AssistedQueueSnapshotSchema.optional(),
|
|
548
|
+
actions: z.array(StrategyActionDescriptorSchema).optional(),
|
|
549
|
+
attentions: z.array(StrategyAttentionSchema).optional(),
|
|
550
|
+
messagePresentation: StrategyMessagePresentationProjectionSchema.optional(),
|
|
551
|
+
transmitGate: z.object({
|
|
552
|
+
allowed: z.literal(false),
|
|
553
|
+
reason: z.string().min(1),
|
|
554
|
+
actionId: z.string().optional(),
|
|
555
|
+
}).optional(),
|
|
379
556
|
});
|
|
557
|
+
export const StrategyActionTargetSchema = z.discriminatedUnion('kind', [
|
|
558
|
+
z.object({ kind: z.literal('runtime') }),
|
|
559
|
+
z.object({
|
|
560
|
+
kind: z.literal('stream'),
|
|
561
|
+
streamId: z.string().min(1),
|
|
562
|
+
lifecycleEpoch: z.number().int().nonnegative(),
|
|
563
|
+
}),
|
|
564
|
+
z.object({
|
|
565
|
+
kind: z.literal('queue-entry'),
|
|
566
|
+
entryId: z.string().min(1),
|
|
567
|
+
queueVersion: z.number().int().nonnegative(),
|
|
568
|
+
}),
|
|
569
|
+
]);
|
|
380
570
|
export const LevelMeterDisplayStyleSchema = z.enum([
|
|
381
571
|
's-meter-dbm',
|
|
382
572
|
's-meter',
|
|
@@ -425,11 +615,12 @@ export const MeterDataSchema = z.object({
|
|
|
425
615
|
raw: z.number(),
|
|
426
616
|
percent: z.number(),
|
|
427
617
|
alert: z.boolean(),
|
|
618
|
+
unit: z.enum(['percent', 'dbfs']).optional(),
|
|
428
619
|
}).nullable(),
|
|
429
620
|
level: LevelMeterReadingSchema.nullable(),
|
|
430
621
|
power: z.object({
|
|
431
622
|
raw: z.number(),
|
|
432
|
-
percent: z.number(),
|
|
623
|
+
percent: z.number().nullable(),
|
|
433
624
|
watts: z.number().nullable(), // 绝对瓦数(仅当电台支持 RFPOWER_METER_WATTS 时非 null)
|
|
434
625
|
maxWatts: z.number().nullable(), // 当前频率+模式对应的量程瓦数
|
|
435
626
|
}).nullable(),
|
|
@@ -455,6 +646,46 @@ export const WSModeChangedMessageSchema = WSBaseMessageSchema.extend({
|
|
|
455
646
|
type: z.literal(WSMessageType.MODE_CHANGED),
|
|
456
647
|
data: ModeDescriptorSchema,
|
|
457
648
|
});
|
|
649
|
+
export const WSSubscribeImageRxMessageSchema = WSBaseMessageSchema.extend({
|
|
650
|
+
type: z.literal(WSMessageType.SUBSCRIBE_IMAGE_RX),
|
|
651
|
+
data: ImageRxSubscriptionSchema,
|
|
652
|
+
});
|
|
653
|
+
export const WSImageRadioStatusMessageSchema = WSBaseMessageSchema.extend({
|
|
654
|
+
type: z.literal(WSMessageType.IMAGE_RADIO_STATUS),
|
|
655
|
+
data: ImageRadioStatusSchema,
|
|
656
|
+
});
|
|
657
|
+
export const WSImageRxEventMessageSchema = WSBaseMessageSchema.extend({
|
|
658
|
+
type: z.literal(WSMessageType.IMAGE_RX_EVENT),
|
|
659
|
+
data: ImageRxEventSchema,
|
|
660
|
+
});
|
|
661
|
+
export const WSSstvTxStartMessageSchema = WSBaseMessageSchema.extend({
|
|
662
|
+
type: z.literal(WSMessageType.SSTV_TX_START),
|
|
663
|
+
data: SstvTxStartCommandSchema,
|
|
664
|
+
});
|
|
665
|
+
export const WSSstvTxCancelMessageSchema = WSBaseMessageSchema.extend({
|
|
666
|
+
type: z.literal(WSMessageType.SSTV_TX_CANCEL),
|
|
667
|
+
data: SstvTxCancelCommandSchema,
|
|
668
|
+
});
|
|
669
|
+
export const WSSstvTxStatusMessageSchema = WSBaseMessageSchema.extend({
|
|
670
|
+
type: z.literal(WSMessageType.SSTV_TX_STATUS),
|
|
671
|
+
data: SstvTxStatusSchema,
|
|
672
|
+
});
|
|
673
|
+
export const WSSstvTxCommandResultMessageSchema = WSBaseMessageSchema.extend({
|
|
674
|
+
type: z.literal(WSMessageType.SSTV_TX_COMMAND_RESULT),
|
|
675
|
+
data: SstvTxCommandResultSchema,
|
|
676
|
+
});
|
|
677
|
+
export const WSFaxCalibrationSetMessageSchema = WSBaseMessageSchema.extend({
|
|
678
|
+
type: z.literal(WSMessageType.FAX_CALIBRATION_SET),
|
|
679
|
+
data: FaxCalibrationSetCommandSchema,
|
|
680
|
+
});
|
|
681
|
+
export const WSFaxCalibrationResetMessageSchema = WSBaseMessageSchema.extend({
|
|
682
|
+
type: z.literal(WSMessageType.FAX_CALIBRATION_RESET),
|
|
683
|
+
data: FaxCalibrationResetCommandSchema,
|
|
684
|
+
});
|
|
685
|
+
export const WSFaxCalibrationCommandResultMessageSchema = WSBaseMessageSchema.extend({
|
|
686
|
+
type: z.literal(WSMessageType.FAX_CALIBRATION_COMMAND_RESULT),
|
|
687
|
+
data: FaxCalibrationCommandResultSchema,
|
|
688
|
+
});
|
|
458
689
|
export const WSSlotStartMessageSchema = WSBaseMessageSchema.extend({
|
|
459
690
|
type: z.literal(WSMessageType.SLOT_START),
|
|
460
691
|
data: SlotInfoSchema,
|
|
@@ -475,8 +706,13 @@ export const WSSubscribeSpectrumMessageSchema = WSBaseMessageSchema.extend({
|
|
|
475
706
|
type: z.literal(WSMessageType.SUBSCRIBE_SPECTRUM),
|
|
476
707
|
data: z.object({
|
|
477
708
|
kind: SpectrumKindSchema.nullable(),
|
|
709
|
+
viewport: SpectrumViewportSchema.optional(),
|
|
478
710
|
}),
|
|
479
711
|
});
|
|
712
|
+
export const WSSpectrumViewportChangedMessageSchema = WSBaseMessageSchema.extend({
|
|
713
|
+
type: z.literal(WSMessageType.SPECTRUM_VIEWPORT_CHANGED),
|
|
714
|
+
data: SpectrumViewportSchema.nullable(),
|
|
715
|
+
});
|
|
480
716
|
export const WSSpectrumSubscriptionChangedMessageSchema = WSBaseMessageSchema.extend({
|
|
481
717
|
type: z.literal(WSMessageType.SPECTRUM_SUBSCRIPTION_CHANGED),
|
|
482
718
|
data: z.object({
|
|
@@ -575,10 +811,13 @@ export const OperatorStatusSchema = z.object({
|
|
|
575
811
|
isTransmitting: z.boolean(), // 是否已授予策略自动发射许可(发射开关状态)
|
|
576
812
|
isInActivePTT: z.boolean().optional(), // 该操作员的音频是否正在被实际播放
|
|
577
813
|
hasTransmitIntent: z.boolean().optional(), // 当前策略是否有可在合法周期发射的有效内容
|
|
814
|
+
currentTransmissions: z.array(StrategyTransmissionSchema).optional(),
|
|
578
815
|
currentSlot: z.string().optional(),
|
|
579
816
|
context: z.object({
|
|
580
817
|
myCall: z.string(),
|
|
581
818
|
myGrid: z.string(),
|
|
819
|
+
/** Canonical active target set; `targetCall` remains the primary compatibility field. */
|
|
820
|
+
targetCalls: z.array(z.string()).optional(),
|
|
582
821
|
targetCall: z.string(),
|
|
583
822
|
targetGrid: z.string().optional(),
|
|
584
823
|
frequency: z.number().optional(),
|
|
@@ -638,8 +877,8 @@ export const WSSetOperatorContextMessageSchema = WSBaseMessageSchema.extend({
|
|
|
638
877
|
targetCallsign: z.string().optional(),
|
|
639
878
|
targetGrid: z.string().optional(),
|
|
640
879
|
frequency: z.number().optional(),
|
|
641
|
-
reportSent:
|
|
642
|
-
reportReceived:
|
|
880
|
+
reportSent: OperatorContextReportFieldSchema,
|
|
881
|
+
reportReceived: OperatorContextReportFieldSchema,
|
|
643
882
|
}),
|
|
644
883
|
}),
|
|
645
884
|
});
|
|
@@ -653,6 +892,25 @@ export const WSSetOperatorRuntimeStateMessageSchema = WSBaseMessageSchema.extend
|
|
|
653
892
|
state: OperatorRuntimeSlotSchema,
|
|
654
893
|
}),
|
|
655
894
|
});
|
|
895
|
+
/** Sets one strategy-owned stream to a protocol-approved state. */
|
|
896
|
+
export const WSSetOperatorStreamStateMessageSchema = WSBaseMessageSchema.extend({
|
|
897
|
+
type: z.literal(WSMessageType.SET_OPERATOR_STREAM_STATE),
|
|
898
|
+
data: z.object({
|
|
899
|
+
operatorId: z.string(),
|
|
900
|
+
streamId: z.string().min(1),
|
|
901
|
+
stateId: z.string().min(1),
|
|
902
|
+
expectedLifecycleEpoch: z.number().int().nonnegative(),
|
|
903
|
+
}),
|
|
904
|
+
});
|
|
905
|
+
export const WSInvokeOperatorStrategyActionMessageSchema = WSBaseMessageSchema.extend({
|
|
906
|
+
type: z.literal(WSMessageType.INVOKE_OPERATOR_STRATEGY_ACTION),
|
|
907
|
+
data: z.object({
|
|
908
|
+
operatorId: z.string().min(1),
|
|
909
|
+
target: StrategyActionTargetSchema,
|
|
910
|
+
actionId: z.string().min(1),
|
|
911
|
+
payload: z.unknown().optional(),
|
|
912
|
+
}),
|
|
913
|
+
});
|
|
656
914
|
/**
|
|
657
915
|
* 设置操作员运行时槽位内容消息
|
|
658
916
|
*/
|
|
@@ -1236,12 +1494,23 @@ export const WSMessageSchema = z.discriminatedUnion('type', [
|
|
|
1236
1494
|
WSPongMessageSchema,
|
|
1237
1495
|
// 服务端到客户端
|
|
1238
1496
|
WSModeChangedMessageSchema,
|
|
1497
|
+
WSSubscribeImageRxMessageSchema,
|
|
1498
|
+
WSImageRadioStatusMessageSchema,
|
|
1499
|
+
WSImageRxEventMessageSchema,
|
|
1500
|
+
WSSstvTxStartMessageSchema,
|
|
1501
|
+
WSSstvTxCancelMessageSchema,
|
|
1502
|
+
WSSstvTxStatusMessageSchema,
|
|
1503
|
+
WSSstvTxCommandResultMessageSchema,
|
|
1504
|
+
WSFaxCalibrationSetMessageSchema,
|
|
1505
|
+
WSFaxCalibrationResetMessageSchema,
|
|
1506
|
+
WSFaxCalibrationCommandResultMessageSchema,
|
|
1239
1507
|
WSSlotStartMessageSchema,
|
|
1240
1508
|
WSSubWindowMessageSchema,
|
|
1241
1509
|
WSSlotPackUpdatedMessageSchema,
|
|
1242
1510
|
WSSpectrumCapabilitiesMessageSchema,
|
|
1243
1511
|
WSSubscribeSpectrumMessageSchema,
|
|
1244
1512
|
WSSpectrumSubscriptionChangedMessageSchema,
|
|
1513
|
+
WSSpectrumViewportChangedMessageSchema,
|
|
1245
1514
|
WSSpectrumFrameMessageSchema,
|
|
1246
1515
|
WSSpectrumSessionStateChangedMessageSchema,
|
|
1247
1516
|
WSInvokeSpectrumControlMessageSchema,
|
|
@@ -1264,6 +1533,8 @@ export const WSMessageSchema = z.discriminatedUnion('type', [
|
|
|
1264
1533
|
WSOperatorStatusUpdateMessageSchema,
|
|
1265
1534
|
WSSetOperatorContextMessageSchema,
|
|
1266
1535
|
WSSetOperatorRuntimeStateMessageSchema,
|
|
1536
|
+
WSSetOperatorStreamStateMessageSchema,
|
|
1537
|
+
WSInvokeOperatorStrategyActionMessageSchema,
|
|
1267
1538
|
WSSetOperatorRuntimeSlotContentMessageSchema,
|
|
1268
1539
|
WSSetOperatorTransmitCyclesMessageSchema,
|
|
1269
1540
|
WSStartOperatorMessageSchema,
|
|
@@ -1336,7 +1607,9 @@ export const WSMessageSchema = z.discriminatedUnion('type', [
|
|
|
1336
1607
|
]);
|
|
1337
1608
|
export const TransmitRequestSchema = z.object({
|
|
1338
1609
|
operatorId: z.string(),
|
|
1610
|
+
streamId: z.string().min(1).optional(),
|
|
1339
1611
|
transmission: z.string(),
|
|
1612
|
+
audioFrequencyHz: z.number().min(0).max(5000).optional(),
|
|
1340
1613
|
/** 是否覆盖同一操作员在同一时隙的现有 TX 帧(自动重决策时为 true) */
|
|
1341
1614
|
replaceExisting: z.boolean().optional(),
|
|
1342
1615
|
source: z.enum(['standard-qso', 'plugin', 'late-decode', 'operator-edit', 'manual']).optional(),
|
|
@@ -1344,12 +1617,26 @@ export const TransmitRequestSchema = z.object({
|
|
|
1344
1617
|
/** Host command epoch used to tombstone stale encode/mix callbacks. */
|
|
1345
1618
|
decisionEpoch: z.number().int().nonnegative().optional(),
|
|
1346
1619
|
});
|
|
1620
|
+
export const TransmitBatchRequestSchema = z.object({
|
|
1621
|
+
operatorId: z.string(),
|
|
1622
|
+
transmissions: z.array(z.object({
|
|
1623
|
+
streamId: z.string().min(1),
|
|
1624
|
+
transmission: z.string(),
|
|
1625
|
+
audioFrequencyHz: z.number().min(0).max(5000),
|
|
1626
|
+
})).max(5),
|
|
1627
|
+
replaceExisting: z.boolean().optional(),
|
|
1628
|
+
source: z.enum(['standard-qso', 'plugin', 'late-decode', 'operator-edit', 'manual']).optional(),
|
|
1629
|
+
reason: z.string().optional(),
|
|
1630
|
+
decisionEpoch: z.number().int().nonnegative().optional(),
|
|
1631
|
+
});
|
|
1347
1632
|
// ===== 前端应用事件接口 =====
|
|
1348
1633
|
/**
|
|
1349
1634
|
* 发射完成事件信息
|
|
1350
1635
|
*/
|
|
1351
1636
|
export const TransmissionCompleteInfoSchema = z.object({
|
|
1352
1637
|
operatorId: z.string(),
|
|
1638
|
+
streamId: z.string().optional(),
|
|
1639
|
+
trackId: z.string().optional(),
|
|
1353
1640
|
success: z.boolean(),
|
|
1354
1641
|
frameId: z.string().optional(),
|
|
1355
1642
|
physicalConfirmed: z.boolean().optional(),
|