prismcast 1.13.0 → 1.14.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.
Files changed (218) hide show
  1. package/dist/app.d.ts +88 -6
  2. package/dist/app.js +287 -154
  3. package/dist/app.js.map +1 -1
  4. package/dist/browser/cdp.d.ts +6 -17
  5. package/dist/browser/cdp.js +6 -57
  6. package/dist/browser/cdp.js.map +1 -1
  7. package/dist/browser/index.d.ts +106 -23
  8. package/dist/browser/index.js +292 -225
  9. package/dist/browser/index.js.map +1 -1
  10. package/dist/browser/precaching.d.ts +25 -11
  11. package/dist/browser/precaching.js +245 -97
  12. package/dist/browser/precaching.js.map +1 -1
  13. package/dist/browser/tabCapture.js +3 -10
  14. package/dist/browser/tabCapture.js.map +1 -1
  15. package/dist/browser/tuning/comcastPolymer.js +13 -14
  16. package/dist/browser/tuning/comcastPolymer.js.map +1 -1
  17. package/dist/browser/tuning/hbo.js +34 -17
  18. package/dist/browser/tuning/hbo.js.map +1 -1
  19. package/dist/browser/video.d.ts +1 -1
  20. package/dist/browser/video.js +3 -3
  21. package/dist/channels/index.js +5 -5
  22. package/dist/channels/index.js.map +1 -1
  23. package/dist/cliHelp.d.ts +11 -0
  24. package/dist/cliHelp.js +148 -0
  25. package/dist/cliHelp.js.map +1 -0
  26. package/dist/config/channelForm.js +5 -4
  27. package/dist/config/channelForm.js.map +1 -1
  28. package/dist/config/consistencyProbe.d.ts +2 -4
  29. package/dist/config/consistencyProbe.js +8 -51
  30. package/dist/config/consistencyProbe.js.map +1 -1
  31. package/dist/config/index.d.ts +107 -55
  32. package/dist/config/index.js +499 -267
  33. package/dist/config/index.js.map +1 -1
  34. package/dist/config/paths.d.ts +13 -8
  35. package/dist/config/paths.js +21 -25
  36. package/dist/config/paths.js.map +1 -1
  37. package/dist/config/persistence.d.ts +57 -11
  38. package/dist/config/persistence.js +127 -44
  39. package/dist/config/persistence.js.map +1 -1
  40. package/dist/config/reactivity.d.ts +60 -36
  41. package/dist/config/reactivity.js +89 -116
  42. package/dist/config/reactivity.js.map +1 -1
  43. package/dist/config/services.d.ts +61 -26
  44. package/dist/config/services.js +137 -68
  45. package/dist/config/services.js.map +1 -1
  46. package/dist/config/streamSettings.d.ts +24 -0
  47. package/dist/config/streamSettings.js +17 -0
  48. package/dist/config/streamSettings.js.map +1 -0
  49. package/dist/config/userChannels.d.ts +60 -52
  50. package/dist/config/userChannels.js +138 -188
  51. package/dist/config/userChannels.js.map +1 -1
  52. package/dist/config/userConfig.d.ts +224 -61
  53. package/dist/config/userConfig.js +351 -134
  54. package/dist/config/userConfig.js.map +1 -1
  55. package/dist/hdhr/discover.d.ts +7 -1
  56. package/dist/hdhr/discover.js +12 -6
  57. package/dist/hdhr/discover.js.map +1 -1
  58. package/dist/hdhr/index.d.ts +51 -10
  59. package/dist/hdhr/index.js +108 -112
  60. package/dist/hdhr/index.js.map +1 -1
  61. package/dist/hdhr/udp.d.ts +11 -4
  62. package/dist/hdhr/udp.js +25 -20
  63. package/dist/hdhr/udp.js.map +1 -1
  64. package/dist/index.js +16 -143
  65. package/dist/index.js.map +1 -1
  66. package/dist/native/index.d.ts +1 -1
  67. package/dist/native/index.js +4 -3
  68. package/dist/native/index.js.map +1 -1
  69. package/dist/native/proxy.d.ts +1 -1
  70. package/dist/native/proxy.js +36 -28
  71. package/dist/native/proxy.js.map +1 -1
  72. package/dist/routes/cdp.d.ts +7 -6
  73. package/dist/routes/cdp.js +9 -8
  74. package/dist/routes/cdp.js.map +1 -1
  75. package/dist/routes/components.d.ts +23 -5
  76. package/dist/routes/components.js +21 -4
  77. package/dist/routes/components.js.map +1 -1
  78. package/dist/routes/config/channels/endpoints/browse.js +39 -29
  79. package/dist/routes/config/channels/endpoints/browse.js.map +1 -1
  80. package/dist/routes/config/channels/endpoints/bulk.js +2 -6
  81. package/dist/routes/config/channels/endpoints/bulk.js.map +1 -1
  82. package/dist/routes/config/channels/endpoints/predefined.js +5 -15
  83. package/dist/routes/config/channels/endpoints/predefined.js.map +1 -1
  84. package/dist/routes/config/channels/endpoints/prefs.js +7 -6
  85. package/dist/routes/config/channels/endpoints/prefs.js.map +1 -1
  86. package/dist/routes/config/channels/endpoints/service.js +6 -5
  87. package/dist/routes/config/channels/endpoints/service.js.map +1 -1
  88. package/dist/routes/config/channels/endpoints/tags.js +4 -16
  89. package/dist/routes/config/channels/endpoints/tags.js.map +1 -1
  90. package/dist/routes/config/channels/table.d.ts +2 -1
  91. package/dist/routes/config/channels/table.js +11 -13
  92. package/dist/routes/config/channels/table.js.map +1 -1
  93. package/dist/routes/config/http/envelope.d.ts +6 -3
  94. package/dist/routes/config/http/envelope.js +18 -5
  95. package/dist/routes/config/http/envelope.js.map +1 -1
  96. package/dist/routes/config/index.d.ts +21 -13
  97. package/dist/routes/config/index.js +47 -34
  98. package/dist/routes/config/index.js.map +1 -1
  99. package/dist/routes/config/settings.d.ts +43 -6
  100. package/dist/routes/config/settings.js +225 -125
  101. package/dist/routes/config/settings.js.map +1 -1
  102. package/dist/routes/config/vocabulary.d.ts +24 -0
  103. package/dist/routes/config/vocabulary.js +33 -0
  104. package/dist/routes/config/vocabulary.js.map +1 -0
  105. package/dist/routes/debug.js +28 -13
  106. package/dist/routes/debug.js.map +1 -1
  107. package/dist/routes/root/content.js +33 -26
  108. package/dist/routes/root/content.js.map +1 -1
  109. package/dist/routes/root/scripts/channels.js +23 -11
  110. package/dist/routes/root/scripts/channels.js.map +1 -1
  111. package/dist/routes/root/scripts/config.d.ts +1 -1
  112. package/dist/routes/root/scripts/config.js +127 -79
  113. package/dist/routes/root/scripts/config.js.map +1 -1
  114. package/dist/routes/root/scripts/shared.js +34 -23
  115. package/dist/routes/root/scripts/shared.js.map +1 -1
  116. package/dist/routes/root/scripts/status.handlers.d.ts +8 -13
  117. package/dist/routes/root/scripts/status.handlers.js +35 -21
  118. package/dist/routes/root/scripts/status.handlers.js.map +1 -1
  119. package/dist/routes/root/styles.js +13 -16
  120. package/dist/routes/root/styles.js.map +1 -1
  121. package/dist/routes/services.js +12 -16
  122. package/dist/routes/services.js.map +1 -1
  123. package/dist/routes/theme.js +12 -12
  124. package/dist/routes/theme.js.map +1 -1
  125. package/dist/routes/ui.d.ts +4 -3
  126. package/dist/routes/ui.js +17 -13
  127. package/dist/routes/ui.js.map +1 -1
  128. package/dist/service/generators.js +12 -9
  129. package/dist/service/generators.js.map +1 -1
  130. package/dist/streaming/captureSession.d.ts +4 -4
  131. package/dist/streaming/captureSession.js +6 -7
  132. package/dist/streaming/captureSession.js.map +1 -1
  133. package/dist/streaming/codec.d.ts +12 -2
  134. package/dist/streaming/codec.js +40 -28
  135. package/dist/streaming/codec.js.map +1 -1
  136. package/dist/streaming/fmp4Segmenter.d.ts +14 -4
  137. package/dist/streaming/fmp4Segmenter.js +99 -79
  138. package/dist/streaming/fmp4Segmenter.js.map +1 -1
  139. package/dist/streaming/hls.d.ts +21 -14
  140. package/dist/streaming/hls.js +148 -122
  141. package/dist/streaming/hls.js.map +1 -1
  142. package/dist/streaming/hlsResume.d.ts +36 -13
  143. package/dist/streaming/hlsResume.js +68 -37
  144. package/dist/streaming/hlsResume.js.map +1 -1
  145. package/dist/streaming/monitor.d.ts +5 -3
  146. package/dist/streaming/monitor.js +47 -37
  147. package/dist/streaming/monitor.js.map +1 -1
  148. package/dist/streaming/mp4Parser.d.ts +29 -4
  149. package/dist/streaming/mp4Parser.js +49 -7
  150. package/dist/streaming/mp4Parser.js.map +1 -1
  151. package/dist/streaming/playlistBuilder.d.ts +1 -2
  152. package/dist/streaming/playlistBuilder.js +2 -3
  153. package/dist/streaming/playlistBuilder.js.map +1 -1
  154. package/dist/streaming/preroll.d.ts +43 -16
  155. package/dist/streaming/preroll.js +112 -62
  156. package/dist/streaming/preroll.js.map +1 -1
  157. package/dist/streaming/pretune.d.ts +2 -2
  158. package/dist/streaming/pretune.js +11 -7
  159. package/dist/streaming/pretune.js.map +1 -1
  160. package/dist/streaming/recovery.d.ts +29 -2
  161. package/dist/streaming/recovery.js +43 -4
  162. package/dist/streaming/recovery.js.map +1 -1
  163. package/dist/streaming/registry.d.ts +13 -10
  164. package/dist/streaming/registry.js +6 -5
  165. package/dist/streaming/registry.js.map +1 -1
  166. package/dist/streaming/setup.d.ts +29 -20
  167. package/dist/streaming/setup.js +181 -170
  168. package/dist/streaming/setup.js.map +1 -1
  169. package/dist/streaming/showInfo.d.ts +24 -12
  170. package/dist/streaming/showInfo.js +120 -113
  171. package/dist/streaming/showInfo.js.map +1 -1
  172. package/dist/streaming/statusEmitter.d.ts +15 -10
  173. package/dist/streaming/statusEmitter.js +24 -20
  174. package/dist/streaming/statusEmitter.js.map +1 -1
  175. package/dist/types/config.d.ts +24 -13
  176. package/dist/types/config.js +5 -1
  177. package/dist/types/config.js.map +1 -1
  178. package/dist/types/index.d.ts +3 -2
  179. package/dist/types/index.js +2 -1
  180. package/dist/types/index.js.map +1 -1
  181. package/dist/types/profiles.d.ts +2 -2
  182. package/dist/types/selection.d.ts +12 -10
  183. package/dist/types/streaming.d.ts +12 -5
  184. package/dist/types/streaming.js +12 -5
  185. package/dist/types/streaming.js.map +1 -1
  186. package/dist/utils/debugFilter.d.ts +3 -2
  187. package/dist/utils/debugFilter.js +7 -5
  188. package/dist/utils/debugFilter.js.map +1 -1
  189. package/dist/{hdhr → utils}/deviceId.d.ts +1 -1
  190. package/dist/{hdhr → utils}/deviceId.js +11 -29
  191. package/dist/utils/deviceId.js.map +1 -0
  192. package/dist/utils/errors.d.ts +7 -0
  193. package/dist/utils/errors.js +12 -3
  194. package/dist/utils/errors.js.map +1 -1
  195. package/dist/utils/fileLogger.d.ts +23 -12
  196. package/dist/utils/fileLogger.js +73 -41
  197. package/dist/utils/fileLogger.js.map +1 -1
  198. package/dist/utils/httpErrors.d.ts +13 -0
  199. package/dist/utils/httpErrors.js +22 -0
  200. package/dist/utils/httpErrors.js.map +1 -0
  201. package/dist/utils/index.d.ts +3 -0
  202. package/dist/utils/index.js +3 -0
  203. package/dist/utils/index.js.map +1 -1
  204. package/dist/utils/logger.d.ts +9 -8
  205. package/dist/utils/logger.js +64 -20
  206. package/dist/utils/logger.js.map +1 -1
  207. package/dist/utils/markup.js +8 -3
  208. package/dist/utils/markup.js.map +1 -1
  209. package/dist/utils/plainObject.d.ts +6 -0
  210. package/dist/utils/plainObject.js +18 -0
  211. package/dist/utils/plainObject.js.map +1 -0
  212. package/dist/utils/runtimeIdentity.context.js +1 -29
  213. package/dist/utils/runtimeIdentity.context.js.map +1 -1
  214. package/dist/utils/runtimeIdentity.d.ts +17 -6
  215. package/dist/utils/runtimeIdentity.js +50 -17
  216. package/dist/utils/runtimeIdentity.js.map +1 -1
  217. package/package.json +5 -5
  218. package/dist/hdhr/deviceId.js.map +0 -1
