@tx5dr/plugin-api 1.7.12 → 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/README.md +475 -17
- package/dist/__tests__/adif.test.js +107 -0
- package/dist/__tests__/adif.test.js.map +1 -1
- package/dist/__tests__/capability-context.test.d.ts +2 -0
- package/dist/__tests__/capability-context.test.d.ts.map +1 -0
- package/dist/__tests__/capability-context.test.js +99 -0
- package/dist/__tests__/capability-context.test.js.map +1 -0
- package/dist/__tests__/testing-utils.test.js +234 -15
- package/dist/__tests__/testing-utils.test.js.map +1 -1
- package/dist/capabilities.d.ts +38 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +50 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/compatibility.d.ts +15 -0
- package/dist/compatibility.d.ts.map +1 -0
- package/dist/compatibility.js +71 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/contest-logbook-ui/assets/contest-log.css +1 -0
- package/dist/contest-logbook-ui/assets/contest-log.js +40 -0
- package/dist/contest-logbook-ui/contest-log.html +13 -0
- package/dist/context.d.ts +125 -54
- package/dist/context.d.ts.map +1 -1
- package/dist/definition.d.ts +98 -21
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +8 -1
- package/dist/definition.js.map +1 -1
- package/dist/ft8/StandardQSOPluginRuntime.d.ts +142 -0
- package/dist/ft8/StandardQSOPluginRuntime.d.ts.map +1 -0
- package/dist/ft8/StandardQSOPluginRuntime.js +1592 -0
- package/dist/ft8/StandardQSOPluginRuntime.js.map +1 -0
- package/dist/ft8/index.d.ts +22 -0
- package/dist/ft8/index.d.ts.map +1 -0
- package/dist/ft8/index.js +176 -0
- package/dist/ft8/index.js.map +1 -0
- package/dist/helpers.d.ts +417 -132
- package/dist/helpers.d.ts.map +1 -1
- package/dist/hooks.d.ts +56 -34
- package/dist/hooks.d.ts.map +1 -1
- package/dist/host-dependencies.d.ts +101 -0
- package/dist/host-dependencies.d.ts.map +1 -1
- package/dist/index.d.ts +20 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts +539 -13
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +9 -1
- package/dist/runtime.js.map +1 -1
- package/dist/settings.d.ts +31 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/simulation.d.ts +60 -0
- package/dist/simulation.d.ts.map +1 -0
- package/dist/simulation.js +2 -0
- package/dist/simulation.js.map +1 -0
- package/dist/sync.d.ts +98 -6
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +6 -0
- package/dist/sync.js.map +1 -1
- package/dist/testing/index.d.ts +74 -12
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +372 -105
- package/dist/testing/index.js.map +1 -1
- package/dist/toolkit/contest/CabrilloBuilder.d.ts +7 -0
- package/dist/toolkit/contest/CabrilloBuilder.d.ts.map +1 -0
- package/dist/toolkit/contest/CabrilloBuilder.js +11 -0
- package/dist/toolkit/contest/CabrilloBuilder.js.map +1 -0
- package/dist/toolkit/contest/ContestCategorySchema.d.ts +11 -0
- package/dist/toolkit/contest/ContestCategorySchema.d.ts.map +1 -0
- package/dist/toolkit/contest/ContestCategorySchema.js +6 -0
- package/dist/toolkit/contest/ContestCategorySchema.js.map +1 -0
- package/dist/toolkit/contest/ContestLogbook.d.ts +223 -0
- package/dist/toolkit/contest/ContestLogbook.d.ts.map +1 -0
- package/dist/toolkit/contest/ContestLogbook.js +845 -0
- package/dist/toolkit/contest/ContestLogbook.js.map +1 -0
- package/dist/toolkit/contest/ContestQsoEnvelopeAdapter.d.ts +28 -0
- package/dist/toolkit/contest/ContestQsoEnvelopeAdapter.d.ts.map +1 -0
- package/dist/toolkit/contest/ContestQsoEnvelopeAdapter.js +79 -0
- package/dist/toolkit/contest/ContestQsoEnvelopeAdapter.js.map +1 -0
- package/dist/toolkit/contest/ContestQsoProjector.d.ts +12 -0
- package/dist/toolkit/contest/ContestQsoProjector.d.ts.map +1 -0
- package/dist/toolkit/contest/ContestQsoProjector.js +13 -0
- package/dist/toolkit/contest/ContestQsoProjector.js.map +1 -0
- package/dist/toolkit/contest/ContestSessionNotifier.d.ts +9 -0
- package/dist/toolkit/contest/ContestSessionNotifier.d.ts.map +1 -0
- package/dist/toolkit/contest/ContestSessionNotifier.js +13 -0
- package/dist/toolkit/contest/ContestSessionNotifier.js.map +1 -0
- package/dist/toolkit/contest/ContestSessionRepository.d.ts +21 -0
- package/dist/toolkit/contest/ContestSessionRepository.d.ts.map +1 -0
- package/dist/toolkit/contest/ContestSessionRepository.js +27 -0
- package/dist/toolkit/contest/ContestSessionRepository.js.map +1 -0
- package/dist/toolkit/contest/DefaultContestSession.d.ts +105 -0
- package/dist/toolkit/contest/DefaultContestSession.d.ts.map +1 -0
- package/dist/toolkit/contest/DefaultContestSession.js +387 -0
- package/dist/toolkit/contest/DefaultContestSession.js.map +1 -0
- package/dist/toolkit/contest/DefaultContestWorkbench.d.ts +100 -0
- package/dist/toolkit/contest/DefaultContestWorkbench.d.ts.map +1 -0
- package/dist/toolkit/contest/DefaultContestWorkbench.js +33 -0
- package/dist/toolkit/contest/DefaultContestWorkbench.js.map +1 -0
- package/dist/toolkit/contest/FT8ContestDefinition.d.ts +83 -0
- package/dist/toolkit/contest/FT8ContestDefinition.d.ts.map +1 -0
- package/dist/toolkit/contest/FT8ContestDefinition.js +167 -0
- package/dist/toolkit/contest/FT8ContestDefinition.js.map +1 -0
- package/dist/toolkit/contest/FT8ContestModules.d.ts +178 -0
- package/dist/toolkit/contest/FT8ContestModules.d.ts.map +1 -0
- package/dist/toolkit/contest/FT8ContestModules.js +247 -0
- package/dist/toolkit/contest/FT8ContestModules.js.map +1 -0
- package/dist/toolkit/contest/FT8ContestPlugin.d.ts +55 -0
- package/dist/toolkit/contest/FT8ContestPlugin.d.ts.map +1 -0
- package/dist/toolkit/contest/FT8ContestPlugin.js +322 -0
- package/dist/toolkit/contest/FT8ContestPlugin.js.map +1 -0
- package/dist/toolkit/contest/FT8ContestTestKit.d.ts +12 -0
- package/dist/toolkit/contest/FT8ContestTestKit.d.ts.map +1 -0
- package/dist/toolkit/contest/FT8ContestTestKit.js +60 -0
- package/dist/toolkit/contest/FT8ContestTestKit.js.map +1 -0
- package/dist/toolkit/contest/contest-toolkit.test.d.ts +2 -0
- package/dist/toolkit/contest/contest-toolkit.test.d.ts.map +1 -0
- package/dist/toolkit/contest/contest-toolkit.test.js +1196 -0
- package/dist/toolkit/contest/contest-toolkit.test.js.map +1 -0
- package/dist/toolkit/contest/index.d.ts +14 -0
- package/dist/toolkit/contest/index.d.ts.map +1 -0
- package/dist/toolkit/contest/index.js +14 -0
- package/dist/toolkit/contest/index.js.map +1 -0
- package/dist/toolkit/index.d.ts +3 -0
- package/dist/toolkit/index.d.ts.map +1 -0
- package/dist/toolkit/index.js +3 -0
- package/dist/toolkit/index.js.map +1 -0
- package/dist/toolkit/parallel-qso/AuthorizationLease.d.ts +15 -0
- package/dist/toolkit/parallel-qso/AuthorizationLease.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/AuthorizationLease.js +25 -0
- package/dist/toolkit/parallel-qso/AuthorizationLease.js.map +1 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.d.ts +40 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.js +81 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.js.map +1 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.test.d.ts +2 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.test.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.test.js +31 -0
- package/dist/toolkit/parallel-qso/BoundedCallSessionController.test.js.map +1 -0
- package/dist/toolkit/parallel-qso/CompletionTracker.d.ts +20 -0
- package/dist/toolkit/parallel-qso/CompletionTracker.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/CompletionTracker.js +20 -0
- package/dist/toolkit/parallel-qso/CompletionTracker.js.map +1 -0
- package/dist/toolkit/parallel-qso/LaneFrequencyController.d.ts +19 -0
- package/dist/toolkit/parallel-qso/LaneFrequencyController.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/LaneFrequencyController.js +23 -0
- package/dist/toolkit/parallel-qso/LaneFrequencyController.js.map +1 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.d.ts +134 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.js +554 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.js.map +1 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.test.d.ts +2 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.test.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.test.js +470 -0
- package/dist/toolkit/parallel-qso/ParallelQSOCoordinator.test.js.map +1 -0
- package/dist/toolkit/parallel-qso/PostCompletionRecoveryLease.d.ts +20 -0
- package/dist/toolkit/parallel-qso/PostCompletionRecoveryLease.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/PostCompletionRecoveryLease.js +29 -0
- package/dist/toolkit/parallel-qso/PostCompletionRecoveryLease.js.map +1 -0
- package/dist/toolkit/parallel-qso/ProtocolLane.d.ts +50 -0
- package/dist/toolkit/parallel-qso/ProtocolLane.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/ProtocolLane.js +2 -0
- package/dist/toolkit/parallel-qso/ProtocolLane.js.map +1 -0
- package/dist/toolkit/parallel-qso/controllers.test.d.ts +2 -0
- package/dist/toolkit/parallel-qso/controllers.test.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/controllers.test.js +36 -0
- package/dist/toolkit/parallel-qso/controllers.test.js.map +1 -0
- package/dist/toolkit/parallel-qso/index.d.ts +8 -0
- package/dist/toolkit/parallel-qso/index.d.ts.map +1 -0
- package/dist/toolkit/parallel-qso/index.js +8 -0
- package/dist/toolkit/parallel-qso/index.js.map +1 -0
- package/dist/utils/adif.d.ts +1 -1
- package/dist/utils/adif.d.ts.map +1 -1
- package/dist/utils/adif.js +96 -51
- package/dist/utils/adif.js.map +1 -1
- package/dist/utils/qso-text-fields.d.ts +7 -1
- package/dist/utils/qso-text-fields.d.ts.map +1 -1
- package/dist/utils/qso-text-fields.js +74 -6
- package/dist/utils/qso-text-fields.js.map +1 -1
- package/package.json +28 -6
- package/src/bridge.d.ts +3 -0
- package/tokens.css +51 -0
package/dist/index.js
CHANGED
|
@@ -19,6 +19,13 @@
|
|
|
19
19
|
* export default { ... };
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
+
/** Core plugin definition and lifecycle interfaces. */
|
|
23
|
+
export { definePlugin } from './definition.js';
|
|
24
|
+
export { assertPluginApiCompatible, comparePluginApiVersions, PluginApiCompatibilityError, } from './compatibility.js';
|
|
25
|
+
export { PLUGIN_COMMAND_CAPABILITY_PERMISSIONS, PLUGIN_CONTEXT_CAPABILITY_KEYS, getPluginContextCapabilityKeys, } from './capabilities.js';
|
|
26
|
+
export { isQueuedStrategyRuntime } from './runtime.js';
|
|
27
|
+
/** Atomic contest-QSO contract and its durable private-field codec. */
|
|
28
|
+
export { CONTEST_QSO_ENVELOPE_MAX_BYTES, ContestQsoEnvelopeSchema, parseContestQsoEnvelope, serializeContestQsoEnvelope, } from '@tx5dr/contracts';
|
|
22
29
|
/** Callsign and DXCC helpers available to plugins. */
|
|
23
30
|
export { getCallsignInfo, listDXCCEntities, resolveDXCCEntity, } from '@tx5dr/core';
|
|
24
31
|
export { createSyncFailure, errorToSyncFailure, failureMessage, sanitizeSyncFailureText, } from './sync.js';
|
|
@@ -30,6 +37,10 @@ export { normalizeCallsign } from './utils/callsign.js';
|
|
|
30
37
|
export { parseADIFContent, parseADIFRecord, parseADIFFields, convertQSOToADIF, generateADIFFile, formatADIFDate, formatADIFTime, parseADIFDateTime, } from './utils/adif.js';
|
|
31
38
|
/** Plugin page scope path utilities. */
|
|
32
39
|
export { getPluginPageFileScopePath, getPluginPageScopePath, getPluginPageScopeSegments, getPluginPageStorePath, } from './utils/page-scope.js';
|
|
40
|
+
/** Composable FT8/FT4 contest rules, assembler and framework-neutral test kit. */
|
|
41
|
+
export * from './toolkit/contest/index.js';
|
|
42
|
+
/** Reusable standard FT8/FT4 QSO runtime for external strategy plugins. */
|
|
43
|
+
export * from './ft8/index.js';
|
|
33
44
|
/** QSO text field utilities. */
|
|
34
|
-
export { parseLegacyComment, resolveQsoComment, buildCommentFromMessageHistory, normalizeMessageHistory, sanitizeAdifFieldValue, } from './utils/qso-text-fields.js';
|
|
45
|
+
export { buildSignalReportComment, parseQsoTextFields, parseLegacyComment, parseMessageHistoryText, resolveQsoComment, buildCommentFromMessageHistory, normalizeMessageHistory, sanitizeAdifFieldValue, } from './utils/qso-text-fields.js';
|
|
35
46
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,uDAAuD;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qCAAqC,EACrC,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAoG3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAgFvD,uEAAuE;AACvE,OAAO,EACL,8BAA8B,EAC9B,wBAAwB,EACxB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAG1B,sDAAsD;AACtD,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAqGrB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAEnB,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,4CAA4C;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,wDAAwD;AACxD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,wCAAwC;AACxC,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAG/B,kFAAkF;AAClF,cAAc,4BAA4B,CAAC;AAE3C,2EAA2E;AAC3E,cAAc,gBAAgB,CAAC;AAE/B,gCAAgC;AAChC,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,8BAA8B,EAC9B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { ParsedFT8Message, FrameMessage, SlotInfo } from '@tx5dr/contracts';
|
|
2
|
-
import type { StrategyDecision
|
|
1
|
+
import type { ParsedFT8Message, FrameMessage, SlotInfo, QSORecord } from '@tx5dr/contracts';
|
|
2
|
+
import type { StrategyDecision } from './hooks.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Legacy identifiers for the six selectable FT8 transmit messages.
|
|
5
5
|
*
|
|
6
|
-
* These labels
|
|
7
|
-
*
|
|
6
|
+
* These labels describe message choices, not T/R time slots or parallel QSO
|
|
7
|
+
* streams. User-facing interfaces should call them Tx messages.
|
|
8
8
|
*/
|
|
9
9
|
export type StrategyRuntimeSlot = 'TX1' | 'TX2' | 'TX3' | 'TX4' | 'TX5' | 'TX6';
|
|
10
10
|
/**
|
|
@@ -39,9 +39,423 @@ export interface StrategyRuntimeSnapshot {
|
|
|
39
39
|
slots?: Partial<Record<StrategyRuntimeSlot, string>>;
|
|
40
40
|
/** Current conversation metadata tracked by the runtime. */
|
|
41
41
|
context?: StrategyRuntimeContext;
|
|
42
|
-
/** Optional list of user-visible next
|
|
42
|
+
/** Optional legacy list of user-visible next Tx messages or branch hints. */
|
|
43
43
|
availableSlots?: string[];
|
|
44
|
+
/** Host correlation token for QSO persistence; it is not an RF decision epoch. */
|
|
45
|
+
qsoLifecycleEpoch?: number;
|
|
46
|
+
/** Active protocol lanes owned by a parallel-capable strategy. */
|
|
47
|
+
streams?: StrategyStreamSnapshot[];
|
|
48
|
+
/** Optional compact projection exposed by queue-capable strategies. */
|
|
49
|
+
queue?: AssistedQueueSnapshot;
|
|
50
|
+
/** Plugin-declared operator controls rendered without business interpretation. */
|
|
51
|
+
actions?: StrategyActionDescriptor[];
|
|
52
|
+
/** Plugin-declared operator attention items. */
|
|
53
|
+
attentions?: StrategyAttention[];
|
|
54
|
+
/** Optional strategy-owned presentation for decoded message history. */
|
|
55
|
+
messagePresentation?: StrategyMessagePresentationProjection;
|
|
56
|
+
/** Strategy-owned operator-start gate, enforced by both Host UI and Server. */
|
|
57
|
+
transmitGate?: StrategyTransmitGate;
|
|
44
58
|
}
|
|
59
|
+
/** Semantic tone requested by strategy-owned message presentation rules. */
|
|
60
|
+
export type StrategyMessagePresentationTone = 'neutral' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger';
|
|
61
|
+
/** Compact label and semantic tone rendered beside a decoded message. */
|
|
62
|
+
export interface StrategyMessagePresentationBadge {
|
|
63
|
+
/** Literal label or plugin locale key. */
|
|
64
|
+
label: string;
|
|
65
|
+
/** Host-themed semantic tone; plugins cannot provide CSS. */
|
|
66
|
+
tone: StrategyMessagePresentationTone;
|
|
67
|
+
}
|
|
68
|
+
/** Bounded token matcher evaluated by the Host against normalized message tokens. */
|
|
69
|
+
export interface StrategyMessagePresentationTokenMatch {
|
|
70
|
+
/** Exact, case-insensitive token matching; arbitrary regular expressions are not accepted. */
|
|
71
|
+
firstTokenIn?: string[];
|
|
72
|
+
/** Matches when any normalized message token equals one of these values. */
|
|
73
|
+
anyTokenIn?: string[];
|
|
74
|
+
}
|
|
75
|
+
/** Named visual class assigned by a strategy presentation projection. */
|
|
76
|
+
export interface StrategyMessagePresentationClass {
|
|
77
|
+
/** @deprecated Use `badges`; retained for API v2 snapshot compatibility. */
|
|
78
|
+
badge?: {
|
|
79
|
+
label: string;
|
|
80
|
+
tone: StrategyMessagePresentationTone;
|
|
81
|
+
};
|
|
82
|
+
/** Badges revealed when the optional emphasis matcher succeeds. */
|
|
83
|
+
badges?: StrategyMessagePresentationBadge[];
|
|
84
|
+
/** Semantic row treatment; Host maps tones to its theme and never accepts plugin CSS. */
|
|
85
|
+
row?: {
|
|
86
|
+
tone: StrategyMessagePresentationTone;
|
|
87
|
+
background?: 'none' | 'soft';
|
|
88
|
+
accent?: boolean;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Only expose badges and soft row emphasis when any matcher succeeds.
|
|
92
|
+
* The accent, text decoration and opacity remain visible when none match.
|
|
93
|
+
*/
|
|
94
|
+
emphasisWhen?: StrategyMessagePresentationTokenMatch[];
|
|
95
|
+
/** Optional semantic strike-through for completed or excluded rows. */
|
|
96
|
+
textDecoration?: 'line-through';
|
|
97
|
+
/** Optional semantic opacity treatment. */
|
|
98
|
+
opacity?: 'normal' | 'muted';
|
|
99
|
+
}
|
|
100
|
+
/** Assigns a class when a Host-extracted fact is new within a partition. */
|
|
101
|
+
export interface StrategyMessagePresentationNoveltyRule {
|
|
102
|
+
/** Canonical message fact extracted by Host before comparing plugin-owned known values. */
|
|
103
|
+
fact: 'grid-field-2';
|
|
104
|
+
/** Plugin-owned known values keyed by the configured partition. */
|
|
105
|
+
knownValuesByPartition: Record<string, string[]>;
|
|
106
|
+
/** Presentation class used when the extracted fact is not known. */
|
|
107
|
+
classId: string;
|
|
108
|
+
}
|
|
109
|
+
/** Adds a badge when a bounded token matcher accepts the decoded message. */
|
|
110
|
+
export interface StrategyMessagePresentationTagRule {
|
|
111
|
+
/** Stable rule identity for diagnostics and replacement. */
|
|
112
|
+
id: string;
|
|
113
|
+
/** Host-evaluated token matcher. */
|
|
114
|
+
match: StrategyMessagePresentationTokenMatch;
|
|
115
|
+
/** Badge rendered when the matcher succeeds. */
|
|
116
|
+
badge: StrategyMessagePresentationBadge;
|
|
117
|
+
}
|
|
118
|
+
/** Complete strategy-owned, data-only presentation projection for decoded messages. */
|
|
119
|
+
export interface StrategyMessagePresentationProjection {
|
|
120
|
+
/** Monotonic plugin revision used to replace stale projections. */
|
|
121
|
+
revision: number;
|
|
122
|
+
/** Whether the projection replaces logbook presentation or augments it. */
|
|
123
|
+
mode: 'replace-logbook' | 'augment';
|
|
124
|
+
/** Canonical message subject classified by the projection. */
|
|
125
|
+
subject: 'sender-callsign';
|
|
126
|
+
/** Partition used for assignments and novelty checks. */
|
|
127
|
+
partitionBy: 'band' | 'mode' | 'none';
|
|
128
|
+
/** Optional partition allowlist. */
|
|
129
|
+
eligiblePartitions?: string[];
|
|
130
|
+
/** Class applied when no assignment or rule selects another class. */
|
|
131
|
+
defaultClass?: string;
|
|
132
|
+
/** Strategy-defined presentation classes keyed by stable ID. */
|
|
133
|
+
classes: Record<string, StrategyMessagePresentationClass>;
|
|
134
|
+
/** Explicit subject-to-class assignments. */
|
|
135
|
+
assignments: Array<{
|
|
136
|
+
subject: string;
|
|
137
|
+
partition?: string;
|
|
138
|
+
classId: string;
|
|
139
|
+
}>;
|
|
140
|
+
/** Optional Host-evaluated novelty rules. */
|
|
141
|
+
noveltyRules?: StrategyMessagePresentationNoveltyRule[];
|
|
142
|
+
/** Optional Host-evaluated tag rules. */
|
|
143
|
+
tagRules?: StrategyMessagePresentationTagRule[];
|
|
144
|
+
}
|
|
145
|
+
/** Strategy-owned reason that prevents an operator from starting transmission. */
|
|
146
|
+
export interface StrategyTransmitGate {
|
|
147
|
+
/** Always false while the gate is present. */
|
|
148
|
+
allowed: false;
|
|
149
|
+
/** Literal message or plugin locale key shown to the operator. */
|
|
150
|
+
reason: string;
|
|
151
|
+
/** Optional strategy action that can resolve the gate. */
|
|
152
|
+
actionId?: string;
|
|
153
|
+
}
|
|
154
|
+
/** Semantic tone used for strategy-owned operator actions. */
|
|
155
|
+
export type StrategyActionTone = 'default' | 'primary' | 'success' | 'warning' | 'danger';
|
|
156
|
+
/** Host layout requested for a strategy-owned action. */
|
|
157
|
+
export type StrategyActionPresentation = 'primary' | 'secondary' | 'menu' | 'segmented';
|
|
158
|
+
/** Optional value editor attached to a strategy-owned action. */
|
|
159
|
+
export type StrategyActionInput = {
|
|
160
|
+
kind: 'text';
|
|
161
|
+
label?: string;
|
|
162
|
+
value?: string;
|
|
163
|
+
placeholder?: string;
|
|
164
|
+
maxLength?: number;
|
|
165
|
+
} | {
|
|
166
|
+
kind: 'number' | 'audio-frequency';
|
|
167
|
+
label?: string;
|
|
168
|
+
value?: number;
|
|
169
|
+
min?: number;
|
|
170
|
+
max?: number;
|
|
171
|
+
step?: number;
|
|
172
|
+
unit?: string;
|
|
173
|
+
spectrumPick?: boolean;
|
|
174
|
+
};
|
|
175
|
+
/** One context-sensitive command wholly owned by a strategy plugin. */
|
|
176
|
+
export interface StrategyActionDescriptor {
|
|
177
|
+
/** Stable action identifier passed back to the owning runtime. */
|
|
178
|
+
id: string;
|
|
179
|
+
/** Literal label or plugin locale key. */
|
|
180
|
+
label: string;
|
|
181
|
+
/** Optional literal description or plugin locale key. */
|
|
182
|
+
description?: string;
|
|
183
|
+
/** Host icon identifier. */
|
|
184
|
+
icon?: string;
|
|
185
|
+
/** Semantic action tone. */
|
|
186
|
+
tone?: StrategyActionTone;
|
|
187
|
+
/** Preferred Host layout for this command. */
|
|
188
|
+
presentation?: StrategyActionPresentation;
|
|
189
|
+
/** Optional group identity used by menus and segmented controls. */
|
|
190
|
+
groupId?: string;
|
|
191
|
+
/** Whether a toggle-like action is currently selected. */
|
|
192
|
+
selected?: boolean;
|
|
193
|
+
/** Explanation shown while the action is disabled. */
|
|
194
|
+
disabledReason?: string;
|
|
195
|
+
/** Optional exact transmission preview. */
|
|
196
|
+
previewText?: string;
|
|
197
|
+
/** Confirmation dialog requested before invocation. */
|
|
198
|
+
confirmation?: {
|
|
199
|
+
title: string;
|
|
200
|
+
description?: string;
|
|
201
|
+
confirmLabel?: string;
|
|
202
|
+
cancelLabel?: string;
|
|
203
|
+
};
|
|
204
|
+
/** Optional text, number, or audio-frequency editor. */
|
|
205
|
+
input?: StrategyActionInput;
|
|
206
|
+
/** Host-validated navigation to a page declared by the owning plugin. */
|
|
207
|
+
navigation?: {
|
|
208
|
+
kind: 'plugin-page';
|
|
209
|
+
pageId: string;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/** Strategy-owned operator attention item with optional actions and notification. */
|
|
213
|
+
export interface StrategyAttention {
|
|
214
|
+
/** Stable identity used to replace or dismiss the item. */
|
|
215
|
+
id: string;
|
|
216
|
+
/** Semantic severity rendered by the Host. */
|
|
217
|
+
tone: 'info' | 'warning' | 'danger' | 'success';
|
|
218
|
+
/** Literal title or plugin locale key. */
|
|
219
|
+
title: string;
|
|
220
|
+
/** Optional literal description or plugin locale key. */
|
|
221
|
+
description?: string;
|
|
222
|
+
/** Locale interpolation parameters. */
|
|
223
|
+
params?: Record<string, string | number>;
|
|
224
|
+
/** Whether the Host may surface an out-of-page notification. */
|
|
225
|
+
notify?: boolean;
|
|
226
|
+
/** Epoch milliseconds after which the Host may discard the item. */
|
|
227
|
+
expiresAt?: number;
|
|
228
|
+
/** Strategy action IDs offered with the item. */
|
|
229
|
+
actionIds?: string[];
|
|
230
|
+
}
|
|
231
|
+
/** Durable QSO completion state projected by one strategy stream. */
|
|
232
|
+
export interface StrategyCompletionProjection {
|
|
233
|
+
/** Current preparation or commit phase. */
|
|
234
|
+
state: 'not-ready' | 'ready' | 'committing' | 'committed' | 'failed';
|
|
235
|
+
/** Optional literal label or plugin locale key. */
|
|
236
|
+
label?: string;
|
|
237
|
+
/** Durable record ID once the Host commits the QSO. */
|
|
238
|
+
recordId?: string;
|
|
239
|
+
}
|
|
240
|
+
/** One user-selectable state exposed by a strategy-owned state machine. */
|
|
241
|
+
export interface StrategyStateOption {
|
|
242
|
+
/** Stable state identifier understood only by the owning strategy. */
|
|
243
|
+
id: string;
|
|
244
|
+
/** Literal label or plugin locale key shown by the Host UI. */
|
|
245
|
+
label?: string;
|
|
246
|
+
/** Exact transmission produced when this state is selected, when applicable. */
|
|
247
|
+
transmitText?: string;
|
|
248
|
+
}
|
|
249
|
+
/** One independently progressing parallel QSO inside an operator strategy. */
|
|
250
|
+
export interface StrategyStreamSnapshot {
|
|
251
|
+
/** Stable identity within the owning strategy runtime. */
|
|
252
|
+
streamId: string;
|
|
253
|
+
/** Current lane state selected by the protocol implementation. */
|
|
254
|
+
currentState: string;
|
|
255
|
+
/** Target station currently owned by this lane. */
|
|
256
|
+
targetCallsign?: string;
|
|
257
|
+
/** Last accepted target grid, when known. */
|
|
258
|
+
targetGrid?: string;
|
|
259
|
+
/** Audio carrier used by this lane in hertz. */
|
|
260
|
+
audioFrequencyHz: number;
|
|
261
|
+
/** Lane-local lifecycle epoch used to correlate durable QSO effects. */
|
|
262
|
+
qsoLifecycleEpoch: number;
|
|
263
|
+
/** Protocol-approved states that the operator may select for this lane. */
|
|
264
|
+
stateOptions?: StrategyStateOption[];
|
|
265
|
+
/** Context-sensitive actions owned by this lane. */
|
|
266
|
+
actions?: StrategyActionDescriptor[];
|
|
267
|
+
/** Operator attention items owned by this lane. */
|
|
268
|
+
attentions?: StrategyAttention[];
|
|
269
|
+
/** Durable QSO completion projection for this lane. */
|
|
270
|
+
completion?: StrategyCompletionProjection;
|
|
271
|
+
/** Most recent accepted inbound protocol text. */
|
|
272
|
+
lastReceivedText?: string;
|
|
273
|
+
/** Exact text this lane plans to transmit next. */
|
|
274
|
+
nextTransmitText?: string;
|
|
275
|
+
}
|
|
276
|
+
/** Optimistic target for a strategy action invocation. */
|
|
277
|
+
export type StrategyActionTarget = {
|
|
278
|
+
kind: 'runtime';
|
|
279
|
+
} | {
|
|
280
|
+
kind: 'stream';
|
|
281
|
+
streamId: string;
|
|
282
|
+
lifecycleEpoch: number;
|
|
283
|
+
} | {
|
|
284
|
+
kind: 'queue-entry';
|
|
285
|
+
entryId: string;
|
|
286
|
+
queueVersion: number;
|
|
287
|
+
};
|
|
288
|
+
/** Host-validated invocation of one strategy-owned action. */
|
|
289
|
+
export interface StrategyActionInvocation {
|
|
290
|
+
/** Runtime, stream, or queue entry that owns the action. */
|
|
291
|
+
target: StrategyActionTarget;
|
|
292
|
+
/** Action identifier from the current strategy projection. */
|
|
293
|
+
actionId: string;
|
|
294
|
+
/** Untrusted action input that the strategy must validate. */
|
|
295
|
+
payload?: unknown;
|
|
296
|
+
}
|
|
297
|
+
/** Host-managed plugin logbook session effect returned by an accepted action or decision. */
|
|
298
|
+
export type StrategyLogbookSessionEffect = {
|
|
299
|
+
operation: 'open';
|
|
300
|
+
sessionKey: string;
|
|
301
|
+
title: string;
|
|
302
|
+
retention?: 'durable' | 'runtime';
|
|
303
|
+
} | {
|
|
304
|
+
operation: 'destroy';
|
|
305
|
+
sessionKey: string;
|
|
306
|
+
};
|
|
307
|
+
/** Declarative effects returned after invoking a strategy-owned action. */
|
|
308
|
+
export interface StrategyActionResult {
|
|
309
|
+
/** Requests a fresh speculative decision after the action commits. */
|
|
310
|
+
requestDecision?: boolean;
|
|
311
|
+
/** Start this operator through the Host's normal automation path after a direct user action. */
|
|
312
|
+
requestOperatorStart?: boolean;
|
|
313
|
+
/** QSO effects prepared and committed by the Host. */
|
|
314
|
+
qsoCompletions?: StrategyQSOCompletionEffect[];
|
|
315
|
+
/** Host-managed plugin logbook session operations caused by this explicit action. */
|
|
316
|
+
logbookSessionEffects?: StrategyLogbookSessionEffect[];
|
|
317
|
+
/** Stable action outcome for UI feedback and diagnostics. */
|
|
318
|
+
outcome?: {
|
|
319
|
+
code: string;
|
|
320
|
+
message?: string;
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/** Optimistic request to move one strategy-owned lane to a user-selectable state. */
|
|
324
|
+
export interface StrategyStreamStateUpdate {
|
|
325
|
+
/** Lane to update. */
|
|
326
|
+
streamId: string;
|
|
327
|
+
/** Strategy-approved target state. */
|
|
328
|
+
stateId: string;
|
|
329
|
+
/** Optimistic lane lifecycle epoch from the current projection. */
|
|
330
|
+
expectedLifecycleEpoch: number;
|
|
331
|
+
}
|
|
332
|
+
/** One independently encoded transmission contributed by a strategy. */
|
|
333
|
+
export interface StrategyTransmission {
|
|
334
|
+
/** Stable lane identity within one operator. */
|
|
335
|
+
streamId: string;
|
|
336
|
+
/** Exact FT8/FT4 text to encode. */
|
|
337
|
+
text: string;
|
|
338
|
+
/** Audio carrier frequency in hertz. */
|
|
339
|
+
audioFrequencyHz: number;
|
|
340
|
+
}
|
|
341
|
+
/** Physical confirmation for one transmitted lane in an atomic frame. */
|
|
342
|
+
export interface StreamPhysicalReceipt extends StrategyTransmission {
|
|
343
|
+
/** Host physical-frame identity. */
|
|
344
|
+
frameId: string;
|
|
345
|
+
/** Monotonic physical-frame revision. */
|
|
346
|
+
revision: number;
|
|
347
|
+
/** Literal proof that this lane reached physical transmission. */
|
|
348
|
+
physicalConfirmed: true;
|
|
349
|
+
}
|
|
350
|
+
/** User-facing phase shown for one row in a queue-capable strategy. */
|
|
351
|
+
export type AssistedQueueDisplayState = 'TX1' | 'TX2' | 'TX3' | 'TX4' | 'TX5' | 'engaged' | 'closing' | 'paused' | 'no-response' | 'later' | 'review' | 'candidate' | 'authorized' | 'dupe';
|
|
352
|
+
/** Why a queued target is temporarily paused instead of being selected. */
|
|
353
|
+
export type AssistedQueuePauseReason = 'target-busy' | 'stale';
|
|
354
|
+
/** Semantic color treatment requested for an assisted queue row. */
|
|
355
|
+
export type AssistedQueueTone = 'neutral' | 'active' | 'success' | 'warning' | 'danger';
|
|
356
|
+
/** Host icon identifier requested for an assisted queue row. */
|
|
357
|
+
export type AssistedQueueIcon = 'circle' | 'radio' | 'check-circle' | 'loader-circle' | 'clock' | 'pause' | 'triangle-alert';
|
|
358
|
+
/** Stable, serializable UI projection of one queued target. */
|
|
359
|
+
export interface AssistedQueueRow {
|
|
360
|
+
/** Queue-entry identity used by reorder/remove/retry commands. */
|
|
361
|
+
entryId: string;
|
|
362
|
+
/** Target station callsign. */
|
|
363
|
+
callsign: string;
|
|
364
|
+
/** Zero-based display order in the current snapshot. */
|
|
365
|
+
order: number;
|
|
366
|
+
/** Whether the UI may offer drag-to-reorder for this row. */
|
|
367
|
+
draggable: boolean;
|
|
368
|
+
/** Current protocol or queue phase shown to the operator. */
|
|
369
|
+
displayState: AssistedQueueDisplayState;
|
|
370
|
+
/** Semantic visual treatment for the row. */
|
|
371
|
+
tone: AssistedQueueTone;
|
|
372
|
+
/** Icon chosen by the strategy for the current state. */
|
|
373
|
+
icon: AssistedQueueIcon;
|
|
374
|
+
/** Why this row is paused, when `displayState` is `paused`. */
|
|
375
|
+
pauseReason?: AssistedQueuePauseReason;
|
|
376
|
+
/** Consecutive no-response cycles observed for this target. */
|
|
377
|
+
noResponseCycles?: number;
|
|
378
|
+
/** Last known Maidenhead grid locator for the target. */
|
|
379
|
+
targetGrid?: string;
|
|
380
|
+
/** Most recently decoded signal report in dB. */
|
|
381
|
+
lastSnr?: number;
|
|
382
|
+
/** Receive cycles elapsed since this target was last decoded. */
|
|
383
|
+
lastHeardCyclesAgo?: number;
|
|
384
|
+
/** Cycle in which the target was most recently decoded transmitting. */
|
|
385
|
+
lastHeardCycle?: 0 | 1;
|
|
386
|
+
/** Active strategy stream currently processing this entry. */
|
|
387
|
+
streamId?: string;
|
|
388
|
+
/** Reserved audio carrier when the entry owns a stream. */
|
|
389
|
+
audioFrequencyHz?: number;
|
|
390
|
+
/** Audited operator authorization associated with this entry. */
|
|
391
|
+
authorizationId?: string;
|
|
392
|
+
/** Plugin-declared row actions. Omission preserves legacy queue controls. */
|
|
393
|
+
actions?: StrategyActionDescriptor[];
|
|
394
|
+
}
|
|
395
|
+
/** Versioned queue projection embedded in `StrategyRuntimeSnapshot.queue`. */
|
|
396
|
+
export interface AssistedQueueSnapshot {
|
|
397
|
+
/** Monotonically increasing revision used for optimistic mutations. */
|
|
398
|
+
version: number;
|
|
399
|
+
/** Entry currently owned by the active QSO lifecycle, when any. */
|
|
400
|
+
activeEntryId?: string;
|
|
401
|
+
/** Entries currently owned by parallel QSO lifecycles. */
|
|
402
|
+
activeEntryIds?: string[];
|
|
403
|
+
/** Maximum number of entries that may be active at once. */
|
|
404
|
+
maxActiveStreams?: number;
|
|
405
|
+
/** User-requested stream count before Host radio-frequency policy is applied. */
|
|
406
|
+
requestedMaxActiveStreams?: number;
|
|
407
|
+
/** Queue rows in display order. */
|
|
408
|
+
rows: AssistedQueueRow[];
|
|
409
|
+
}
|
|
410
|
+
/** Metadata supplied when a queue-capable strategy observes decoded messages. */
|
|
411
|
+
export interface QueuedStrategyObservationMeta {
|
|
412
|
+
/** Slot that produced the decoded messages. */
|
|
413
|
+
slotInfo: SlotInfo;
|
|
414
|
+
/** Why the Host is asking the strategy to observe this batch. */
|
|
415
|
+
source: StrategyDecisionSource;
|
|
416
|
+
/** Aborts when this observation is superseded or the instance stops. */
|
|
417
|
+
signal: AbortSignal;
|
|
418
|
+
}
|
|
419
|
+
/** Target and optional triggering frame submitted to an assisted queue. */
|
|
420
|
+
export interface QueuedStrategyTargetRequest {
|
|
421
|
+
/** Callsign to normalize and enqueue. */
|
|
422
|
+
callsign: string;
|
|
423
|
+
/** Authentic decoder frame/slot pair that triggered the request, when known. */
|
|
424
|
+
lastMessage?: {
|
|
425
|
+
message: FrameMessage;
|
|
426
|
+
slotInfo: SlotInfo;
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/** Result of an assisted queue mutation, including the authoritative snapshot. */
|
|
430
|
+
export interface QueuedStrategyMutationResult {
|
|
431
|
+
/** Whether the mutation changed the queue, was already satisfied, or was rejected. */
|
|
432
|
+
outcome: 'accepted' | 'duplicate' | 'rejected';
|
|
433
|
+
/** Machine-readable rejection reason. */
|
|
434
|
+
reason?: 'queue_full' | 'invalid_target' | 'entry_not_found' | 'entry_not_retryable' | 'active_entry' | 'version_conflict';
|
|
435
|
+
/** Authoritative queue state after the attempted mutation. */
|
|
436
|
+
snapshot: AssistedQueueSnapshot;
|
|
437
|
+
/** Requests a normal operator start after this explicit manual queue mutation. */
|
|
438
|
+
requestOperatorStart?: boolean;
|
|
439
|
+
}
|
|
440
|
+
/** Optional capability implemented by strategies that own a target queue. */
|
|
441
|
+
export interface QueuedStrategyRuntime extends StrategyRuntime {
|
|
442
|
+
/** Incorporates a decoded batch and returns whether the queue projection changed. */
|
|
443
|
+
observeDecodedMessages(messages: ParsedFT8Message[], meta: QueuedStrategyObservationMeta): boolean;
|
|
444
|
+
/** Adds a target unless it is invalid, duplicated or the queue is full. */
|
|
445
|
+
enqueueTarget(request: QueuedStrategyTargetRequest): QueuedStrategyMutationResult;
|
|
446
|
+
/** Moves an entry before another entry, or to the end when `beforeEntryId` is null. */
|
|
447
|
+
reorderTarget(entryId: string, beforeEntryId: string | null, expectedVersion: number): QueuedStrategyMutationResult;
|
|
448
|
+
/** Removes a non-active entry using optimistic version validation. */
|
|
449
|
+
removeTarget(entryId: string, expectedVersion: number): QueuedStrategyMutationResult;
|
|
450
|
+
/** Makes a retryable failed/no-response entry eligible again. */
|
|
451
|
+
retryTarget?(entryId: string, expectedVersion: number): QueuedStrategyMutationResult;
|
|
452
|
+
/** Removes every non-active entry using optimistic version validation. */
|
|
453
|
+
clearTargets?(expectedVersion: number): QueuedStrategyMutationResult;
|
|
454
|
+
/** Returns the current detached queue snapshot. */
|
|
455
|
+
getQueueSnapshot(): AssistedQueueSnapshot;
|
|
456
|
+
}
|
|
457
|
+
/** Runtime type guard for the optional assisted-target queue capability. */
|
|
458
|
+
export declare function isQueuedStrategyRuntime(runtime: StrategyRuntime): runtime is QueuedStrategyRuntime;
|
|
45
459
|
/**
|
|
46
460
|
* Describes a slot text mutation emitted by the strategy runtime.
|
|
47
461
|
*/
|
|
@@ -51,6 +465,88 @@ export interface StrategyRuntimeSlotContentUpdate {
|
|
|
51
465
|
/** Human-readable content for the slot, usually an FT8 message template. */
|
|
52
466
|
content: string;
|
|
53
467
|
}
|
|
468
|
+
/** Trigger that caused the Host to request a strategy decision. */
|
|
469
|
+
export type StrategyDecisionSource = 'slot-auto' | 'late-decode';
|
|
470
|
+
/** Invocation metadata for a speculative API v2 strategy decision. */
|
|
471
|
+
export interface StrategyDecisionMetaV2 {
|
|
472
|
+
/** Monotonic Host decision epoch; newer epochs supersede older decisions. */
|
|
473
|
+
epoch: number;
|
|
474
|
+
/** Slot progression or late-decode event that triggered the decision. */
|
|
475
|
+
source: StrategyDecisionSource;
|
|
476
|
+
/** `true` when new information caused the current slot to be evaluated again. */
|
|
477
|
+
isReDecision: boolean;
|
|
478
|
+
/** Aborts when this decision is superseded, times out or the instance stops. */
|
|
479
|
+
signal: AbortSignal;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Strategy-owned state captured before a speculative decision.
|
|
483
|
+
*
|
|
484
|
+
* The value must be structured-clone compatible and must not contain Host
|
|
485
|
+
* capabilities, functions, promises or external resource handles.
|
|
486
|
+
*/
|
|
487
|
+
export type StrategyRuntimeCheckpoint = unknown;
|
|
488
|
+
/** Operator transmit-cycle selection observed by an active strategy runtime. */
|
|
489
|
+
export interface StrategyOperatorTransmitCyclesChanged {
|
|
490
|
+
/** Previous Host-selected transmit cycles. */
|
|
491
|
+
previousTransmitCycles: number[];
|
|
492
|
+
/** Current Host-selected transmit cycles. */
|
|
493
|
+
transmitCycles: number[];
|
|
494
|
+
/** Source of the accepted cycle change. */
|
|
495
|
+
source?: 'manual' | 'plugin' | 'late-decode' | 'slot-auto';
|
|
496
|
+
}
|
|
497
|
+
/** Declarative request for the Host to durably commit one completed QSO. */
|
|
498
|
+
export interface StrategyQSOCompletionEffect {
|
|
499
|
+
/** Complete QSO record to validate and persist. */
|
|
500
|
+
record: QSORecord;
|
|
501
|
+
/** Stable within one strategy runtime generation; distinct from RF decision epochs. */
|
|
502
|
+
lifecycleEpoch: number;
|
|
503
|
+
/** Lane that produced the completion; omitted by legacy single-lane strategies. */
|
|
504
|
+
streamId?: string;
|
|
505
|
+
/** Host persistence behavior requested by the strategy. */
|
|
506
|
+
persistencePolicy?: 'merge-nearby' | 'preserve-distinct';
|
|
507
|
+
/** Optional Host-issued destination. Omitted effects use the operator's primary logbook. */
|
|
508
|
+
destination?: {
|
|
509
|
+
kind: 'plugin-session';
|
|
510
|
+
sessionId: string;
|
|
511
|
+
} | {
|
|
512
|
+
kind: 'plugin-session-key';
|
|
513
|
+
sessionKey: string;
|
|
514
|
+
};
|
|
515
|
+
/** Structured-cloneable source metadata returned with post-commit delivery. */
|
|
516
|
+
metadata?: Record<string, unknown>;
|
|
517
|
+
}
|
|
518
|
+
/** Host acknowledgement for a previously returned QSO completion effect. */
|
|
519
|
+
export interface StrategyQSOCompletionSettlement {
|
|
520
|
+
/** Lifecycle epoch copied from the effect being settled. */
|
|
521
|
+
lifecycleEpoch: number;
|
|
522
|
+
/** Record ID from the accepted completion effect, used for correlation. */
|
|
523
|
+
recordId: string;
|
|
524
|
+
/** Final durable record ID; differs when the Host merged into an existing QSO. */
|
|
525
|
+
persistedRecordId?: string;
|
|
526
|
+
/** Whether the Host committed the record or the durable operation failed. */
|
|
527
|
+
status: 'committed' | 'failed';
|
|
528
|
+
/** Lane copied from the accepted completion effect. */
|
|
529
|
+
streamId?: string;
|
|
530
|
+
/** Detached source metadata copied from the accepted completion effect. */
|
|
531
|
+
metadata?: Record<string, unknown>;
|
|
532
|
+
}
|
|
533
|
+
/** Complete output of one speculative strategy decision. */
|
|
534
|
+
export interface StrategyDecisionResult extends StrategyDecision {
|
|
535
|
+
/** Exact text to queue next, or `null` when this decision should not transmit. */
|
|
536
|
+
transmission: string | null;
|
|
537
|
+
/** Parallel transmissions. New strategies use this instead of `transmission`. */
|
|
538
|
+
transmissions?: StrategyTransmission[];
|
|
539
|
+
/** UI/diagnostic snapshot produced from the same post-decision state. */
|
|
540
|
+
snapshot: StrategyRuntimeSnapshot;
|
|
541
|
+
/** Optional QSO persistence effect executed by the Host after acceptance. */
|
|
542
|
+
qsoCompletion?: StrategyQSOCompletionEffect;
|
|
543
|
+
/** Parallel QSO effects committed in the same accepted decision. */
|
|
544
|
+
qsoCompletions?: StrategyQSOCompletionEffect[];
|
|
545
|
+
/** Host-managed plugin logbook lifecycle effects accepted with this decision. */
|
|
546
|
+
logbookSessionEffects?: StrategyLogbookSessionEffect[];
|
|
547
|
+
/** Optional cycle selected from the triggering RX frame; applied by the host after target reservation. */
|
|
548
|
+
requestedTransmitCycle?: number;
|
|
549
|
+
}
|
|
54
550
|
/**
|
|
55
551
|
* Active controller for a `strategy` plugin.
|
|
56
552
|
*
|
|
@@ -59,31 +555,55 @@ export interface StrategyRuntimeSlotContentUpdate {
|
|
|
59
555
|
* respect to the incoming slot/decode stream.
|
|
60
556
|
*/
|
|
61
557
|
export interface StrategyRuntime {
|
|
558
|
+
/** Captures all mutable state needed to roll back the next decision. */
|
|
559
|
+
checkpoint(): StrategyRuntimeCheckpoint;
|
|
560
|
+
/** Restores a previously captured checkpoint after a decision is discarded. */
|
|
561
|
+
restore(checkpoint: StrategyRuntimeCheckpoint): void;
|
|
562
|
+
/**
|
|
563
|
+
* Observes an already-applied Host transmit-cycle selection. Returning true
|
|
564
|
+
* asks the Host to publish the resulting runtime projection.
|
|
565
|
+
*/
|
|
566
|
+
onOperatorTransmitCyclesChanged?(change: StrategyOperatorTransmitCyclesChanged): boolean;
|
|
567
|
+
/**
|
|
568
|
+
* Optional acknowledgement for a declarative QSO effect. Implementations may
|
|
569
|
+
* use it to prevent a completed contact from leaking into the next lifecycle.
|
|
570
|
+
* The Host invokes it only for an accepted effect from the same runtime
|
|
571
|
+
* generation and reports whether durable persistence committed or failed.
|
|
572
|
+
*/
|
|
573
|
+
settleQSOCompletion?(settlement: StrategyQSOCompletionSettlement): void;
|
|
62
574
|
/**
|
|
63
575
|
* Re-evaluates the current automation state using the latest decoded messages.
|
|
64
576
|
*
|
|
65
|
-
* Return `{ stop: true }` to
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
577
|
+
* Return `{ stop: true }` to stop this operator's automation and prevent new
|
|
578
|
+
* frames. It never grants an RF interrupt: an already committed/on-air frame
|
|
579
|
+
* is allowed to finish. Explicit operator contribution removal is available
|
|
580
|
+
* only through the invocation-guarded `operator:transmit-control` command
|
|
581
|
+
* port outside speculative strategy execution.
|
|
70
582
|
*/
|
|
71
|
-
decide(messages: ParsedFT8Message[], meta
|
|
583
|
+
decide(messages: ParsedFT8Message[], meta: StrategyDecisionMetaV2): Promise<StrategyDecisionResult> | StrategyDecisionResult;
|
|
72
584
|
/**
|
|
73
585
|
* Returns the exact text that should be transmitted next, or `null` when no
|
|
74
586
|
* transmission should be queued.
|
|
75
587
|
*/
|
|
76
588
|
getTransmitText(): string | null;
|
|
589
|
+
/**
|
|
590
|
+
* Returns every lane that should contribute to the next physical frame.
|
|
591
|
+
* Legacy runtimes may omit this method; the Host then maps getTransmitText()
|
|
592
|
+
* to the `default` stream at the operator's configured audio frequency.
|
|
593
|
+
*/
|
|
594
|
+
getTransmissions?(): StrategyTransmission[];
|
|
77
595
|
/**
|
|
78
596
|
* Requests that the runtime initiate or resume a call to a target station.
|
|
79
597
|
*
|
|
80
598
|
* The optional `lastMessage` provides the frame that triggered the call, which
|
|
81
599
|
* is useful when reacting to a specific CQ or completion signal.
|
|
600
|
+
* Return exactly `false` to reject the target; `true` or `void` means the
|
|
601
|
+
* runtime accepted it and the Host may start the operator.
|
|
82
602
|
*/
|
|
83
603
|
requestCall(callsign: string, lastMessage?: {
|
|
84
604
|
message: FrameMessage;
|
|
85
605
|
slotInfo: SlotInfo;
|
|
86
|
-
}): void;
|
|
606
|
+
}): boolean | void;
|
|
87
607
|
/**
|
|
88
608
|
* Produces a serializable runtime snapshot for diagnostics and UI.
|
|
89
609
|
*/
|
|
@@ -96,6 +616,10 @@ export interface StrategyRuntime {
|
|
|
96
616
|
* Switches the runtime to a specific logical transmit slot/state.
|
|
97
617
|
*/
|
|
98
618
|
setState(state: StrategyRuntimeSlot): void;
|
|
619
|
+
/** Switches one independently progressing lane to a strategy-approved state. */
|
|
620
|
+
setStreamState?(update: StrategyStreamStateUpdate): void;
|
|
621
|
+
/** Executes one plugin-declared runtime, stream or queue-entry action. */
|
|
622
|
+
invokeAction?(invocation: StrategyActionInvocation): StrategyActionResult | void | Promise<StrategyActionResult | void>;
|
|
99
623
|
/**
|
|
100
624
|
* Updates the human-readable content associated with a logical slot.
|
|
101
625
|
*/
|
|
@@ -112,5 +636,7 @@ export interface StrategyRuntime {
|
|
|
112
636
|
* Use this to mirror queued text into internal state when needed.
|
|
113
637
|
*/
|
|
114
638
|
onTransmissionQueued?(transmission: string): void;
|
|
639
|
+
/** Physical success notification for a complete parallel frame. */
|
|
640
|
+
onTransmissionsCompleted?(receipts: StreamPhysicalReceipt[]): void;
|
|
115
641
|
}
|
|
116
642
|
//# sourceMappingURL=runtime.d.ts.map
|