ultravisor 1.0.21 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "Name": "ultravisor",
3
+ "Version": "1.0.21",
4
+ "Description": "Cyclic process execution with ai integration.",
5
+ "GeneratedAt": "2026-04-10T17:13:52.044Z",
6
+ "GitCommit": "f140f37"
7
+ }
@@ -1,73 +1,327 @@
1
1
  /* ============================================================================
2
- Pict Docuserve - Base Styles
2
+ Pict Docuserve - Base Styles & Theme Variables
3
3
  ============================================================================ */
4
4
 
5
- /* Reset and base */
6
- *, *::before, *::after {
5
+ /* ----------------------------------------------------------------------------
6
+ Theme variables light defaults on :root.
7
+ Dark mode applies when either:
8
+ (a) the user explicitly selected dark via <html data-theme="dark">
9
+ (b) the user hasn't chosen anything AND the system prefers dark
10
+ An explicit <html data-theme="light"> pins the light palette regardless.
11
+ ---------------------------------------------------------------------------- */
12
+
13
+ :root
14
+ {
15
+ /* Surfaces */
16
+ --docuserve-bg: #FDFBF7;
17
+ --docuserve-bg-elevated: #FFFFFF;
18
+ --docuserve-border: #DDD6CA;
19
+ --docuserve-border-soft: #EAE3D8;
20
+
21
+ /* Text */
22
+ --docuserve-text: #2A241E;
23
+ --docuserve-text-strong: #3D3229;
24
+ --docuserve-text-muted: #5E5549;
25
+ --docuserve-text-dim: #8A7F72;
26
+
27
+ /* Accent / links */
28
+ --docuserve-accent: #2E7D74;
29
+ --docuserve-accent-hover: #236660;
30
+
31
+ /* Top bar */
32
+ --docuserve-topbar-bg: #3D3229;
33
+ --docuserve-topbar-text: #E8E0D4;
34
+ --docuserve-topbar-text-muted: #B5AA9A;
35
+ --docuserve-topbar-text-dim: #8A7F72;
36
+ --docuserve-topbar-hover-bg: #524438;
37
+ --docuserve-topbar-version-bg: rgba(255, 255, 255, 0.06);
38
+ --docuserve-topbar-version-border: rgba(255, 255, 255, 0.08);
39
+ --docuserve-topbar-version-text: #B5AA9A;
40
+
41
+ /* Sidebar */
42
+ --docuserve-sidebar-bg: #FAF7F1;
43
+ --docuserve-sidebar-border: #DDD6CA;
44
+ --docuserve-sidebar-border-soft: #E5DED1;
45
+ --docuserve-sidebar-text: #423D37;
46
+ --docuserve-sidebar-group-title: #3D3229;
47
+ --docuserve-sidebar-module-text: #5E5549;
48
+ --docuserve-sidebar-hover-bg: #EAE3D8;
49
+ --docuserve-sidebar-hover-text: #2E7D74;
50
+ --docuserve-sidebar-active-bg: #E5DED1;
51
+ --docuserve-sidebar-active-text: #2E7D74;
52
+ --docuserve-sidebar-search-bg: #FFFFFF;
53
+ --docuserve-sidebar-search-border: #DDD6CA;
54
+
55
+ /* Inline code */
56
+ --docuserve-inline-code-bg: #F0ECE4;
57
+ --docuserve-inline-code-text: #9E3A50;
58
+
59
+ /* Code block panel */
60
+ --docuserve-code-bg: #F6F3EE;
61
+ --docuserve-code-border: #E5DED1;
62
+ --docuserve-code-gutter-bg: #EFEAE0;
63
+ --docuserve-code-gutter-border: #DDD6CA;
64
+ --docuserve-code-gutter-text: #A59986;
65
+ --docuserve-code-text: #2A241E;
66
+
67
+ /* Syntax tokens — low-chroma dark-on-light palette */
68
+ --docuserve-tok-keyword: #A03472;
69
+ --docuserve-tok-string: #1A6640;
70
+ --docuserve-tok-number: #B25A00;
71
+ --docuserve-tok-comment: #8A7F72;
72
+ --docuserve-tok-operator: #2E7D74;
73
+ --docuserve-tok-punctuation: #2A241E;
74
+ --docuserve-tok-function: #2A5DB0;
75
+ --docuserve-tok-property: #9E3A50;
76
+ --docuserve-tok-tag: #9E3A50;
77
+ --docuserve-tok-attr-name: #B25A00;
78
+ --docuserve-tok-attr-value: #1A6640;
79
+
80
+ /* Tables, blockquotes, mermaid */
81
+ --docuserve-table-header-bg: #F5F0E8;
82
+ --docuserve-table-row-alt-bg: #F9F6F0;
83
+ --docuserve-blockquote-bg: #F7F5F0;
84
+ --docuserve-blockquote-border: #2E7D74;
85
+ --docuserve-blockquote-text: #5E5549;
86
+ --docuserve-mermaid-bg: #FFFFFF;
87
+
88
+ /* Scrollbars */
89
+ --docuserve-scrollbar-track: #F5F0E8;
90
+ --docuserve-scrollbar-thumb: #D4CCBE;
91
+ --docuserve-scrollbar-thumb-hover: #B5AA9A;
92
+ }
93
+
94
+ @media (prefers-color-scheme: dark)
95
+ {
96
+ :root:not([data-theme="light"])
97
+ {
98
+ --docuserve-bg: #15120F;
99
+ --docuserve-bg-elevated: #1B1814;
100
+ --docuserve-border: #2F2823;
101
+ --docuserve-border-soft: #26211C;
102
+
103
+ --docuserve-text: #E8E0D4;
104
+ --docuserve-text-strong: #F2ECE0;
105
+ --docuserve-text-muted: #B5AA9A;
106
+ --docuserve-text-dim: #7A6F62;
107
+
108
+ --docuserve-accent: #5DB8A8;
109
+ --docuserve-accent-hover: #7FCCB8;
110
+
111
+ --docuserve-topbar-bg: #1A1612;
112
+ --docuserve-topbar-text: #E8E0D4;
113
+ --docuserve-topbar-text-muted: #B5AA9A;
114
+ --docuserve-topbar-text-dim: #7A6F62;
115
+ --docuserve-topbar-hover-bg: #2A241E;
116
+ --docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
117
+ --docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
118
+ --docuserve-topbar-version-text: #B5AA9A;
119
+
120
+ --docuserve-sidebar-bg: #1B1814;
121
+ --docuserve-sidebar-border: #2F2823;
122
+ --docuserve-sidebar-border-soft: #26211C;
123
+ --docuserve-sidebar-text: #C9C0B3;
124
+ --docuserve-sidebar-group-title: #F2ECE0;
125
+ --docuserve-sidebar-module-text: #B5AA9A;
126
+ --docuserve-sidebar-hover-bg: #2A241E;
127
+ --docuserve-sidebar-hover-text: #7FCCB8;
128
+ --docuserve-sidebar-active-bg: #2F2823;
129
+ --docuserve-sidebar-active-text: #7FCCB8;
130
+ --docuserve-sidebar-search-bg: #26211C;
131
+ --docuserve-sidebar-search-border: #2F2823;
132
+
133
+ --docuserve-inline-code-bg: #2A241E;
134
+ --docuserve-inline-code-text: #E8B07A;
135
+
136
+ --docuserve-code-bg: #1E1A17;
137
+ --docuserve-code-border: #2F2823;
138
+ --docuserve-code-gutter-bg: #17130F;
139
+ --docuserve-code-gutter-border: #2F2823;
140
+ --docuserve-code-gutter-text: #6A6052;
141
+ --docuserve-code-text: #E8E0D4;
142
+
143
+ --docuserve-tok-keyword: #C678DD;
144
+ --docuserve-tok-string: #98C379;
145
+ --docuserve-tok-number: #D19A66;
146
+ --docuserve-tok-comment: #7F848E;
147
+ --docuserve-tok-operator: #56B6C2;
148
+ --docuserve-tok-punctuation: #E8E0D4;
149
+ --docuserve-tok-function: #61AFEF;
150
+ --docuserve-tok-property: #E06C75;
151
+ --docuserve-tok-tag: #E06C75;
152
+ --docuserve-tok-attr-name: #D19A66;
153
+ --docuserve-tok-attr-value: #98C379;
154
+
155
+ --docuserve-table-header-bg: #26211C;
156
+ --docuserve-table-row-alt-bg: #1F1B17;
157
+ --docuserve-blockquote-bg: #1F1B17;
158
+ --docuserve-blockquote-border: #5DB8A8;
159
+ --docuserve-blockquote-text: #C9C0B3;
160
+ --docuserve-mermaid-bg: #E8E0D4;
161
+
162
+ --docuserve-scrollbar-track: #1B1814;
163
+ --docuserve-scrollbar-thumb: #3A322B;
164
+ --docuserve-scrollbar-thumb-hover: #524438;
165
+ }
166
+ }
167
+
168
+ :root[data-theme="dark"]
169
+ {
170
+ --docuserve-bg: #15120F;
171
+ --docuserve-bg-elevated: #1B1814;
172
+ --docuserve-border: #2F2823;
173
+ --docuserve-border-soft: #26211C;
174
+
175
+ --docuserve-text: #E8E0D4;
176
+ --docuserve-text-strong: #F2ECE0;
177
+ --docuserve-text-muted: #B5AA9A;
178
+ --docuserve-text-dim: #7A6F62;
179
+
180
+ --docuserve-accent: #5DB8A8;
181
+ --docuserve-accent-hover: #7FCCB8;
182
+
183
+ --docuserve-topbar-bg: #1A1612;
184
+ --docuserve-topbar-text: #E8E0D4;
185
+ --docuserve-topbar-text-muted: #B5AA9A;
186
+ --docuserve-topbar-text-dim: #7A6F62;
187
+ --docuserve-topbar-hover-bg: #2A241E;
188
+ --docuserve-topbar-version-bg: rgba(255, 255, 255, 0.05);
189
+ --docuserve-topbar-version-border: rgba(255, 255, 255, 0.09);
190
+ --docuserve-topbar-version-text: #B5AA9A;
191
+
192
+ --docuserve-sidebar-bg: #1B1814;
193
+ --docuserve-sidebar-border: #2F2823;
194
+ --docuserve-sidebar-border-soft: #26211C;
195
+ --docuserve-sidebar-text: #C9C0B3;
196
+ --docuserve-sidebar-group-title: #F2ECE0;
197
+ --docuserve-sidebar-module-text: #B5AA9A;
198
+ --docuserve-sidebar-hover-bg: #2A241E;
199
+ --docuserve-sidebar-hover-text: #7FCCB8;
200
+ --docuserve-sidebar-active-bg: #2F2823;
201
+ --docuserve-sidebar-active-text: #7FCCB8;
202
+ --docuserve-sidebar-search-bg: #26211C;
203
+ --docuserve-sidebar-search-border: #2F2823;
204
+
205
+ --docuserve-inline-code-bg: #2A241E;
206
+ --docuserve-inline-code-text: #E8B07A;
207
+
208
+ --docuserve-code-bg: #1E1A17;
209
+ --docuserve-code-border: #2F2823;
210
+ --docuserve-code-gutter-bg: #17130F;
211
+ --docuserve-code-gutter-border: #2F2823;
212
+ --docuserve-code-gutter-text: #6A6052;
213
+ --docuserve-code-text: #E8E0D4;
214
+
215
+ --docuserve-tok-keyword: #C678DD;
216
+ --docuserve-tok-string: #98C379;
217
+ --docuserve-tok-number: #D19A66;
218
+ --docuserve-tok-comment: #7F848E;
219
+ --docuserve-tok-operator: #56B6C2;
220
+ --docuserve-tok-punctuation: #E8E0D4;
221
+ --docuserve-tok-function: #61AFEF;
222
+ --docuserve-tok-property: #E06C75;
223
+ --docuserve-tok-tag: #E06C75;
224
+ --docuserve-tok-attr-name: #D19A66;
225
+ --docuserve-tok-attr-value: #98C379;
226
+
227
+ --docuserve-table-header-bg: #26211C;
228
+ --docuserve-table-row-alt-bg: #1F1B17;
229
+ --docuserve-blockquote-bg: #1F1B17;
230
+ --docuserve-blockquote-border: #5DB8A8;
231
+ --docuserve-blockquote-text: #C9C0B3;
232
+ --docuserve-mermaid-bg: #E8E0D4;
233
+
234
+ --docuserve-scrollbar-track: #1B1814;
235
+ --docuserve-scrollbar-thumb: #3A322B;
236
+ --docuserve-scrollbar-thumb-hover: #524438;
237
+ }
238
+
239
+ /* ----------------------------------------------------------------------------
240
+ Reset and base
241
+ ---------------------------------------------------------------------------- */
242
+
243
+ *, *::before, *::after
244
+ {
7
245
  box-sizing: border-box;
8
246
  }
9
247
 
10
- html, body {
248
+ html, body
249
+ {
11
250
  margin: 0;
12
251
  padding: 0;
13
252
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
14
253
  font-size: 16px;
15
254
  line-height: 1.5;
16
- color: #423D37;
17
- background-color: #fff;
255
+ color: var(--docuserve-text);
256
+ background-color: var(--docuserve-bg);
18
257
  -webkit-font-smoothing: antialiased;
19
258
  -moz-osx-font-smoothing: grayscale;
259
+ transition: background-color 0.15s ease, color 0.15s ease;
20
260
  }
21
261
 
22
262
  /* Typography */
23
- h1, h2, h3, h4, h5, h6 {
263
+ h1, h2, h3, h4, h5, h6
264
+ {
24
265
  margin-top: 0;
25
266
  line-height: 1.3;
267
+ color: var(--docuserve-text-strong);
26
268
  }
27
269
 
28
- a {
29
- color: #2E7D74;
270
+ a
271
+ {
272
+ color: var(--docuserve-accent);
30
273
  text-decoration: none;
31
274
  }
32
275
 
33
- a:hover {
34
- color: #256861;
276
+ a:hover
277
+ {
278
+ color: var(--docuserve-accent-hover);
35
279
  }
36
280
 
37
281
  /* Application container */
38
- #Docuserve-Application-Container {
282
+ #Docuserve-Application-Container
283
+ {
39
284
  min-height: 100vh;
40
285
  }
41
286
 
42
287
  /* Utility: scrollbar styling */
43
- ::-webkit-scrollbar {
288
+ ::-webkit-scrollbar
289
+ {
44
290
  width: 8px;
291
+ height: 8px;
45
292
  }
46
293
 
47
- ::-webkit-scrollbar-track {
48
- background: #F5F0E8;
294
+ ::-webkit-scrollbar-track
295
+ {
296
+ background: var(--docuserve-scrollbar-track);
49
297
  }
50
298
 
51
- ::-webkit-scrollbar-thumb {
52
- background: #D4CCBE;
299
+ ::-webkit-scrollbar-thumb
300
+ {
301
+ background: var(--docuserve-scrollbar-thumb);
53
302
  border-radius: 4px;
54
303
  }
55
304
 
56
- ::-webkit-scrollbar-thumb:hover {
57
- background: #B5AA9A;
305
+ ::-webkit-scrollbar-thumb:hover
306
+ {
307
+ background: var(--docuserve-scrollbar-thumb-hover);
58
308
  }
59
309
 
60
310
  /* Responsive adjustments */
61
- @media (max-width: 768px) {
62
- html {
311
+ @media (max-width: 768px)
312
+ {
313
+ html
314
+ {
63
315
  font-size: 14px;
64
316
  }
65
317
 
66
- #Docuserve-Sidebar-Container {
318
+ #Docuserve-Sidebar-Container
319
+ {
67
320
  display: none;
68
321
  }
69
322
 
70
- .docuserve-body {
323
+ .docuserve-body
324
+ {
71
325
  flex-direction: column;
72
326
  }
73
327
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- Ultravisor uses Orator Authentication to manage beacon identity and connectivity. Beacons authenticate with the server before registering, receive a session cookie, and use it on all subsequent requests. If a session expires or the server restarts, beacons automatically re-authenticate and re-register eliminating "unknown beacon" errors and providing graceful reconnection.
5
+ Ultravisor uses Orator Authentication to manage beacon identity and connectivity. Beacons authenticate with the server before registering, receive a session cookie, and use it on all subsequent requests. If a session expires or the server restarts, beacons automatically re-authenticate and re-register -- eliminating "unknown beacon" errors and providing graceful reconnection.
6
6
 
7
7
  ## Architecture
8
8
 
@@ -10,28 +10,21 @@ Ultravisor uses Orator Authentication to manage beacon identity and connectivity
10
10
 
11
11
  Rather than a custom identity scheme, beacons use Orator's cookie-based session system:
12
12
 
13
- ```
14
- Beacon Client Ultravisor Server
15
- │ │
16
- │ POST /1.0/Authenticate │
17
- { UserName: "gpu-worker-1" }
18
- │───────────────────────────────────────▸
19
- │ │ Create session
20
- │ ◂─── 200 { LoggedIn: true } │ Set-Cookie: SessionID=<uuid>
21
- │ │
22
- │ POST /Beacon/Register │
23
- │ Cookie: SessionID=<uuid> │
24
- │ { Capabilities, MaxConcurrent, Tags } │
25
- │───────────────────────────────────────▸
26
- │ │ Create/reclaim beacon record
27
- │ ◂─── 200 { BeaconID: "bcn-..." } │ Associate with session
28
- │ │
29
- │ POST /Beacon/Work/Poll │
30
- │ Cookie: SessionID=<uuid> │ (every 5s)
31
- │───────────────────────────────────────▸ │
32
- │ │ Validate session → OK
33
- │ ◂─── 200 { WorkItem } or null │
34
- │ │
13
+ ```mermaid
14
+ sequenceDiagram
15
+ participant BC as Beacon Client
16
+ participant UV as Ultravisor Server
17
+ BC->>UV: POST /1.0/Authenticate<br/>{ UserName: "gpu-worker-1" }
18
+ Note right of UV: Create session
19
+ UV-->>BC: 200 { LoggedIn: true }<br/>Set-Cookie: SessionID
20
+ BC->>UV: POST /Beacon/Register<br/>Cookie: SessionID<br/>{ Capabilities, MaxConcurrent, Tags }
21
+ Note right of UV: Create/reclaim beacon record<br/>Associate with session
22
+ UV-->>BC: 200 { BeaconID: "bcn-..." }
23
+ loop Every 5s
24
+ BC->>UV: POST /Beacon/Work/Poll<br/>Cookie: SessionID
25
+ Note right of UV: Validate session
26
+ UV-->>BC: 200 { WorkItem } or null
27
+ end
35
28
  ```
36
29
 
37
30
  ### Separation of Concerns
@@ -118,10 +111,10 @@ node Ultravisor-Beacon-CLI.cjs --password <password>
118
111
 
119
112
  The system is designed for incremental security hardening:
120
113
 
121
- **Level 0 Open (default):**
114
+ **Level 0 -- Open (default):**
122
115
  No credentials required. Any beacon name is accepted. Suitable for development and trusted networks.
123
116
 
124
- **Level 1 Shared secret:**
117
+ **Level 1 -- Shared secret:**
125
118
  Set a custom authenticator that checks passwords against a configured secret or API key list:
126
119
 
127
120
  ```javascript
@@ -135,7 +128,7 @@ tmpAuth.setAuthenticator((pUsername, pPassword, fCallback) =>
135
128
  });
136
129
  ```
137
130
 
138
- **Level 2 Per-beacon credentials:**
131
+ **Level 2 -- Per-beacon credentials:**
139
132
  Validate each beacon's name and password against a database or config:
140
133
 
141
134
  ```javascript
@@ -151,7 +144,7 @@ tmpAuth.setAuthenticator((pUsername, pPassword, fCallback) =>
151
144
  });
152
145
  ```
153
146
 
154
- **Level 3 OAuth/OIDC:**
147
+ **Level 3 -- OAuth/OIDC:**
155
148
  For beacons on remote networks, use Orator Authentication's built-in OIDC provider to authenticate against an identity provider (Azure AD, Okta, etc.).
156
149
 
157
150
  ## HTTP Endpoints
@@ -195,10 +188,10 @@ For beacons on remote networks, use Orator Authentication's built-in OIDC provid
195
188
 
196
189
  ### Session Lifecycle
197
190
 
198
- 1. **Creation:** Beacon POSTs to `/1.0/Authenticate` session created in-memory Map `Set-Cookie` header returned
199
- 2. **Validation:** Every beacon request `getSessionForRequest()` parses cookie, looks up session, checks TTL, updates `LastAccess`
200
- 3. **Expiry:** Session TTL exceeded (default 24h) next request returns 401 beacon reconnects
201
- 4. **Server restart:** All sessions lost (in-memory) all beacons get 401 all reconnect automatically
191
+ 1. **Creation:** Beacon POSTs to `/1.0/Authenticate` -> session created in-memory Map -> `Set-Cookie` header returned
192
+ 2. **Validation:** Every beacon request -> `getSessionForRequest()` parses cookie, looks up session, checks TTL, updates `LastAccess`
193
+ 3. **Expiry:** Session TTL exceeded (default 24h) -> next request returns 401 -> beacon reconnects
194
+ 4. **Server restart:** All sessions lost (in-memory) -> all beacons get 401 -> all reconnect automatically
202
195
 
203
196
  ### Timeout Interactions
204
197
 
@@ -92,26 +92,20 @@ cd /path/to/config && node /path/to/Ultravisor-Beacon-CLI.cjs
92
92
  ## Anatomy of a Provider
93
93
 
94
94
  Every provider is a plain JavaScript class that extends
95
- `UltravisorBeaconCapabilityProvider`. There is no Fable dependency keep
95
+ `UltravisorBeaconCapabilityProvider`. There is no Fable dependency -- keep
96
96
  providers lightweight and self-contained.
97
97
 
98
- ```
99
- ┌──────────────────────────────────────────┐
100
- CapabilityProvider
101
- │ │
102
- │ Name "MyProvider"
103
- │ Capability "SomeCapability" │
104
- │ │
105
- │ get actions() → { ActionA, ActionB } │
106
- │ │
107
- │ initialize(fCallback) ← optional │
108
- │ shutdown(fCallback) ← optional
109
- │ │
110
- │ execute(pAction, pWorkItem, pContext, │
111
- │ fCallback, fReportProgress) │
112
- │ │
113
- │ _ProviderConfig ← per-provider cfg │
114
- └──────────────────────────────────────────┘
98
+ ```mermaid
99
+ classDiagram
100
+ class CapabilityProvider {
101
+ +String Name = "MyProvider"
102
+ +String Capability = "SomeCapability"
103
+ +Object _ProviderConfig
104
+ +get actions() Map~String, Action~
105
+ +initialize(fCallback) optional
106
+ +shutdown(fCallback) optional
107
+ +execute(pAction, pWorkItem, pContext, fCallback, fReportProgress)
108
+ }
115
109
  ```
116
110
 
117
111
  ### The `execute` Contract
@@ -693,10 +687,10 @@ class FFmpegTranscodeProvider extends libBeaconCapabilityProvider
693
687
  this._FFmpegPath = this._ProviderConfig.FFmpegPath || 'ffmpeg';
694
688
  this._FFprobePath = this._ProviderConfig.FFprobePath || 'ffprobe';
695
689
 
696
- // Preset library each preset is an array of FFmpeg arguments
690
+ // Preset library -- each preset is an array of FFmpeg arguments
697
691
  this._Presets =
698
692
  {
699
- // H.264 + AAC in MP4 plays in all modern browsers
693
+ // H.264 + AAC in MP4 -- plays in all modern browsers
700
694
  'browser-mp4':
701
695
  [
702
696
  '-c:v', 'libx264',
@@ -708,7 +702,7 @@ class FFmpegTranscodeProvider extends libBeaconCapabilityProvider
708
702
  '-pix_fmt', 'yuv420p' // broad compatibility
709
703
  ],
710
704
 
711
- // VP9 + Opus in WebM smaller files, good for web
705
+ // VP9 + Opus in WebM -- smaller files, good for web
712
706
  'browser-webm':
713
707
  [
714
708
  '-c:v', 'libvpx-vp9',
@@ -718,7 +712,7 @@ class FFmpegTranscodeProvider extends libBeaconCapabilityProvider
718
712
  '-b:a', '96k'
719
713
  ],
720
714
 
721
- // H.264 Low mobile-friendly, small file
715
+ // H.264 Low -- mobile-friendly, small file
722
716
  'browser-mobile':
723
717
  [
724
718
  '-c:v', 'libx264',
@@ -731,14 +725,14 @@ class FFmpegTranscodeProvider extends libBeaconCapabilityProvider
731
725
  '-pix_fmt', 'yuv420p'
732
726
  ],
733
727
 
734
- // Thumbnail extraction single frame to JPEG
728
+ // Thumbnail extraction -- single frame to JPEG
735
729
  'thumbnail':
736
730
  [
737
731
  '-vframes', '1',
738
732
  '-q:v', '2'
739
733
  ],
740
734
 
741
- // Audio extraction AAC in M4A container
735
+ // Audio extraction -- AAC in M4A container
742
736
  'audio-only':
743
737
  [
744
738
  '-vn',
@@ -787,7 +781,7 @@ class FFmpegTranscodeProvider extends libBeaconCapabilityProvider
787
781
  }
788
782
 
789
783
  // -------------------------------------------------------------------
790
- // Lifecycle validate FFmpeg is installed
784
+ // Lifecycle -- validate FFmpeg is installed
791
785
  // -------------------------------------------------------------------
792
786
 
793
787
  initialize(fCallback)
@@ -987,7 +981,7 @@ class FFmpegTranscodeProvider extends libBeaconCapabilityProvider
987
981
  }
988
982
 
989
983
  // -------------------------------------------------------------------
990
- // Probe return media metadata as JSON
984
+ // Probe -- return media metadata as JSON
991
985
  // -------------------------------------------------------------------
992
986
 
993
987
  _executeProbe(pWorkItem, pContext, fCallback, fReportProgress)
@@ -1163,7 +1157,7 @@ Probe file metadata before deciding how to transcode:
1163
1157
  ### Full Pipeline Manifest
1164
1158
 
1165
1159
  A complete manifest that probes a file, then transcodes it into browser-MP4,
1166
- mobile-MP4, and thumbnail distributed across media workers:
1160
+ mobile-MP4, and thumbnail -- distributed across media workers:
1167
1161
 
1168
1162
  ```json
1169
1163
  {
@@ -1272,28 +1266,28 @@ up the first task. This avoids copying the source file across workers.
1272
1266
 
1273
1267
  Use this as a reference when building your own provider:
1274
1268
 
1275
- - [ ] **Extend `CapabilityProvider`** set `Name` and `Capability` in the
1269
+ - [ ] **Extend `CapabilityProvider`** -- set `Name` and `Capability` in the
1276
1270
  constructor.
1277
- - [ ] **Declare actions** implement `get actions()` returning the action
1271
+ - [ ] **Declare actions** -- implement `get actions()` returning the action
1278
1272
  map. Each action should have a `Description` and optionally a
1279
1273
  `SettingsSchema` array.
1280
- - [ ] **Implement `execute`** dispatch on `pAction`, read from
1274
+ - [ ] **Implement `execute`** -- dispatch on `pAction`, read from
1281
1275
  `pWorkItem.Settings`, resolve paths against `pContext.StagingPath`, call
1282
1276
  `fCallback` when done.
1283
- - [ ] **Return structured results** always include `Outputs.ExitCode`
1277
+ - [ ] **Return structured results** -- always include `Outputs.ExitCode`
1284
1278
  (0 = success), `Outputs.StdOut` (summary), and `Outputs.Result` (data).
1285
- - [ ] **Use `fReportProgress`** for any operation that takes more than a
1279
+ - [ ] **Use `fReportProgress`** -- for any operation that takes more than a
1286
1280
  few seconds, report progress so the orchestrator can track it.
1287
- - [ ] **Implement `initialize`** validate prerequisites (is the binary
1281
+ - [ ] **Implement `initialize`** -- validate prerequisites (is the binary
1288
1282
  installed? can we connect to the service?). Return an error to prevent
1289
1283
  the Beacon from starting if the provider cannot function.
1290
- - [ ] **Implement `shutdown`** release resources (close browser, disconnect
1284
+ - [ ] **Implement `shutdown`** -- release resources (close browser, disconnect
1291
1285
  from service, clean up temp files).
1292
- - [ ] **Handle errors gracefully** catch exceptions and return them as
1286
+ - [ ] **Handle errors gracefully** -- catch exceptions and return them as
1293
1287
  `ExitCode: 1` results rather than throwing. The Beacon must stay alive
1294
1288
  even if individual work items fail.
1295
- - [ ] **Resolve paths** use `pContext.StagingPath` to resolve relative file
1289
+ - [ ] **Resolve paths** -- use `pContext.StagingPath` to resolve relative file
1296
1290
  paths. This keeps file operations predictable across machines.
1297
- - [ ] **Guard external access** if the provider makes network requests or
1291
+ - [ ] **Guard external access** -- if the provider makes network requests or
1298
1292
  accesses the filesystem, add configuration to restrict what it can reach
1299
1293
  (e.g. `AllowedDomains`, `AllowedPaths`).