@@ -2,11 +2,12 @@
2
2
  *
3
3
  * logger.ts: Logging utilities with color-coded output for PrismCast.
4
4
  */
5
- import { format, styleText } from "node:util";
5
+ import { format, inspect, styleText } from "node:util";
6
6
  import { getStreamId, resolveContextShowName } from "./streamContext.js";
7
7
  import { initDebugFilter, isAnyDebugEnabled, isCategoryEnabled } from "./debugFilter.js";
8
8
  import { emitLogEntry } from "./logEmitter.js";
9
9
  import { formatTimestamp } from "./format.js";
10
+ import { isPlainObject } from "./plainObject.js";
10
11
  import { writeLogEntry } from "./fileLogger.js";
11
12
  /* Terminal color choices for log output. Warnings appear in yellow and errors in red, making it easy to spot issues when scanning log output. Coloring is delegated
12
13
  * to node:util.styleText so the SGR sequences are managed by the platform rather than hand-written escape codes.
@@ -31,7 +32,8 @@ export function isConsoleLogging() {
31
32
  return useConsoleLogging;
32
33
  }
33
34
  /* Debug logging is controlled by the category-based filter system in debugFilter.ts. The --debug CLI flag enables all categories (equivalent to
34
- * PRISMCAST_DEBUG=*), while the PRISMCAST_DEBUG environment variable allows fine-grained category selection.
35
+ * PRISMCAST_DEBUG=*), the PRISMCAST_DEBUG environment variable allows fine-grained category selection, and the /debug page sets the filter at runtime and
36
+ * persists it in the configuration.
35
37
  */
