@tx5dr/plugin-api 1.0.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/__tests__/ft8-message-type.test.d.ts +2 -0
- package/dist/__tests__/ft8-message-type.test.d.ts.map +1 -0
- package/dist/__tests__/ft8-message-type.test.js +9 -0
- package/dist/__tests__/ft8-message-type.test.js.map +1 -0
- package/dist/__tests__/testing-utils.test.d.ts +2 -0
- package/dist/__tests__/testing-utils.test.d.ts.map +1 -0
- package/dist/__tests__/testing-utils.test.js +151 -0
- package/dist/__tests__/testing-utils.test.js.map +1 -0
- package/dist/context.d.ts +82 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/definition.d.ts +181 -0
- package/dist/definition.d.ts.map +1 -0
- package/dist/definition.js +2 -0
- package/dist/definition.js.map +1 -0
- package/dist/ft8-message-type.d.ts +21 -0
- package/dist/ft8-message-type.d.ts.map +1 -0
- package/dist/ft8-message-type.js +21 -0
- package/dist/ft8-message-type.js.map +1 -0
- package/dist/helpers.d.ts +223 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +2 -0
- package/dist/helpers.js.map +1 -0
- package/dist/hooks.d.ts +204 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.d.ts +116 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2 -0
- package/dist/runtime.js.map +1 -0
- package/dist/testing/index.d.ts +83 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +190 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import type { ParsedFT8Message, SlotInfo, SlotPack, QSORecord, FrameMessage, OperatorSlots, ModeDescriptor } from '@tx5dr/contracts';
|
|
2
|
+
import type { StrategyRuntimeSnapshot } from './runtime.js';
|
|
3
|
+
/**
|
|
4
|
+
* Simple persistent key-value store exposed to plugins.
|
|
5
|
+
*
|
|
6
|
+
* Values are serialized by the host. Keep payloads reasonably small and prefer
|
|
7
|
+
* plain JSON-compatible data for maximum portability.
|
|
8
|
+
*/
|
|
9
|
+
export interface KVStore {
|
|
10
|
+
/**
|
|
11
|
+
* Reads a stored value.
|
|
12
|
+
*
|
|
13
|
+
* When the key is missing, the provided `defaultValue` is returned instead.
|
|
14
|
+
*/
|
|
15
|
+
get<T = unknown>(key: string, defaultValue?: T): T;
|
|
16
|
+
/**
|
|
17
|
+
* Persists a value under the given key.
|
|
18
|
+
*/
|
|
19
|
+
set(key: string, value: unknown): void;
|
|
20
|
+
/**
|
|
21
|
+
* Removes a stored key and its value.
|
|
22
|
+
*/
|
|
23
|
+
delete(key: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Returns a shallow snapshot of all stored entries in this scope.
|
|
26
|
+
*/
|
|
27
|
+
getAll(): Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Structured logger dedicated to a plugin instance.
|
|
31
|
+
*
|
|
32
|
+
* Messages should be concise and machine-friendly because they may appear in
|
|
33
|
+
* both backend logs and operator-facing diagnostics.
|
|
34
|
+
*/
|
|
35
|
+
export interface PluginLogger {
|
|
36
|
+
/** Writes a verbose diagnostic message. */
|
|
37
|
+
debug(message: string, data?: Record<string, unknown>): void;
|
|
38
|
+
/** Writes a lifecycle or informational message. */
|
|
39
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
40
|
+
/** Writes a warning that does not stop plugin execution. */
|
|
41
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
42
|
+
/** Writes an error with optional structured details or an exception object. */
|
|
43
|
+
error(message: string, error?: unknown): void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Host-managed named timers for plugin code.
|
|
47
|
+
*/
|
|
48
|
+
export interface PluginTimers {
|
|
49
|
+
/**
|
|
50
|
+
* Starts or replaces a named interval timer.
|
|
51
|
+
*
|
|
52
|
+
* When the timer fires, the host invokes {@link PluginHooks.onTimer} with the
|
|
53
|
+
* same id.
|
|
54
|
+
*/
|
|
55
|
+
set(id: string, intervalMs: number): void;
|
|
56
|
+
/** Clears a named timer if it exists. */
|
|
57
|
+
clear(id: string): void;
|
|
58
|
+
/** Clears all timers owned by the current plugin instance. */
|
|
59
|
+
clearAll(): void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Control surface for the active operator instance.
|
|
63
|
+
*
|
|
64
|
+
* This interface lets plugins inspect operator state and request host-managed
|
|
65
|
+
* actions such as starting automation, calling a target or notifying the UI.
|
|
66
|
+
*/
|
|
67
|
+
export interface OperatorControl {
|
|
68
|
+
/** Unique operator identifier used by the host. */
|
|
69
|
+
readonly id: string;
|
|
70
|
+
/** Whether this operator is currently transmitting or otherwise armed. */
|
|
71
|
+
readonly isTransmitting: boolean;
|
|
72
|
+
/** Configured callsign of the operator/station. */
|
|
73
|
+
readonly callsign: string;
|
|
74
|
+
/** Configured grid locator of the operator/station. */
|
|
75
|
+
readonly grid: string;
|
|
76
|
+
/** Current audio offset frequency in Hz within the passband. */
|
|
77
|
+
readonly frequency: number;
|
|
78
|
+
/** Active digital mode descriptor, for example FT8 or FT4. */
|
|
79
|
+
readonly mode: ModeDescriptor;
|
|
80
|
+
/** Current transmit cycle selection where `0` is even and `1` is odd. */
|
|
81
|
+
readonly transmitCycles: number[];
|
|
82
|
+
/** Current automation runtime snapshot visible to the operator UI. */
|
|
83
|
+
readonly automation: StrategyRuntimeSnapshot | null;
|
|
84
|
+
/** Enables transmission/automation for the current operator. */
|
|
85
|
+
startTransmitting(): void;
|
|
86
|
+
/** Disables transmission/automation for the current operator. */
|
|
87
|
+
stopTransmitting(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Requests that the operator call the specified target station.
|
|
90
|
+
*
|
|
91
|
+
* Passing `lastMessage` helps the host preserve the triggering context.
|
|
92
|
+
*/
|
|
93
|
+
call(callsign: string, lastMessage?: {
|
|
94
|
+
message: FrameMessage;
|
|
95
|
+
slotInfo: SlotInfo;
|
|
96
|
+
}): void;
|
|
97
|
+
/**
|
|
98
|
+
* Updates the operator's transmit cycle preference.
|
|
99
|
+
*
|
|
100
|
+
* Pass a single value or an array to support alternating or multi-cycle modes.
|
|
101
|
+
*/
|
|
102
|
+
setTransmitCycles(cycles: number | number[]): void;
|
|
103
|
+
/**
|
|
104
|
+
* Checks whether this operator has previously worked the given callsign.
|
|
105
|
+
*/
|
|
106
|
+
hasWorkedCallsign(callsign: string): Promise<boolean>;
|
|
107
|
+
/**
|
|
108
|
+
* Checks whether another operator with the same station identity is already
|
|
109
|
+
* working the target callsign.
|
|
110
|
+
*/
|
|
111
|
+
isTargetBeingWorkedByOthers(targetCallsign: string): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Records a completed QSO through the host logbook pipeline.
|
|
114
|
+
*/
|
|
115
|
+
recordQSO(record: QSORecord): void;
|
|
116
|
+
/**
|
|
117
|
+
* Pushes updated slot text content to the frontend operator view.
|
|
118
|
+
*/
|
|
119
|
+
notifySlotsUpdated(slots: OperatorSlots): void;
|
|
120
|
+
/**
|
|
121
|
+
* Pushes a strategy state change notification to the frontend operator view.
|
|
122
|
+
*/
|
|
123
|
+
notifyStateChanged(state: string): void;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Read/write access to radio state that is safe for plugins.
|
|
127
|
+
*/
|
|
128
|
+
export interface RadioControl {
|
|
129
|
+
/** Current tuned radio frequency in Hz. */
|
|
130
|
+
readonly frequency: number;
|
|
131
|
+
/** Human-readable current band label, for example `20m`. */
|
|
132
|
+
readonly band: string;
|
|
133
|
+
/** Whether the radio transport is currently connected. */
|
|
134
|
+
readonly isConnected: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Requests a frequency change.
|
|
137
|
+
*
|
|
138
|
+
* The host remains responsible for serializing hardware access and enforcing
|
|
139
|
+
* any safety or capability constraints.
|
|
140
|
+
*/
|
|
141
|
+
setFrequency(freq: number): Promise<void>;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Read-only helpers backed by the station logbook.
|
|
145
|
+
*/
|
|
146
|
+
export interface LogbookAccess {
|
|
147
|
+
/** Checks whether the callsign has already been worked. */
|
|
148
|
+
hasWorked(callsign: string): Promise<boolean>;
|
|
149
|
+
/** Checks whether the DXCC entity has already been worked. */
|
|
150
|
+
hasWorkedDXCC(dxccEntity: string): Promise<boolean>;
|
|
151
|
+
/** Checks whether the Maidenhead grid has already been worked. */
|
|
152
|
+
hasWorkedGrid(grid: string): Promise<boolean>;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Optional constraints used when asking the host for a quieter transmit offset.
|
|
156
|
+
*/
|
|
157
|
+
export interface IdleTransmitFrequencyOptions {
|
|
158
|
+
/** Slot identifier to analyze. Defaults to the latest available slot when omitted. */
|
|
159
|
+
slotId?: string;
|
|
160
|
+
/** Inclusive lower bound in Hz within the passband. */
|
|
161
|
+
minHz?: number;
|
|
162
|
+
/** Inclusive upper bound in Hz within the passband. */
|
|
163
|
+
maxHz?: number;
|
|
164
|
+
/** Guard bandwidth in Hz to keep around occupied frequencies. */
|
|
165
|
+
guardHz?: number;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Reason codes returned by the host when evaluating whether a decoded target
|
|
169
|
+
* should be eligible for automatic CQ-style replies.
|
|
170
|
+
*/
|
|
171
|
+
export type AutoTargetEligibilityReason = 'non_cq_message' | 'plain_cq' | 'missing_callsign_identity' | 'missing_target_identity' | 'unsupported_activity_token' | 'unsupported_callback_token' | 'continent_match' | 'continent_mismatch' | 'dx_match' | 'dx_same_continent' | 'entity_match' | 'entity_mismatch' | 'unknown_modifier';
|
|
172
|
+
/**
|
|
173
|
+
* Structured result returned by the host for automatic-target eligibility
|
|
174
|
+
* checks.
|
|
175
|
+
*/
|
|
176
|
+
export interface AutoTargetEligibilityDecision {
|
|
177
|
+
/** Whether the host would currently allow automation to react to the target. */
|
|
178
|
+
eligible: boolean;
|
|
179
|
+
/** Machine-friendly explanation of the decision. */
|
|
180
|
+
reason: AutoTargetEligibilityReason;
|
|
181
|
+
/** Directed CQ modifier/token extracted from the message, when present. */
|
|
182
|
+
modifier?: string;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Read-only access to the current decode environment.
|
|
186
|
+
*/
|
|
187
|
+
export interface BandAccess {
|
|
188
|
+
/**
|
|
189
|
+
* Returns the active CQ-like callers known in the current slot context.
|
|
190
|
+
*/
|
|
191
|
+
getActiveCallers(): ParsedFT8Message[];
|
|
192
|
+
/**
|
|
193
|
+
* Returns the latest slot pack snapshot, or `null` if no slot has been
|
|
194
|
+
* processed yet.
|
|
195
|
+
*/
|
|
196
|
+
getLatestSlotPack(): SlotPack | null;
|
|
197
|
+
/**
|
|
198
|
+
* Asks the host to recommend a quieter transmit audio offset for the current
|
|
199
|
+
* decode environment.
|
|
200
|
+
*
|
|
201
|
+
* Returns `null` when the host cannot evaluate the slot or when no suitable
|
|
202
|
+
* idle window is found.
|
|
203
|
+
*/
|
|
204
|
+
findIdleTransmitFrequency(options?: IdleTransmitFrequencyOptions): number | null;
|
|
205
|
+
/**
|
|
206
|
+
* Evaluates whether the given decoded message is eligible for automatic
|
|
207
|
+
* target selection under the host's built-in CQ modifier rules.
|
|
208
|
+
*
|
|
209
|
+
* This lets third-party plugins reuse the same directed-CQ policy that the
|
|
210
|
+
* host applies to standard autocall and auto-reply flows.
|
|
211
|
+
*/
|
|
212
|
+
evaluateAutoTargetEligibility(message: ParsedFT8Message): AutoTargetEligibilityDecision;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Minimal bridge for sending structured data to plugin panels in the frontend.
|
|
216
|
+
*/
|
|
217
|
+
export interface UIBridge {
|
|
218
|
+
/**
|
|
219
|
+
* Publishes new panel data for the given declarative panel id.
|
|
220
|
+
*/
|
|
221
|
+
send(panelId: string, data: unknown): void;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":""}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import type { ParsedFT8Message, SlotInfo, QSORecord, FrameMessage } from '@tx5dr/contracts';
|
|
2
|
+
import type { PluginContext } from './context.js';
|
|
3
|
+
/**
|
|
4
|
+
* Candidate message plus an accumulated ranking score.
|
|
5
|
+
*
|
|
6
|
+
* The host constructs this shape before invoking
|
|
7
|
+
* {@link PluginHooks.onScoreCandidates}. Each scoring plugin may adjust the
|
|
8
|
+
* numeric `score`, then the host uses the final values to rank target stations.
|
|
9
|
+
*/
|
|
10
|
+
export interface ScoredCandidate extends ParsedFT8Message {
|
|
11
|
+
/**
|
|
12
|
+
* Relative desirability assigned by the scoring pipeline.
|
|
13
|
+
*
|
|
14
|
+
* Higher values are preferred. Plugins may add or subtract from the incoming
|
|
15
|
+
* score, which means scoring logic composes naturally across multiple utility
|
|
16
|
+
* plugins.
|
|
17
|
+
*/
|
|
18
|
+
score: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Decision returned from {@link StrategyRuntime.decide}.
|
|
22
|
+
*
|
|
23
|
+
* The shape is intentionally extensible so future API revisions can add new
|
|
24
|
+
* control signals without breaking existing plugins.
|
|
25
|
+
*/
|
|
26
|
+
export interface StrategyDecision {
|
|
27
|
+
/**
|
|
28
|
+
* Requests that the host stop transmitting and leave the active QSO flow.
|
|
29
|
+
*
|
|
30
|
+
* During a late re-decision (`meta.isReDecision === true`), the host treats
|
|
31
|
+
* this as an immediate abort request for the operator's in-flight
|
|
32
|
+
* transmission. In other words, `stop: true` means both:
|
|
33
|
+
* - stop the operator's automation/runtime state; and
|
|
34
|
+
* - interrupt the operator's current audio/PTT contribution right away.
|
|
35
|
+
*/
|
|
36
|
+
stop?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Metadata describing why a strategy decision is being evaluated.
|
|
40
|
+
*/
|
|
41
|
+
export interface StrategyDecisionMeta {
|
|
42
|
+
/**
|
|
43
|
+
* Indicates that the host is re-processing a late decode during the same TX
|
|
44
|
+
* window rather than advancing to a brand-new decision cycle.
|
|
45
|
+
*
|
|
46
|
+
* Strategy runtimes can use this to avoid double-counting timeouts or other
|
|
47
|
+
* one-shot transitions.
|
|
48
|
+
*/
|
|
49
|
+
isReDecision?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Pairing of a received frame and its slot metadata.
|
|
53
|
+
*
|
|
54
|
+
* This is commonly passed back into strategy/runtime APIs when a plugin wants
|
|
55
|
+
* to remember which exact message triggered a target selection.
|
|
56
|
+
*/
|
|
57
|
+
export interface LastMessageInfo {
|
|
58
|
+
/** Original frame as received from the decoder or playback pipeline. */
|
|
59
|
+
message: FrameMessage;
|
|
60
|
+
/** Slot timing metadata for the frame. */
|
|
61
|
+
slotInfo: SlotInfo;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Declarative automatic-call request proposed by a utility plugin.
|
|
65
|
+
*
|
|
66
|
+
* Utility plugins should prefer returning this shape from
|
|
67
|
+
* {@link PluginHooks.onAutoCallCandidate} instead of directly invoking
|
|
68
|
+
* `ctx.operator.call(...)` inside broadcast hooks. This lets the host arbitrate
|
|
69
|
+
* between multiple simultaneous auto-call plugins in a deterministic way.
|
|
70
|
+
*/
|
|
71
|
+
export interface AutoCallProposal {
|
|
72
|
+
/** Target callsign that should be called next. */
|
|
73
|
+
callsign: string;
|
|
74
|
+
/** Optional arbitration priority; higher values win. */
|
|
75
|
+
priority?: number;
|
|
76
|
+
/** Optional triggering frame context used to preserve slot alignment. */
|
|
77
|
+
lastMessage?: LastMessageInfo;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Immutable metadata about the automatic-call proposal that won arbitration.
|
|
81
|
+
*/
|
|
82
|
+
export interface AutoCallExecutionRequest {
|
|
83
|
+
/** Plugin name that produced the winning proposal. */
|
|
84
|
+
sourcePluginName: string;
|
|
85
|
+
/** Target callsign chosen by the arbitration step. */
|
|
86
|
+
callsign: string;
|
|
87
|
+
/** Slot that is currently being processed when the autocall starts. */
|
|
88
|
+
slotInfo: SlotInfo;
|
|
89
|
+
/**
|
|
90
|
+
* Source receive slot that produced the accepted proposal.
|
|
91
|
+
*
|
|
92
|
+
* Execution-stage plugins should prefer this slot when they need to inspect
|
|
93
|
+
* the decode environment that triggered the autocall, such as picking a
|
|
94
|
+
* quieter transmit offset from the previous RX slot.
|
|
95
|
+
*/
|
|
96
|
+
sourceSlotInfo?: SlotInfo;
|
|
97
|
+
/** Optional triggering frame context preserved from the proposal stage. */
|
|
98
|
+
lastMessage?: LastMessageInfo;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Host-managed execution plan for an accepted automatic-call proposal.
|
|
102
|
+
*
|
|
103
|
+
* Utility plugins may refine this plan in
|
|
104
|
+
* {@link PluginHooks.onConfigureAutoCallExecution}. The host then applies the
|
|
105
|
+
* merged plan before calling the active strategy runtime.
|
|
106
|
+
*/
|
|
107
|
+
export interface AutoCallExecutionPlan {
|
|
108
|
+
/**
|
|
109
|
+
* Optional transmit audio offset to apply before starting the automatic call.
|
|
110
|
+
*/
|
|
111
|
+
audioFrequency?: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Hook collection implemented by a plugin.
|
|
115
|
+
*
|
|
116
|
+
* Hooks fall into three broad categories:
|
|
117
|
+
* - pipeline hooks transform candidate lists before target selection;
|
|
118
|
+
* - strategy-only hooks steer the active automation runtime;
|
|
119
|
+
* - broadcast hooks observe lifecycle events and side effects.
|
|
120
|
+
*
|
|
121
|
+
* Hooks should be quick and defensive. A misbehaving plugin can delay the whole
|
|
122
|
+
* decode pipeline, so expensive work should be throttled, cached or deferred.
|
|
123
|
+
*/
|
|
124
|
+
export interface PluginHooks {
|
|
125
|
+
/**
|
|
126
|
+
* Proposes an automatic call target while the operator is idle.
|
|
127
|
+
*
|
|
128
|
+
* The host collects proposals from all active utility plugins, resolves
|
|
129
|
+
* conflicts deterministically, and then triggers at most one host-managed
|
|
130
|
+
* `requestCall(...)` action for the winning proposal.
|
|
131
|
+
*/
|
|
132
|
+
onAutoCallCandidate?(slotInfo: SlotInfo, messages: ParsedFT8Message[], ctx: PluginContext): AutoCallProposal | null | undefined | Promise<AutoCallProposal | null | undefined>;
|
|
133
|
+
/**
|
|
134
|
+
* Refines how an accepted automatic-call proposal should be executed.
|
|
135
|
+
*
|
|
136
|
+
* The host runs this as a utility-plugin pipeline after proposal
|
|
137
|
+
* arbitration. Each plugin receives the current execution plan and may return
|
|
138
|
+
* an updated copy. This is the preferred place to centralize execution
|
|
139
|
+
* policies such as pre-call frequency selection.
|
|
140
|
+
*/
|
|
141
|
+
onConfigureAutoCallExecution?(request: AutoCallExecutionRequest, plan: AutoCallExecutionPlan, ctx: PluginContext): AutoCallExecutionPlan | null | undefined | Promise<AutoCallExecutionPlan | null | undefined>;
|
|
142
|
+
/**
|
|
143
|
+
* Filters candidate target messages before the scoring phase.
|
|
144
|
+
*
|
|
145
|
+
* The returned array feeds into the next plugin in the utility pipeline. As a
|
|
146
|
+
* safety mechanism, returning an empty array when the input was non-empty is
|
|
147
|
+
* treated by the host as an accidental full drop and may be ignored.
|
|
148
|
+
*/
|
|
149
|
+
onFilterCandidates?(candidates: ParsedFT8Message[], ctx: PluginContext): ParsedFT8Message[] | Promise<ParsedFT8Message[]>;
|
|
150
|
+
/**
|
|
151
|
+
* Adjusts ranking scores for the current candidate list.
|
|
152
|
+
*
|
|
153
|
+
* Implementations typically add bonuses or penalties based on DXCC, signal
|
|
154
|
+
* quality, duplicate history or custom operator preferences.
|
|
155
|
+
*/
|
|
156
|
+
onScoreCandidates?(candidates: ScoredCandidate[], ctx: PluginContext): ScoredCandidate[] | Promise<ScoredCandidate[]>;
|
|
157
|
+
/**
|
|
158
|
+
* Broadcast at the start of every slot with the slot metadata and decoded
|
|
159
|
+
* messages already associated with that slot.
|
|
160
|
+
*/
|
|
161
|
+
onSlotStart?(slotInfo: SlotInfo, messages: ParsedFT8Message[], ctx: PluginContext): void;
|
|
162
|
+
/**
|
|
163
|
+
* Broadcast whenever decoded messages become available.
|
|
164
|
+
*
|
|
165
|
+
* This fires even when the operator is idle, which makes it a good place for
|
|
166
|
+
* monitoring, trigger detection and passive analytics.
|
|
167
|
+
*/
|
|
168
|
+
onDecode?(messages: ParsedFT8Message[], ctx: PluginContext): void;
|
|
169
|
+
/**
|
|
170
|
+
* Broadcast when the host locks onto a target and a QSO officially starts.
|
|
171
|
+
*/
|
|
172
|
+
onQSOStart?(info: {
|
|
173
|
+
targetCallsign: string;
|
|
174
|
+
grid?: string;
|
|
175
|
+
}, ctx: PluginContext): void;
|
|
176
|
+
/**
|
|
177
|
+
* Broadcast after a QSO has been completed and recorded.
|
|
178
|
+
*/
|
|
179
|
+
onQSOComplete?(record: QSORecord, ctx: PluginContext): void;
|
|
180
|
+
/**
|
|
181
|
+
* Broadcast when an in-progress QSO terminates unsuccessfully.
|
|
182
|
+
*/
|
|
183
|
+
onQSOFail?(info: {
|
|
184
|
+
targetCallsign: string;
|
|
185
|
+
reason: string;
|
|
186
|
+
}, ctx: PluginContext): void;
|
|
187
|
+
/**
|
|
188
|
+
* Broadcast when a named timer created through {@link PluginContext.timers}
|
|
189
|
+
* fires.
|
|
190
|
+
*/
|
|
191
|
+
onTimer?(timerId: string, ctx: PluginContext): void;
|
|
192
|
+
/**
|
|
193
|
+
* Broadcast when the user clicks one of the plugin's declared quick actions.
|
|
194
|
+
*/
|
|
195
|
+
onUserAction?(actionId: string, payload: unknown, ctx: PluginContext): void;
|
|
196
|
+
/**
|
|
197
|
+
* Broadcast after one or more persisted plugin settings have changed.
|
|
198
|
+
*
|
|
199
|
+
* The `changes` object contains only the updated keys and their new resolved
|
|
200
|
+
* values.
|
|
201
|
+
*/
|
|
202
|
+
onConfigChange?(changes: Record<string, unknown>, ctx: PluginContext): void;
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable public development surface for TX-5DR plugins.
|
|
3
|
+
*
|
|
4
|
+
* Plugin authors should import from this package instead of reaching into
|
|
5
|
+
* internal monorepo packages. The package intentionally combines:
|
|
6
|
+
* - plugin-specific contracts such as {@link PluginDefinition};
|
|
7
|
+
* - runtime helper interfaces such as {@link PluginContext};
|
|
8
|
+
* - a curated subset of shared radio/message types re-exported from
|
|
9
|
+
* `@tx5dr/contracts`.
|
|
10
|
+
*
|
|
11
|
+
* Typical usage:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import type { PluginDefinition, PluginContext } from '@tx5dr/plugin-api';
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* ```js
|
|
18
|
+
* /** @type {import('@tx5dr/plugin-api').PluginDefinition} *\/
|
|
19
|
+
* export default { ... };
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/** Core plugin definition and lifecycle interfaces. */
|
|
23
|
+
export type { PluginDefinition } from './definition.js';
|
|
24
|
+
export type { PluginContext } from './context.js';
|
|
25
|
+
export type { PluginHooks, AutoCallProposal, AutoCallExecutionRequest, AutoCallExecutionPlan, ScoredCandidate, StrategyDecision, StrategyDecisionMeta, LastMessageInfo, } from './hooks.js';
|
|
26
|
+
export type { StrategyRuntime, StrategyRuntimeContext, StrategyRuntimeSnapshot, StrategyRuntimeSlot, StrategyRuntimeSlotContentUpdate, } from './runtime.js';
|
|
27
|
+
/** Host-provided helper interfaces available through {@link PluginContext}. */
|
|
28
|
+
export type { KVStore, PluginLogger, PluginTimers, OperatorControl, RadioControl, LogbookAccess, BandAccess, IdleTransmitFrequencyOptions, AutoTargetEligibilityReason, AutoTargetEligibilityDecision, UIBridge, } from './helpers.js';
|
|
29
|
+
/** Common radio/message/settings types re-exported for plugin author convenience. */
|
|
30
|
+
export type { FT8Message, FT8MessageBase, FT8MessageCQ, FT8MessageCall, FT8MessageSignalReport, FT8MessageRogerReport, FT8MessageRRR, FT8MessageSeventyThree, FT8MessageFoxRR73, FT8MessageCustom, FT8MessageUnknown, ParsedFT8Message, LogbookAnalysis, SlotInfo, SlotPack, QSORecord, FrameMessage, ModeDescriptor, OperatorSlots, DxccStatus, TargetSelectionPriorityMode, PluginType, PluginPermission, PluginSettingType, PluginSettingDescriptor, PluginSettingScope, PluginQuickAction, PluginQuickSetting, PluginCapability, PluginPanelDescriptor, PluginPanelComponent, PluginSettingOption, PluginStorageScope, PluginStorageConfig, PluginManifest, PluginStatus, } from '@tx5dr/contracts';
|
|
31
|
+
/** Stable runtime enum values commonly referenced by plugin implementations. */
|
|
32
|
+
export { FT8MessageType } from './ft8-message-type.js';
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,uDAAuD;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,EACnB,gCAAgC,GACjC,MAAM,cAAc,CAAC;AAEtB,+EAA+E;AAC/E,YAAY,EACV,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,aAAa,EACb,UAAU,EACV,4BAA4B,EAC5B,2BAA2B,EAC3B,6BAA6B,EAC7B,QAAQ,GACT,MAAM,cAAc,CAAC;AAEtB,qFAAqF;AACrF,YAAY,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,cAAc,EACd,aAAa,EACb,UAAU,EACV,2BAA2B,EAC3B,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable public development surface for TX-5DR plugins.
|
|
3
|
+
*
|
|
4
|
+
* Plugin authors should import from this package instead of reaching into
|
|
5
|
+
* internal monorepo packages. The package intentionally combines:
|
|
6
|
+
* - plugin-specific contracts such as {@link PluginDefinition};
|
|
7
|
+
* - runtime helper interfaces such as {@link PluginContext};
|
|
8
|
+
* - a curated subset of shared radio/message types re-exported from
|
|
9
|
+
* `@tx5dr/contracts`.
|
|
10
|
+
*
|
|
11
|
+
* Typical usage:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import type { PluginDefinition, PluginContext } from '@tx5dr/plugin-api';
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* ```js
|
|
18
|
+
* /** @type {import('@tx5dr/plugin-api').PluginDefinition} *\/
|
|
19
|
+
* export default { ... };
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/** Stable runtime enum values commonly referenced by plugin implementations. */
|
|
23
|
+
export { FT8MessageType } from './ft8-message-type.js';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA8EH,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { ParsedFT8Message, FrameMessage, SlotInfo } from '@tx5dr/contracts';
|
|
2
|
+
import type { StrategyDecision, StrategyDecisionMeta } from './hooks.js';
|
|
3
|
+
/**
|
|
4
|
+
* Logical FT8 transmit slot identifiers used by the built-in automation model.
|
|
5
|
+
*
|
|
6
|
+
* These labels correspond to the six sequential transmit messages in a typical
|
|
7
|
+
* FT8 QSO flow and are used for status snapshots and UI updates.
|
|
8
|
+
*/
|
|
9
|
+
export type StrategyRuntimeSlot = 'TX1' | 'TX2' | 'TX3' | 'TX4' | 'TX5' | 'TX6';
|
|
10
|
+
/**
|
|
11
|
+
* Mutable strategy context maintained by the host/runtime pair.
|
|
12
|
+
*
|
|
13
|
+
* This object captures the operator's current conversation target and selected
|
|
14
|
+
* radio metadata. Strategy implementations can patch it incrementally through
|
|
15
|
+
* {@link StrategyRuntime.patchContext}.
|
|
16
|
+
*/
|
|
17
|
+
export interface StrategyRuntimeContext {
|
|
18
|
+
/** Currently selected target callsign, if any. */
|
|
19
|
+
targetCallsign?: string;
|
|
20
|
+
/** Grid locator reported by the target station, if known. */
|
|
21
|
+
targetGrid?: string;
|
|
22
|
+
/** Signal report sent to the target station. */
|
|
23
|
+
reportSent?: number;
|
|
24
|
+
/** Signal report received from the target station. */
|
|
25
|
+
reportReceived?: number;
|
|
26
|
+
/** Actual RF/audio frequency being used for the active QSO. */
|
|
27
|
+
actualFrequency?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Serializable snapshot of the strategy runtime.
|
|
31
|
+
*
|
|
32
|
+
* The host forwards this structure to operator-facing UI so users can inspect
|
|
33
|
+
* the current automation state without coupling the UI to strategy internals.
|
|
34
|
+
*/
|
|
35
|
+
export interface StrategyRuntimeSnapshot {
|
|
36
|
+
/** Stable or semi-stable state identifier chosen by the strategy runtime. */
|
|
37
|
+
currentState: string;
|
|
38
|
+
/** Text currently queued or associated with each logical transmit slot. */
|
|
39
|
+
slots?: Partial<Record<StrategyRuntimeSlot, string>>;
|
|
40
|
+
/** Current conversation metadata tracked by the runtime. */
|
|
41
|
+
context?: StrategyRuntimeContext;
|
|
42
|
+
/** Optional list of user-visible next states, modes or branch hints. */
|
|
43
|
+
availableSlots?: string[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Describes a slot text mutation emitted by the strategy runtime.
|
|
47
|
+
*/
|
|
48
|
+
export interface StrategyRuntimeSlotContentUpdate {
|
|
49
|
+
/** Logical slot whose rendered content should be updated. */
|
|
50
|
+
slot: StrategyRuntimeSlot;
|
|
51
|
+
/** Human-readable content for the slot, usually an FT8 message template. */
|
|
52
|
+
content: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Active controller for a `strategy` plugin.
|
|
56
|
+
*
|
|
57
|
+
* The host delegates core automation flow to this runtime. A strategy runtime is
|
|
58
|
+
* expected to be lightweight, synchronous where possible and deterministic with
|
|
59
|
+
* respect to the incoming slot/decode stream.
|
|
60
|
+
*/
|
|
61
|
+
export interface StrategyRuntime {
|
|
62
|
+
/**
|
|
63
|
+
* Re-evaluates the current automation state using the latest decoded messages.
|
|
64
|
+
*
|
|
65
|
+
* Return `{ stop: true }` to ask the host to stop transmitting. During a
|
|
66
|
+
* late re-decision (`meta.isReDecision === true`), the host also immediately
|
|
67
|
+
* aborts the operator's current live transmission contribution. Any other
|
|
68
|
+
* decision fields can be added in future API revisions, so plugins should
|
|
69
|
+
* return an object rather than a bare boolean.
|
|
70
|
+
*/
|
|
71
|
+
decide(messages: ParsedFT8Message[], meta?: StrategyDecisionMeta): Promise<StrategyDecision> | StrategyDecision;
|
|
72
|
+
/**
|
|
73
|
+
* Returns the exact text that should be transmitted next, or `null` when no
|
|
74
|
+
* transmission should be queued.
|
|
75
|
+
*/
|
|
76
|
+
getTransmitText(): string | null;
|
|
77
|
+
/**
|
|
78
|
+
* Requests that the runtime initiate or resume a call to a target station.
|
|
79
|
+
*
|
|
80
|
+
* The optional `lastMessage` provides the frame that triggered the call, which
|
|
81
|
+
* is useful when reacting to a specific CQ or completion signal.
|
|
82
|
+
*/
|
|
83
|
+
requestCall(callsign: string, lastMessage?: {
|
|
84
|
+
message: FrameMessage;
|
|
85
|
+
slotInfo: SlotInfo;
|
|
86
|
+
}): void;
|
|
87
|
+
/**
|
|
88
|
+
* Produces a serializable runtime snapshot for diagnostics and UI.
|
|
89
|
+
*/
|
|
90
|
+
getSnapshot(): StrategyRuntimeSnapshot;
|
|
91
|
+
/**
|
|
92
|
+
* Applies a partial update to the runtime context.
|
|
93
|
+
*/
|
|
94
|
+
patchContext(patch: Partial<StrategyRuntimeContext>): void;
|
|
95
|
+
/**
|
|
96
|
+
* Switches the runtime to a specific logical transmit slot/state.
|
|
97
|
+
*/
|
|
98
|
+
setState(state: StrategyRuntimeSlot): void;
|
|
99
|
+
/**
|
|
100
|
+
* Updates the human-readable content associated with a logical slot.
|
|
101
|
+
*/
|
|
102
|
+
setSlotContent(update: StrategyRuntimeSlotContentUpdate): void;
|
|
103
|
+
/**
|
|
104
|
+
* Clears transient state and returns the runtime to an idle baseline.
|
|
105
|
+
*
|
|
106
|
+
* The optional `reason` is intended for logging or diagnostics only.
|
|
107
|
+
*/
|
|
108
|
+
reset(reason?: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Optional notification that a transmission has just been queued by the host.
|
|
111
|
+
*
|
|
112
|
+
* Use this to mirror queued text into internal state when needed.
|
|
113
|
+
*/
|
|
114
|
+
onTransmissionQueued?(transmission: string): void;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEhF;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,4DAA4D;IAC5D,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,6DAA6D;IAC7D,IAAI,EAAE,mBAAmB,CAAC;IAC1B,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,MAAM,CACJ,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,IAAI,CAAC,EAAE,oBAAoB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC;IAEhD;;;OAGG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,CACT,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GAC1D,IAAI,CAAC;IAER;;OAEG;IACH,WAAW,IAAI,uBAAuB,CAAC;IAEvC;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI,CAAC;IAE3D;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAE3C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,gCAAgC,GAAG,IAAI,CAAC;IAE/D;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;;;OAIG;IACH,oBAAoB,CAAC,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACnD"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":""}
|