36
38
  /**
37
39
  * Enables or disables debug logging. When called with true, initializes the debug filter with wildcard (*) to enable all categories.
@@ -41,25 +43,57 @@ export function setDebugLogging(enabled) {
41
43
  initDebugFilter(enabled ? "*" : "");
42
44
  }
43
45
  /**
44
- * Returns whether any debug logging is currently enabled.
45
- * @returns True if any debug categories are enabled, false otherwise.
46
+ * Returns whether any debug filter pattern is configured. An exclude-only pattern counts, so a true answer does not mean a category is enabled.
47
+ * @returns True if any debug filter pattern is configured, including an exclude-only pattern, false otherwise.
46
48
  */
47
49
  export function isDebugLogging() {
48
50
  return isAnyDebugEnabled();
49
51
  }
50
52
  /* The LOG object provides a centralized logging interface with color-coded output and printf-style format strings. All methods accept a format string followed by
51
- * optional arguments, using Node's util.format() for interpolation. Supported format specifiers include %s (string), %d (number), %j (JSON), and %o (object).
53
+ * optional arguments, using Node's util.format() for interpolation. The supported format specifiers are the ones FORMAT_SPECIFIER_PATTERN holds: %s (string),
54
+ * %d (number), %i (integer), %f (floating point), %j (JSON), %o and %O (object), and %c (CSS, consumed and ignored).
52
55
  *
53
56
  * Stream context is automatically detected via AsyncLocalStorage. When running within a stream context (established by runWithStreamContext()), log messages are
54
57
  * automatically prefixed with the stream ID for correlation across concurrent streaming sessions.
55
58
  *
56
59
  * For logging outside a stream context (e.g., iterating over streams in a disconnect handler), use LOG.withStreamId() to create a bound logger.
57
60
  */
61
+ /* The format specifiers util.format() consumes an argument for. An escaped percent consumes nothing, so the count strips every escaped percent before it matches,
62
+ * and what remains mirrors util.format()'s own consumption: a message whose arguments outnumber its specifiers leaves its trailing arguments unconsumed, which is
63
+ * how logWithLevel tells a trailing context object from an argument a specifier renders. The pattern is global so String.prototype.match returns every
64
+ * occurrence, and it is read only through match, because a global pattern's own exec and test carry their position from one call to the next in lastIndex.
65
+ */
66
+ const FORMAT_SPECIFIER_PATTERN = /%[sdifjoOc]/g;
67
+ // An escaped percent. util.format() renders it as one literal percent sign, and it consumes no argument.
68
+ const ESCAPED_PERCENT = "%%";
69
+ /**
70
+ * Counts the specifiers in a message that each consume an argument, with escaped percents removed first so "%%s" reads as a literal percent sign and an "s".
71
+ * @param message - The format string.
72
+ * @returns The number of argument-consuming specifiers in the message.
73
+ */
74
+ function countFormatSpecifiers(message) {
75
+ return message.replaceAll(ESCAPED_PERCENT, "").match(FORMAT_SPECIFIER_PATTERN)?.length ?? 0;
76
+ }
77
+ /**
78
+ * Formats the sentence of a line whose trailing context object has been set aside, from the message and the arguments that precede the context.
79
+ * @param message - The format string.
80
+ * @param args - The arguments that precede the context object.
81
+ * @returns The formatted sentence, before normalization.
82
+ */
83
+ function formatSentence(message, args) {
84
+ if (args.length > 0) {
85
+ return format(message, ...args);
86
+ }
87
+ // util.format() renders an escaped percent only when it is given an argument, and the context object is such an argument. A message that leaves no argument
88
+ // for the sentence has no specifier, so rendering its escaped percents is all util.format() would do to the sentence if the context went through it as well.
89
+ return message.replaceAll(ESCAPED_PERCENT, "%");
90
+ }
58
91
  /* The logger commits to emitting exactly one sentence terminator on every non-debug line so callers do not have to reason about whether the format string or an
59
92
  * interpolated value carries the punctuation. This encodes the "non-debug logs are complete sentences" project rule as logger behavior rather than as per-call-site
60
- * discipline - a producer changing its message punctuation can no longer silently regress an interpolated log line, and the differing punctuation conventions
93
+ * discipline - a producer changing its message punctuation cannot silently regress an interpolated log line, and the differing punctuation conventions
61
94
  * between formatError (which strips trailing punctuation) and userMessage/validator strings (which carry it) become invisible to callers. Debug stays raw because
62
- * debug is fragments by convention.
95
+ * debug is fragments by convention. The terminator closes the sentence, and a trailing context object follows it: a line in the house form, a complete sentence
96
+ * with its details in a context object, ends with the object rather than with a period after it.
63
97
  */
64
98
  /**
65
99
  * Normalizes a non-debug log message to exactly one terminal sentence terminator. Runs of trailing periods collapse to a single period (the double-period
@@ -98,8 +132,10 @@ function emitToSubscribers(level, message, categoryTag) {
98
132
  emitLogEntry(entry);
99
133
  }
100
134
  /**
101
- * Interpolates the format string against its arguments and normalizes non-debug messages to a single trailing sentence terminator, then hands the result to
102
- * emitFormatted for prefixing, SSE emission, and output routing. Debug messages skip normalization because debug output is fragments by convention.
135
+ * Interpolates the format string against its arguments and normalizes non-debug messages to a single sentence terminator, then hands the result to emitFormatted
136
+ * for prefixing, SSE emission, and output routing. A non-debug line whose last argument is a plain object that no specifier consumes carries that object as its
137
+ * context: the sentence is formatted from the message and the other arguments and normalized on its own, and the context follows its terminator as
138
+ * util.inspect() renders it. Debug messages skip normalization because debug output is fragments by convention.
103
139
  * @param level - The log level (error, warn, info, debug).
104
140
  * @param color - Color name accepted by node:util.styleText, or null for the default terminal color.
105
141
  * @param message - The format string.
@@ -108,15 +144,22 @@ function emitToSubscribers(level, message, categoryTag) {
108
144
  * @param categoryTag - Optional debug category tag for category-filtered debug messages.
109
145
  */
110
146
  function logWithLevel(level, color, message, args, explicitStreamId, categoryTag) {
111
- const rawFormatted = args.length > 0 ? format(message, ...args) : message;
147
+ const context = args.at(-1);
148
+ // A trailing plain object that the message's specifiers leave unconsumed is the line's context. On a non-debug line the terminator closes the sentence, formatted
149
+ // from the message and the other arguments, and the context follows it as util.inspect() renders it, the rendering util.format() gives an argument it does not
150
+ // consume. The plain-object test runs before the specifier count because it is the cheaper check and a line without a trailing object fails it at once.
151
+ if ((level !== "debug") && isPlainObject(context) && (args.length > countFormatSpecifiers(message))) {
152
+ emitFormatted(level, color, normalizeSentence(formatSentence(message, args.slice(0, -1))) + " " + inspect(context), explicitStreamId, categoryTag);
153
+ return;
154
+ }
155
+ const formatted = args.length > 0 ? format(message, ...args) : message;
112
156
  // Non-debug levels are guaranteed sentence-terminated; debug stays raw because debug is fragments by convention. The contract lives here, not at the call site.
113
- const formatted = (level === "debug") ? rawFormatted : normalizeSentence(rawFormatted);
114
- emitFormatted(level, color, formatted, explicitStreamId, categoryTag);
157
+ emitFormatted(level, color, (level === "debug") ? formatted : normalizeSentence(formatted), explicitStreamId, categoryTag);
115
158
  }
116
159
  /**
117
160
  * Emits an already-formatted message body through the full logger pipeline: stream-ID prefix composition, SSE subscriber emission, and console-or-file routing.
118
- * Shared between logWithLevel (which normalizes first) and displayLine (which deliberately bypasses normalization for tabular display). Factoring this out keeps
119
- * the two callers from drifting on prefix shape, SSE routing, or color handling.
161
+ * Shared between logWithLevel (which normalizes first) and displayLine (which deliberately bypasses normalization for tabular display). One shared emitter keeps
162
+ * every caller from drifting on prefix shape, SSE routing, or color handling.
120
163
  * @param level - The log level (drives console method routing and category tagging).
121
164
  * @param color - Color name for styleText, or null for the default terminal color.
122
165
  * @param formatted - The fully-prepared message body (post-normalization if applicable).
@@ -186,12 +229,13 @@ export function displayLine(message, ...args) {
186
229
  }
187
230
  export const LOG = {
188
231
  /**
189
- * Logs a debug message in cyan, filtered by category. Debug messages are only output when the specified category is enabled via the PRISMCAST_DEBUG environment
190
- * variable or the --debug CLI flag (which enables all categories). Use this for verbose diagnostic information that would clutter normal logs.
232
+ * Logs a debug message in cyan, filtered by category. Debug messages are output only when the debug filter in debugFilter.ts enables the specified category.
233
+ * The filter is set by the PRISMCAST_DEBUG environment variable, by the --debug CLI flag (which enables all categories), or from the /debug page, whose filter
234
+ * is persisted in the configuration and applied at startup. Use this for verbose diagnostic information that would clutter normal logs.
191
235
  *
192
236
  * Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
193
237
  * @param category - The debug category (e.g., "tuning:hulu", "recovery:tab", "streaming:segmenter").
194
- * @param message - The format string (supports %s, %d, %j, %o).
238
+ * @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
195
239
  * @param args - Values to interpolate into the format string.
196
240
  */
197
241
  debug: function (category, message, ...args) {
@@ -205,7 +249,7 @@ export const LOG = {
205
249
  * stream initialization errors. The red color provides immediate visual indication of serious problems requiring attention.
206
250
  *
207
251
  * Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
208
- * @param message - The format string (supports %s, %d, %j, %o).
252
+ * @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
209
253
  * @param args - Values to interpolate into the format string.
210
254
  */
211
255
  error: function (message, ...args) {
@@ -216,7 +260,7 @@ export const LOG = {
216
260
  * status updates.
217
261
  *
218
262
  * Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
219
- * @param message - The format string (supports %s, %d, %j, %o).
263
+ * @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
220
264
  * @param args - Values to interpolate into the format string.
221
265
  */
222
266
  info: function (message, ...args) {
@@ -227,7 +271,7 @@ export const LOG = {
227
271
  * recovered from, missing optional features, or degraded functionality.
228
272
  *
229
273
  * Stream ID is automatically included if running within a stream context (established by runWithStreamContext()).
230
- * @param message - The format string (supports %s, %d, %j, %o).
274
+ * @param message - The format string (supports %s, %d, %i, %f, %j, %o, %O, %c).
231
275
  * @param args - Values to interpolate into the format string.
232
276
  */
233
277
  warn: function (message, ...args) {
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -5,9 +5,10 @@
5
5
  /* This module is the single source of truth for escape-style markup encoding. HTML escaping (used pervasively across the routes layer to embed user-provided
6
6
  * values in server-rendered pages) and XML escaping (used by the macOS launchd plist generator and the HDHomeRun device description) cover the same reserved
7
7
  * characters; only the apostrophe entity differs - HTML5 spells it ' and XML spells it '. Centralizing both surfaces over a shared regex and a
8
- * Readonly entity map keeps the character class in one place so adding an entity to one flavor can't silently desync the other.
8
+ * Readonly entity map per flavor keeps the character class in one place, so every flavor matches the same characters.
9
9
  */
10
- // The shared character class for both HTML and XML escape sweeps. Defined once so the two escape variants never disagree about which characters they encode.
10
+ // The shared character class for the HTML and XML escape sweeps. Defined once so every escape variant matches the same characters...each entity map still needs
11
+ // an entry for every character here, because escapeMarkup passes a matched character with no entry through unescaped.
11
12
  const MARKUP_ENTITY_REGEX = /[&<>"']/g;
12
13
  // HTML5 entity map. The apostrophe entity is &#39; because the named entity &apos; was only added to HTML5 (older browsers fall back to the numeric reference).
13
14
  const HTML_ENTITIES = {
@@ -27,7 +28,7 @@ const XML_ENTITIES = {
27
28
  };
28
29
  /**
29
30
  * Shared escape body for both HTML and XML. Returns the input with every character in MARKUP_ENTITY_REGEX replaced by its entity from the supplied table. The
30
- * private factor here is intentional: it commits the two public escapers to the same regex and the same Record-based lookup so behavior never drifts between them.
31
+ * private factor here is intentional: it commits each public escaper to the same regex and the same Record-based lookup, so every flavor matches the same characters.
31
32
  * @param value - The string to escape.
32
33
  * @param entities - The entity table that owns the per-character substitution.
33
34
  * @returns The escaped string.
@@ -52,6 +53,10 @@ export function escapeHtml(value) {
52
53
  export function escapeXml(value) {
53
54
  return escapeMarkup(value, XML_ENTITIES);
54
55
  }
56
+ /* The status script's HANDLER_FUNCTIONS ships this function to the browser by its source, beside the badge builder that calls it, so its body references only its
57
+ * parameter, Object.entries and escapeHtml, each of which the browser holds by the same name. A call to any other helper leaves the shipped stream table throwing
58
+ * in the browser while every Node row passes, because the helper's binding exists only here.
59
+ */
55
60
  /**
56
61
  * Serializes a record of HTML attribute names to values into the inline fragment suitable for embedding in an opening tag. Value semantics keep this tied
57
62
  * to the way HTML actually shapes attributes: undefined and boolean false are omitted entirely; boolean true emits the attribute name alone (HTML5 boolean
@@ -1 +1 @@
1
- {"version":3,"file":"markup.js","sourceRoot":"","sources":["../../src/utils/markup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH,6JAA6J;AAC7J,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAEvC,gKAAgK;AAChK,MAAM,aAAa,GAAqC;IAEtD,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;CACZ,CAAC;AAEF,wIAAwI;AACxI,MAAM,YAAY,GAAqC;IAErD,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;CACZ,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,KAAa,EAAE,QAA0C;IAE7E,OAAO,KAAK,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IAEtC,OAAO,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IAErC,OAAO,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,KAA6D;IAE1F,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAI,MAAM,CAAE,IAAI,EAAE,KAAK,CAAE,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAEnD,IAAG,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;YAE9C,SAAS;QACX,CAAC;QAED,IAAG,KAAK,KAAK,IAAI,EAAE,CAAC;YAElB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAErB,SAAS;QACX,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"markup.js","sourceRoot":"","sources":["../../src/utils/markup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH,gKAAgK;AAChK,sHAAsH;AACtH,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAEvC,gKAAgK;AAChK,MAAM,aAAa,GAAqC;IAEtD,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;CACZ,CAAC;AAEF,wIAAwI;AACxI,MAAM,YAAY,GAAqC;IAErD,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;CACZ,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,KAAa,EAAE,QAA0C;IAE7E,OAAO,KAAK,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IAEtC,OAAO,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IAErC,OAAO,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,KAA6D;IAE1F,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAI,MAAM,CAAE,IAAI,EAAE,KAAK,CAAE,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAEnD,IAAG,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;YAE9C,SAAS;QACX,CAAC;QAED,IAAG,KAAK,KAAK,IAAI,EAAE,CAAC;YAElB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAErB,SAAS;QACX,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Predicate: is the value a plain object (not array, not null, not a class instance like Date)?
3
+ * @param value - The candidate.
4
+ * @returns True if value is a plain object literal.
5
+ */
6
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
@@ -0,0 +1,18 @@
1
+ /* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * plainObject.ts: Plain-object predicate for PrismCast.
4
+ */
5
+ /**
6
+ * Predicate: is the value a plain object (not array, not null, not a class instance like Date)?
7
+ * @param value - The candidate.
8
+ * @returns True if value is a plain object literal.
9
+ */
10
+ export function isPlainObject(value) {
11
+ if ((value === null) || (typeof value !== "object") || Array.isArray(value)) {
12
+ return false;
13
+ }
14
+ // Object.getPrototypeOf is typed as returning any in the standard lib. Cast through unknown so the comparisons below are type-safe.
15
+ const proto = Object.getPrototypeOf(value);
16
+ return (proto === null) || (proto === Object.prototype);
17
+ }
18
+ //# sourceMappingURL=plainObject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plainObject.js","sourceRoot":"","sources":["../../src/utils/plainObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAE1C,IAAG,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAE3E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oIAAoI;IACpI,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAY,CAAC;IAEtD,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC;AAC1D,CAAC"}
@@ -2,44 +2,16 @@ import { getBootSessionId } from "./bootSession.js";
2
2
  import { isProcessRunning } from "./pid.js";
3
3
  import { listProcesses } from "./processInspector.js";
4
4
  import { systemClock } from "homebridge-plugin-utils";
5
- /* The product-identity token searched for in a process's command line. This mirrors the package name / SERVICE_NAME identity; it lives as a local constant
6
- * because the runtime-identity context must remain free of sideways imports into identity.ts. Matching is case-insensitive so launcher casing differences (e.g.
7
- * the macOS app bundle versus the lowercase binary) do not cause a false negative.
8
- */
9
- const PRISMCAST_COMMAND_TOKEN = "prismcast";
10
5
  /**
11
6
  * Builds the default RuntimeIdentityContext from real runtime I/O.
12
7
  * @returns A RuntimeIdentityContext populated from the live process.
13
8
  */
14
9
  export function createDefaultRuntimeIdentityContext() {
15
10
  return {
11
+ commandLineOf: (pid) => listProcesses().find((entry) => entry.pid === pid)?.commandLine ?? null,
16
12
  getBootSessionId: () => getBootSessionId(),
17
- isPidOurProcess: (pid) => resolvePidIdentity(pid),
18
13
  isProcessRunning,
19
14
  now: () => systemClock.now()
20
15
  };
21
16
  }
22
- /**
23
- * Resolves whether the live process at the given PID is genuinely a PrismCast instance by enumerating the OS process table and matching the product token in the
24
- * row's command line. Returns true when the row's command line contains the token, false when it contains a non-empty command line without the token, and null
25
- * when identity cannot be determined - the process table is empty (unsupported platform or enumeration failure), the PID is absent from it, or the matching
26
- * row reports an empty command line (kernel threads, hidden command lines). The null cases all map upstream to the conservative held-live verdict.
27
- * @param pid - The PID to identify.
28
- * @returns True for a confirmed PrismCast process, false for a confirmed different process, null when identity cannot be determined.
29
- */
30
- function resolvePidIdentity(pid) {
31
- const processes = listProcesses();
32
- const match = processes.find((entry) => entry.pid === pid);
33
- // The PID is absent from the snapshot (it exited between the liveness check and this enumeration, or the platform returned an empty table). We cannot prove the
34
- // process is unrelated, so identity is indeterminate.
35
- if (match === undefined) {
36
- return null;
37
- }
38
- const commandLine = match.commandLine.trim();
39
- // An empty command line (kernel thread, process that hid its argv) gives us nothing to match against, so identity remains indeterminate.
40
- if (commandLine === "") {
41
- return null;
42
- }
43
- return commandLine.toLowerCase().includes(PRISMCAST_COMMAND_TOKEN);
44
- }
45
17
  //# sourceMappingURL=runtimeIdentity.context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeIdentity.context.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.context.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;GAGG;AACH,MAAM,uBAAuB,GAAG,WAAW,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,mCAAmC;IAEjD,OAAO;QAEL,gBAAgB,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE;QAC1C,eAAe,EAAE,CAAC,GAAW,EAAqB,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC;QAC5E,gBAAgB;QAChB,GAAG,EAAE,GAAW,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;KACrC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,kBAAkB,CAAC,GAAW;IAErC,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAE3D,gKAAgK;IAChK,sDAAsD;IACtD,IAAG,KAAK,KAAK,SAAS,EAAE,CAAC;QAEvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IAE7C,yIAAyI;IACzI,IAAG,WAAW,KAAK,EAAE,EAAE,CAAC;QAEtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"runtimeIdentity.context.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.context.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,mCAAmC;IAEjD,OAAO;QAEL,aAAa,EAAE,CAAC,GAAW,EAAoB,EAAE,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,WAAW,IAAI,IAAI;QACzH,gBAAgB,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE;QAC1C,gBAAgB;QAChB,GAAG,EAAE,GAAW,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;KACrC,CAAC;AACJ,CAAC"}
@@ -4,13 +4,14 @@ import type { Nullable } from "../types/index.ts";
4
4
  */
5
5
  export interface IdentityRecord {
6
6
  readonly bootId: string;
7
+ readonly commandHash: Nullable<string>;
7
8
  readonly pid: number;
8
9
  readonly startedAt: string;
9
10
  readonly version: string;
10
11
  }
11
12
  /**
12
- * Discriminated union representing the on-disk state at a given path. Every branch is exhaustive at compile time, so callers must handle each variant
13
- * explicitly and the type system catches any new state added in the future.
13
+ * Discriminated union representing the on-disk state at a given path. Each variant carries only the data its state has. claim() and release() test for
14
+ * held-live alone, so unless they are extended, claim() overwrites a new variant and release() leaves its file in place.
14
15
  */
15
16
  export type IdentityState = {
16
17
  kind: "free";
@@ -42,8 +43,8 @@ export type ClaimResult = {
42
43
  * literal to drive each state-machine branch deterministically.
43
44
  */
44
45
  export interface RuntimeIdentityContext {
46
+ readonly commandLineOf: (pid: number) => Nullable<string>;
45
47
  readonly getBootSessionId: () => string;
46
- readonly isPidOurProcess: (pid: number) => Nullable<boolean>;
47
48
  readonly isProcessRunning: (pid: number) => boolean;
48
49
  readonly now: () => number;
49
50
  }
@@ -82,16 +83,26 @@ export declare function release(filePath: string, ctx?: RuntimeIdentityContext):
82
83
  * @param filePath - The absolute path to the identity file.
83
84
  */
84
85
  export declare function forceRelease(filePath: string): void;
86
+ /**
87
+ * Fingerprints a command line as the identity record stores it: the lowercase hex sha256 digest of the trimmed text. It is the one normalization of a command
88
+ * line, applied at the claim and at inspect alike, which is why it lives here rather than in the context: the platforms report surrounding whitespace
89
+ * differently, and trimming the claim's reading and inspect's reading alike keeps a holder's command line matching its own record.
90
+ * @param commandLine - The command line as the process table reported it, or null when the table had no row for the process.
91
+ * @returns The fingerprint, or null when there is no command line to fingerprint.
92
+ */
93
+ export declare function fingerprintCommandLine(commandLine: Nullable<string>): Nullable<string>;
85
94
  /**
86
95
  * Serializes a record to its on-disk representation. The first line is the bare PID for backwards compatibility with shell tooling; subsequent lines are
87
- * key=value pairs in deterministic order. The trailing newline keeps the file well-formed for POSIX text-file tools.
96
+ * key=value pairs in deterministic order, the commandHash line written only when the record carries a fingerprint. The trailing newline keeps the file
97
+ * well-formed for POSIX text-file tools.
88
98
  * @param record - The identity record to serialize.
89
99
  * @returns The serialized payload.
90
100
  */
91
101
  export declare function serializeRecord(record: IdentityRecord): string;
92
102
  /**
93
- * Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record (missing or non-integer
94
- * pid, missing bootId). Unknown key=value pairs are silently ignored so future fields can be added without breaking older readers.
103
+ * Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record: a first line that is not a
104
+ * positive integer PID, or a boot session that is missing or empty. A commandHash that is not a well-formed fingerprint reads as absent rather than refusing the
105
+ * record, and unknown key=value pairs are silently ignored so future fields can be added without breaking older readers.
95
106
  * @param raw - The raw file contents.
96
107
  * @returns The parsed record, or null when the payload is unusable.
97
108
  */
@@ -1,5 +1,6 @@
1
1
  import { clearPidFile } from "./pid.js";
2
2
  import { createDefaultRuntimeIdentityContext } from "./runtimeIdentity.context.js";
3
+ import { createHash } from "node:crypto";
3
4
  import fs from "node:fs";
4
5
  /**
5
6
  * Inspects the identity file at the given path and reports the current state. Reads the file, parses the record, and combines boot session match with PID
@@ -18,8 +19,11 @@ export function inspect(filePath, ctx = createDefaultRuntimeIdentityContext()) {
18
19
  if (error.code === "ENOENT") {
19
20
  return { kind: "free" };
20
21
  }
21
- // Any other read error (EACCES, EIO, ...) is reported as malformed-with-empty-raw so callers fall through to the overwrite path rather than crashing on
22
- // transient I/O.
22
+ // Any other read error (EACCES, EIO, ...) is reported as malformed-with-empty-raw, so claim() takes the overwrite path rather than crashing. Like a record
23
+ // that fails to parse, this downgrade is made without proof that the holder is gone, a deliberate exception to the header's rule that unconfirmed identity
24
+ // keeps held-live: an unreadable file holds no record to confirm, so keeping held-live would refuse every startup until the file was repaired by hand. The
25
+ // overwrite either throws, when the temp write or the rename is refused, or replaces the file, and if a holder is still running behind it, this startup
26
+ // meets the port bind the concurrency note describes.
23
27
  return { kind: "stale-malformed", raw: "" };
24
28
  }
25
29
  const record = parseRecord(raw);
@@ -32,12 +36,14 @@ export function inspect(filePath, ctx = createDefaultRuntimeIdentityContext()) {
32
36
  if (!ctx.isProcessRunning(record.pid)) {
33
37
  return { kind: "stale-dead-pid", record };
34
38
  }
35
- // The PID is alive and the boot session matches, but within a single boot the kernel can reassign a freed PID to an unrelated process after PrismCast was
36
- // SIGKILLed. We confirm process identity through the processInspector port: a verdict of false means the process table positively identified a non-PrismCast
37
- // command line at this PID, so the original writer is gone and the slot is stale. A verdict of true (confirmed PrismCast) or null (cannot determine) both
38
- // keep the held-live verdict - we only downgrade on positive proof of a different process. We classify the recycled case as stale-dead-pid rather than a
39
- // new branch because the operational meaning is identical - the writing process is gone - and callers already overwrite that state.
40
- if (ctx.isPidOurProcess(record.pid) === false) {
39
+ // The PID is alive and the boot session matches, but within a single boot the kernel can reassign a freed PID to another program after PrismCast was
40
+ // SIGKILLed. The record carries the fingerprint of its writer's command line, so a live process at that PID whose command line fingerprints differently is
41
+ // another program, the writer is gone, and the slot is stale. We classify that case as stale-dead-pid rather than a new branch because the operational meaning
42
+ // is identical and callers already overwrite that state. Only that positive proof downgrades the slot: a record with no fingerprint reads no process table, and
43
+ // a PID whose command line the table cannot report keeps the held-live verdict, because downgrading a possibly-live holder is the only path to two concurrent
44
+ // instances.
45
+ const liveHash = (record.commandHash === null) ? null : fingerprintCommandLine(ctx.commandLineOf(record.pid));
46
+ if ((liveHash !== null) && (liveHash !== record.commandHash)) {
41
47
  return { kind: "stale-dead-pid", record };
42
48
  }
43
49
  return { kind: "held-live", record };
@@ -58,6 +64,7 @@ export function claim(filePath, metadata, ctx = createDefaultRuntimeIdentityCont
58
64
  }
59
65
  const record = {
60
66
  bootId: ctx.getBootSessionId(),
67
+ commandHash: fingerprintCommandLine(ctx.commandLineOf(process.pid)),
61
68
  pid: process.pid,
62
69
  startedAt: new Date(ctx.now()).toISOString(),
63
70
  version: metadata.version
@@ -89,21 +96,38 @@ export function release(filePath, ctx = createDefaultRuntimeIdentityContext()) {
89
96
  export function forceRelease(filePath) {
90
97
  clearPidFile(filePath, "identity");
91
98
  }
99
+ /**
100
+ * Fingerprints a command line as the identity record stores it: the lowercase hex sha256 digest of the trimmed text. It is the one normalization of a command
101
+ * line, applied at the claim and at inspect alike, which is why it lives here rather than in the context: the platforms report surrounding whitespace
102
+ * differently, and trimming the claim's reading and inspect's reading alike keeps a holder's command line matching its own record.
103
+ * @param commandLine - The command line as the process table reported it, or null when the table had no row for the process.
104
+ * @returns The fingerprint, or null when there is no command line to fingerprint.
105
+ */
106
+ export function fingerprintCommandLine(commandLine) {
107
+ const text = commandLine?.trim() ?? "";
108
+ if (text === "") {
109
+ return null;
110
+ }
111
+ return createHash("sha256").update(text).digest("hex");
112
+ }
92
113
  /**
93
114
  * Serializes a record to its on-disk representation. The first line is the bare PID for backwards compatibility with shell tooling; subsequent lines are
94
- * key=value pairs in deterministic order. The trailing newline keeps the file well-formed for POSIX text-file tools.
115
+ * key=value pairs in deterministic order, the commandHash line written only when the record carries a fingerprint. The trailing newline keeps the file
116
+ * well-formed for POSIX text-file tools.
95
117
  * @param record - The identity record to serialize.
96
118
  * @returns The serialized payload.
97
119
  */
98
120
  export function serializeRecord(record) {
99
121
  return String(record.pid) + "\n" +
100
122
  "bootId=" + record.bootId + "\n" +
123
+ ((record.commandHash === null) ? "" : "commandHash=" + record.commandHash + "\n") +
101
124
  "startedAt=" + record.startedAt + "\n" +
102
125
  "version=" + record.version + "\n";
103
126
  }
104
127
  /**
105
- * Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record (missing or non-integer
106
- * pid, missing bootId). Unknown key=value pairs are silently ignored so future fields can be added without breaking older readers.
128
+ * Parses the on-disk representation of an identity record. Returns null when the payload cannot be interpreted as a complete record: a first line that is not a
129
+ * positive integer PID, or a boot session that is missing or empty. A commandHash that is not a well-formed fingerprint reads as absent rather than refusing the
130
+ * record, and unknown key=value pairs are silently ignored so future fields can be added without breaking older readers.
107
131
  * @param raw - The raw file contents.
108
132
  * @returns The parsed record, or null when the payload is unusable.
109
133
  */
@@ -118,11 +142,15 @@ export function parseRecord(raw) {
118
142
  if (firstLine === undefined) {
119
143
  return null;
120
144
  }
121
- const pid = parseInt(firstLine.trim(), 10);
122
- if (Number.isNaN(pid)) {
145
+ // The PID is a required field, so a first line that is not all digits, or whose value is zero, names no process and the record is malformed. Reading the line
146
+ // whole, rather than by its leading digits, keeps a corrupt line from naming whatever PID its digits happen to spell.
147
+ const pidText = firstLine.trim();
148
+ const pid = Number(pidText);
149
+ if (!/^\d+$/.test(pidText) || (pid <= 0)) {
123
150
  return null;
124
151
  }
125
152
  let bootId = null;
153
+ let commandHash = null;
126
154
  let startedAt = "";
127
155
  let version = "";
128
156
  for (let i = 1; i < lines.length; i++) {
@@ -145,6 +173,11 @@ export function parseRecord(raw) {
145
173
  bootId = value;
146
174
  break;
147
175
  }
176
+ // Only a sha256 digest in lowercase hex is a fingerprint fingerprintCommandLine could have written, so any other value reads as no fingerprint at all.
177
+ case "commandHash": {
178
+ commandHash = /^[0-9a-f]{64}$/.test(value) ? value : null;
179
+ break;
180
+ }
148
181
  case "startedAt": {
149
182
  startedAt = value;
150
183
  break;
@@ -158,12 +191,12 @@ export function parseRecord(raw) {
158
191
  }
159
192
  }
160
193
  }
161
- // bootId is the only required metadata field. A file without one was written by a pre-runtimeIdentity PrismCast (or by an external tool) and is treated as
162
- // malformed for state-machine purposes.
163
- if (bootId === null) {
194
+ // The boot session is the other required field. A file without one, or with an empty one, gives the state machine nothing to compare against the current
195
+ // boot, whether an external tool or a PrismCast that predates the identity record wrote it or it is corrupt, so it is treated as malformed.
196
+ if ((bootId === null) || (bootId === "")) {
164
197
  return null;
165
198
  }
166
- return { bootId, pid, startedAt, version };
199
+ return { bootId, commandHash, pid, startedAt, version };
167
200
  }
168
201
  /**
169
202
  * Persists a record to disk via atomic write (write-temp + rename). On POSIX rename is atomic within a filesystem; on Windows the rename is best-effort but
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeIdentity.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtimeIdentity.js","sourceRoot":"","sources":["../../src/utils/runtimeIdentity.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "prismcast",
3
3
  "displayName": "PrismCast",
4
- "version": "1.13.0",
4
+ "version": "1.14.0",
5
5
  "description": "Browser-based live TV capture server for Channels DVR, Plex, and other streaming clients.",
6
6
  "author": {
7
7
  "name": "HJD",
@@ -79,20 +79,20 @@
79
79
  "morgan": "1.12.1",
80
80
  "puppeteer-core": "24.43.1",
81
81
  "puppeteer-stream": "3.0.23",
82
- "ws": "8.21.3"
82
+ "ws": "8.22.0"
83
83
  },
84
84
  "devDependencies": {
85
85
  "@stylistic/eslint-plugin": "5.10.0",
86
86
  "@types/compression": "1.8.1",
87
87
  "@types/express": "5.0.6",
88
88
  "@types/morgan": "1.9.10",
89
- "@types/node": "26.6.3",
90
- "@types/ws": "8.18.1",
89
+ "@types/node": "26.6.4",
90
+ "@types/ws": "8.18.2",
91
91
  "eslint": "9.39.2",
92
92
  "happy-dom": "20.14.5",
93
93
  "nodemon": "3.1.14",
94
94
  "typescript": "5.9.3",
95
- "typescript-eslint": "8.70.1"
95
+ "typescript-eslint": "8.71.1"
96
96
  },
97
97
  "allowScripts": {
98
98
  "ffmpeg-for-homebridge": true
@@ -1 +0,0 @@
1
- {"version":3,"file":"deviceId.js","sourceRoot":"","sources":["../../src/hdhr/deviceId.ts"],"names":[],"mappings":"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"}