@raidiant/notifai 11.7.1 → 12.0.0-beta.11

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 (409) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/NOTICE +16 -0
  3. package/THIRD_PARTY_NOTICES +725 -0
  4. package/bin/notifai.mjs +11420 -0
  5. package/data/install.ps1 +318 -0
  6. package/data/release.json +1 -0
  7. package/inventory.json +1 -0
  8. package/npm-adapter-files.json +52 -0
  9. package/package.json +14 -44
  10. package/README.md +0 -168
  11. package/dist/agent-update-notice.d.ts +0 -7
  12. package/dist/agent-update-notice.js +0 -77
  13. package/dist/agent-update-notice.js.map +0 -1
  14. package/dist/atomic-file.d.ts +0 -30
  15. package/dist/atomic-file.js +0 -148
  16. package/dist/atomic-file.js.map +0 -1
  17. package/dist/attendant-update.d.ts +0 -15
  18. package/dist/attendant-update.js +0 -96
  19. package/dist/attendant-update.js.map +0 -1
  20. package/dist/claude-wake.d.ts +0 -108
  21. package/dist/claude-wake.js +0 -369
  22. package/dist/claude-wake.js.map +0 -1
  23. package/dist/cli-bin.d.ts +0 -26
  24. package/dist/cli-bin.js +0 -220
  25. package/dist/cli-bin.js.map +0 -1
  26. package/dist/cli-contract.d.ts +0 -16
  27. package/dist/cli-contract.js +0 -27
  28. package/dist/cli-contract.js.map +0 -1
  29. package/dist/cli-release.d.ts +0 -36
  30. package/dist/cli-release.js +0 -85
  31. package/dist/cli-release.js.map +0 -1
  32. package/dist/client.d.ts +0 -109
  33. package/dist/client.js +0 -217
  34. package/dist/client.js.map +0 -1
  35. package/dist/codex-answer-control.d.ts +0 -14
  36. package/dist/codex-answer-control.js +0 -41
  37. package/dist/codex-answer-control.js.map +0 -1
  38. package/dist/codex-answer-presentation.d.ts +0 -18
  39. package/dist/codex-answer-presentation.js +0 -113
  40. package/dist/codex-answer-presentation.js.map +0 -1
  41. package/dist/codex-input-lifecycle.d.ts +0 -10
  42. package/dist/codex-input-lifecycle.js +0 -63
  43. package/dist/codex-input-lifecycle.js.map +0 -1
  44. package/dist/codex-native-control.d.ts +0 -13
  45. package/dist/codex-native-control.js +0 -120
  46. package/dist/codex-native-control.js.map +0 -1
  47. package/dist/codex-native-turn.d.ts +0 -37
  48. package/dist/codex-native-turn.js +0 -155
  49. package/dist/codex-native-turn.js.map +0 -1
  50. package/dist/codex-question-bindings.d.ts +0 -76
  51. package/dist/codex-question-bindings.js +0 -151
  52. package/dist/codex-question-bindings.js.map +0 -1
  53. package/dist/codex-queue-control.d.ts +0 -21
  54. package/dist/codex-queue-control.js +0 -59
  55. package/dist/codex-queue-control.js.map +0 -1
  56. package/dist/codex-tool-messages.d.ts +0 -7
  57. package/dist/codex-tool-messages.js +0 -126
  58. package/dist/codex-tool-messages.js.map +0 -1
  59. package/dist/codex-wake.d.ts +0 -58
  60. package/dist/codex-wake.js +0 -135
  61. package/dist/codex-wake.js.map +0 -1
  62. package/dist/command-session.d.ts +0 -14
  63. package/dist/command-session.js +0 -31
  64. package/dist/command-session.js.map +0 -1
  65. package/dist/commands-acknowledge.d.ts +0 -13
  66. package/dist/commands-acknowledge.js +0 -116
  67. package/dist/commands-acknowledge.js.map +0 -1
  68. package/dist/commands-agent-sessions.d.ts +0 -6
  69. package/dist/commands-agent-sessions.js +0 -51
  70. package/dist/commands-agent-sessions.js.map +0 -1
  71. package/dist/commands-ask.d.ts +0 -62
  72. package/dist/commands-ask.js +0 -503
  73. package/dist/commands-ask.js.map +0 -1
  74. package/dist/commands-auth.d.ts +0 -76
  75. package/dist/commands-auth.js +0 -421
  76. package/dist/commands-auth.js.map +0 -1
  77. package/dist/commands-close.d.ts +0 -6
  78. package/dist/commands-close.js +0 -273
  79. package/dist/commands-close.js.map +0 -1
  80. package/dist/commands-config.d.ts +0 -31
  81. package/dist/commands-config.js +0 -272
  82. package/dist/commands-config.js.map +0 -1
  83. package/dist/commands-core.d.ts +0 -145
  84. package/dist/commands-core.js +0 -190
  85. package/dist/commands-core.js.map +0 -1
  86. package/dist/commands-devices.d.ts +0 -41
  87. package/dist/commands-devices.js +0 -144
  88. package/dist/commands-devices.js.map +0 -1
  89. package/dist/commands-doctor.d.ts +0 -25
  90. package/dist/commands-doctor.js +0 -1553
  91. package/dist/commands-doctor.js.map +0 -1
  92. package/dist/commands-guidance.d.ts +0 -27
  93. package/dist/commands-guidance.js +0 -150
  94. package/dist/commands-guidance.js.map +0 -1
  95. package/dist/commands-harness-context.d.ts +0 -57
  96. package/dist/commands-harness-context.js +0 -102
  97. package/dist/commands-harness-context.js.map +0 -1
  98. package/dist/commands-hook-attend.d.ts +0 -70
  99. package/dist/commands-hook-attend.js +0 -655
  100. package/dist/commands-hook-attend.js.map +0 -1
  101. package/dist/commands-hook-diagnostics.d.ts +0 -37
  102. package/dist/commands-hook-diagnostics.js +0 -136
  103. package/dist/commands-hook-diagnostics.js.map +0 -1
  104. package/dist/commands-hook-install.d.ts +0 -26
  105. package/dist/commands-hook-install.js +0 -784
  106. package/dist/commands-hook-install.js.map +0 -1
  107. package/dist/commands-hook-run.d.ts +0 -29
  108. package/dist/commands-hook-run.js +0 -933
  109. package/dist/commands-hook-run.js.map +0 -1
  110. package/dist/commands-hook-shape.d.ts +0 -19
  111. package/dist/commands-hook-shape.js +0 -48
  112. package/dist/commands-hook-shape.js.map +0 -1
  113. package/dist/commands-init.d.ts +0 -42
  114. package/dist/commands-init.js +0 -901
  115. package/dist/commands-init.js.map +0 -1
  116. package/dist/commands-io.d.ts +0 -2
  117. package/dist/commands-io.js +0 -117
  118. package/dist/commands-io.js.map +0 -1
  119. package/dist/commands-logs.d.ts +0 -30
  120. package/dist/commands-logs.js +0 -201
  121. package/dist/commands-logs.js.map +0 -1
  122. package/dist/commands-native-acknowledge.d.ts +0 -8
  123. package/dist/commands-native-acknowledge.js +0 -114
  124. package/dist/commands-native-acknowledge.js.map +0 -1
  125. package/dist/commands-project.d.ts +0 -4
  126. package/dist/commands-project.js +0 -41
  127. package/dist/commands-project.js.map +0 -1
  128. package/dist/commands-receive.d.ts +0 -3
  129. package/dist/commands-receive.js +0 -59
  130. package/dist/commands-receive.js.map +0 -1
  131. package/dist/commands-send-support.d.ts +0 -59
  132. package/dist/commands-send-support.js +0 -258
  133. package/dist/commands-send-support.js.map +0 -1
  134. package/dist/commands-send.d.ts +0 -34
  135. package/dist/commands-send.js +0 -900
  136. package/dist/commands-send.js.map +0 -1
  137. package/dist/commands-setup-proof.d.ts +0 -43
  138. package/dist/commands-setup-proof.js +0 -134
  139. package/dist/commands-setup-proof.js.map +0 -1
  140. package/dist/commands-skill.d.ts +0 -21
  141. package/dist/commands-skill.js +0 -199
  142. package/dist/commands-skill.js.map +0 -1
  143. package/dist/commands-sounds.d.ts +0 -12
  144. package/dist/commands-sounds.js +0 -35
  145. package/dist/commands-sounds.js.map +0 -1
  146. package/dist/commands-update-check.d.ts +0 -6
  147. package/dist/commands-update-check.js +0 -102
  148. package/dist/commands-update-check.js.map +0 -1
  149. package/dist/commands-update-resume.d.ts +0 -7
  150. package/dist/commands-update-resume.js +0 -143
  151. package/dist/commands-update-resume.js.map +0 -1
  152. package/dist/commands-update-skill.d.ts +0 -5
  153. package/dist/commands-update-skill.js +0 -36
  154. package/dist/commands-update-skill.js.map +0 -1
  155. package/dist/commands-update.d.ts +0 -11
  156. package/dist/commands-update.js +0 -286
  157. package/dist/commands-update.js.map +0 -1
  158. package/dist/commands.d.ts +0 -26
  159. package/dist/commands.js +0 -27
  160. package/dist/commands.js.map +0 -1
  161. package/dist/config-schema.d.ts +0 -62
  162. package/dist/config-schema.js +0 -302
  163. package/dist/config-schema.js.map +0 -1
  164. package/dist/config.d.ts +0 -181
  165. package/dist/config.js +0 -357
  166. package/dist/config.js.map +0 -1
  167. package/dist/credentials.d.ts +0 -96
  168. package/dist/credentials.js +0 -342
  169. package/dist/credentials.js.map +0 -1
  170. package/dist/file-lock.d.ts +0 -34
  171. package/dist/file-lock.js +0 -367
  172. package/dist/file-lock.js.map +0 -1
  173. package/dist/generated-session-label.d.ts +0 -2
  174. package/dist/generated-session-label.js +0 -152
  175. package/dist/generated-session-label.js.map +0 -1
  176. package/dist/guidance-content.d.ts +0 -53
  177. package/dist/guidance-content.js +0 -248
  178. package/dist/guidance-content.js.map +0 -1
  179. package/dist/guidance-render.d.ts +0 -25
  180. package/dist/guidance-render.js +0 -47
  181. package/dist/guidance-render.js.map +0 -1
  182. package/dist/guidance.d.ts +0 -69
  183. package/dist/guidance.js +0 -173
  184. package/dist/guidance.js.map +0 -1
  185. package/dist/harness-session-title.d.ts +0 -22
  186. package/dist/harness-session-title.js +0 -74
  187. package/dist/harness-session-title.js.map +0 -1
  188. package/dist/harnesses.d.ts +0 -65
  189. package/dist/harnesses.js +0 -159
  190. package/dist/harnesses.js.map +0 -1
  191. package/dist/hermes-attendant.d.ts +0 -38
  192. package/dist/hermes-attendant.js +0 -337
  193. package/dist/hermes-attendant.js.map +0 -1
  194. package/dist/hermes-plugin.d.ts +0 -11
  195. package/dist/hermes-plugin.js +0 -299
  196. package/dist/hermes-plugin.js.map +0 -1
  197. package/dist/hook-acknowledgements.d.ts +0 -70
  198. package/dist/hook-acknowledgements.js +0 -490
  199. package/dist/hook-acknowledgements.js.map +0 -1
  200. package/dist/hook-adapter.d.ts +0 -48
  201. package/dist/hook-adapter.js +0 -419
  202. package/dist/hook-adapter.js.map +0 -1
  203. package/dist/hook-events.d.ts +0 -105
  204. package/dist/hook-events.js +0 -130
  205. package/dist/hook-events.js.map +0 -1
  206. package/dist/hook-gates.d.ts +0 -7
  207. package/dist/hook-gates.js +0 -20
  208. package/dist/hook-gates.js.map +0 -1
  209. package/dist/hook-input.d.ts +0 -10
  210. package/dist/hook-input.js +0 -64
  211. package/dist/hook-input.js.map +0 -1
  212. package/dist/hook-lifecycle.d.ts +0 -112
  213. package/dist/hook-lifecycle.js +0 -2031
  214. package/dist/hook-lifecycle.js.map +0 -1
  215. package/dist/hook-project-sessions.d.ts +0 -28
  216. package/dist/hook-project-sessions.js +0 -141
  217. package/dist/hook-project-sessions.js.map +0 -1
  218. package/dist/hook-question-lock.d.ts +0 -29
  219. package/dist/hook-question-lock.js +0 -217
  220. package/dist/hook-question-lock.js.map +0 -1
  221. package/dist/hook-question-retirement.d.ts +0 -74
  222. package/dist/hook-question-retirement.js +0 -314
  223. package/dist/hook-question-retirement.js.map +0 -1
  224. package/dist/hook-question-state.d.ts +0 -58
  225. package/dist/hook-question-state.js +0 -239
  226. package/dist/hook-question-state.js.map +0 -1
  227. package/dist/hook-session-state.d.ts +0 -127
  228. package/dist/hook-session-state.js +0 -488
  229. package/dist/hook-session-state.js.map +0 -1
  230. package/dist/hook-types.d.ts +0 -476
  231. package/dist/hook-types.js +0 -4
  232. package/dist/hook-types.js.map +0 -1
  233. package/dist/injection-render.d.ts +0 -36
  234. package/dist/injection-render.js +0 -61
  235. package/dist/injection-render.js.map +0 -1
  236. package/dist/install-hooks.d.ts +0 -470
  237. package/dist/install-hooks.js +0 -1622
  238. package/dist/install-hooks.js.map +0 -1
  239. package/dist/integration-health.d.ts +0 -26
  240. package/dist/integration-health.js +0 -133
  241. package/dist/integration-health.js.map +0 -1
  242. package/dist/interactive.d.ts +0 -22
  243. package/dist/interactive.js +0 -644
  244. package/dist/interactive.js.map +0 -1
  245. package/dist/invocation-context.d.ts +0 -47
  246. package/dist/invocation-context.js +0 -164
  247. package/dist/invocation-context.js.map +0 -1
  248. package/dist/local-path.d.ts +0 -7
  249. package/dist/local-path.js +0 -27
  250. package/dist/local-path.js.map +0 -1
  251. package/dist/logging.d.ts +0 -157
  252. package/dist/logging.js +0 -599
  253. package/dist/logging.js.map +0 -1
  254. package/dist/main-run.d.ts +0 -1
  255. package/dist/main-run.js +0 -42
  256. package/dist/main-run.js.map +0 -1
  257. package/dist/main.d.ts +0 -2
  258. package/dist/main.js +0 -12
  259. package/dist/main.js.map +0 -1
  260. package/dist/native-answer-operation.d.ts +0 -70
  261. package/dist/native-answer-operation.js +0 -247
  262. package/dist/native-answer-operation.js.map +0 -1
  263. package/dist/native-skills.d.ts +0 -64
  264. package/dist/native-skills.js +0 -167
  265. package/dist/native-skills.js.map +0 -1
  266. package/dist/node-floor.d.ts +0 -19
  267. package/dist/node-floor.js +0 -32
  268. package/dist/node-floor.js.map +0 -1
  269. package/dist/npm-invocation.d.ts +0 -34
  270. package/dist/npm-invocation.js +0 -53
  271. package/dist/npm-invocation.js.map +0 -1
  272. package/dist/openclaw-continuation-bridge.d.ts +0 -7
  273. package/dist/openclaw-continuation-bridge.js +0 -64
  274. package/dist/openclaw-continuation-bridge.js.map +0 -1
  275. package/dist/openclaw-gateway-readiness.d.ts +0 -1
  276. package/dist/openclaw-gateway-readiness.js +0 -24
  277. package/dist/openclaw-gateway-readiness.js.map +0 -1
  278. package/dist/openclaw-generation.d.ts +0 -21
  279. package/dist/openclaw-generation.js +0 -115
  280. package/dist/openclaw-generation.js.map +0 -1
  281. package/dist/openclaw-message-bridge.d.ts +0 -8
  282. package/dist/openclaw-message-bridge.js +0 -93
  283. package/dist/openclaw-message-bridge.js.map +0 -1
  284. package/dist/openclaw-pending.d.ts +0 -8
  285. package/dist/openclaw-pending.js +0 -47
  286. package/dist/openclaw-pending.js.map +0 -1
  287. package/dist/openclaw-plugin.d.ts +0 -75
  288. package/dist/openclaw-plugin.js +0 -1353
  289. package/dist/openclaw-plugin.js.map +0 -1
  290. package/dist/openclaw-session-access.d.ts +0 -12
  291. package/dist/openclaw-session-access.js +0 -79
  292. package/dist/openclaw-session-access.js.map +0 -1
  293. package/dist/opencode-plugin.d.ts +0 -88
  294. package/dist/opencode-plugin.js +0 -286
  295. package/dist/opencode-plugin.js.map +0 -1
  296. package/dist/orca-session-title.d.ts +0 -11
  297. package/dist/orca-session-title.js +0 -111
  298. package/dist/orca-session-title.js.map +0 -1
  299. package/dist/pack-feedback-slice.d.ts +0 -35
  300. package/dist/pack-feedback-slice.js +0 -126
  301. package/dist/pack-feedback-slice.js.map +0 -1
  302. package/dist/pairing-qr.d.ts +0 -5
  303. package/dist/pairing-qr.js +0 -24
  304. package/dist/pairing-qr.js.map +0 -1
  305. package/dist/pending-pairing.d.ts +0 -38
  306. package/dist/pending-pairing.js +0 -70
  307. package/dist/pending-pairing.js.map +0 -1
  308. package/dist/platform.d.ts +0 -67
  309. package/dist/platform.js +0 -140
  310. package/dist/platform.js.map +0 -1
  311. package/dist/process-identity.d.ts +0 -26
  312. package/dist/process-identity.js +0 -82
  313. package/dist/process-identity.js.map +0 -1
  314. package/dist/program.d.ts +0 -59
  315. package/dist/program.js +0 -691
  316. package/dist/program.js.map +0 -1
  317. package/dist/project-enablement.d.ts +0 -21
  318. package/dist/project-enablement.js +0 -71
  319. package/dist/project-enablement.js.map +0 -1
  320. package/dist/question-settlement-process.d.ts +0 -17
  321. package/dist/question-settlement-process.js +0 -35
  322. package/dist/question-settlement-process.js.map +0 -1
  323. package/dist/question-timing.d.ts +0 -46
  324. package/dist/question-timing.js +0 -48
  325. package/dist/question-timing.js.map +0 -1
  326. package/dist/readiness.d.ts +0 -153
  327. package/dist/readiness.js +0 -149
  328. package/dist/readiness.js.map +0 -1
  329. package/dist/release.d.ts +0 -31
  330. package/dist/release.js +0 -52
  331. package/dist/release.js.map +0 -1
  332. package/dist/send-attempts.d.ts +0 -26
  333. package/dist/send-attempts.js +0 -139
  334. package/dist/send-attempts.js.map +0 -1
  335. package/dist/send.d.ts +0 -115
  336. package/dist/send.js +0 -421
  337. package/dist/send.js.map +0 -1
  338. package/dist/session-activation.d.ts +0 -13
  339. package/dist/session-activation.js +0 -64
  340. package/dist/session-activation.js.map +0 -1
  341. package/dist/session-attendant-probe.d.ts +0 -85
  342. package/dist/session-attendant-probe.js +0 -173
  343. package/dist/session-attendant-probe.js.map +0 -1
  344. package/dist/session-attendant-state.d.ts +0 -70
  345. package/dist/session-attendant-state.js +0 -256
  346. package/dist/session-attendant-state.js.map +0 -1
  347. package/dist/session-attendant.d.ts +0 -143
  348. package/dist/session-attendant.js +0 -520
  349. package/dist/session-attendant.js.map +0 -1
  350. package/dist/session-delivery.d.ts +0 -249
  351. package/dist/session-delivery.js +0 -576
  352. package/dist/session-delivery.js.map +0 -1
  353. package/dist/session-handoff.d.ts +0 -98
  354. package/dist/session-handoff.js +0 -118
  355. package/dist/session-handoff.js.map +0 -1
  356. package/dist/session-input-wakes.d.ts +0 -78
  357. package/dist/session-input-wakes.js +0 -239
  358. package/dist/session-input-wakes.js.map +0 -1
  359. package/dist/session-inputs.d.ts +0 -57
  360. package/dist/session-inputs.js +0 -434
  361. package/dist/session-inputs.js.map +0 -1
  362. package/dist/session-labels.d.ts +0 -56
  363. package/dist/session-labels.js +0 -396
  364. package/dist/session-labels.js.map +0 -1
  365. package/dist/session-message-handoff.d.ts +0 -39
  366. package/dist/session-message-handoff.js +0 -107
  367. package/dist/session-message-handoff.js.map +0 -1
  368. package/dist/setup-destinations.d.ts +0 -23
  369. package/dist/setup-destinations.js +0 -44
  370. package/dist/setup-destinations.js.map +0 -1
  371. package/dist/skill-integrity.d.ts +0 -54
  372. package/dist/skill-integrity.js +0 -164
  373. package/dist/skill-integrity.js.map +0 -1
  374. package/dist/skill-source/manifest.json +0 -40
  375. package/dist/skill-source/notifai/SKILL.md +0 -350
  376. package/dist/skill-source/notifai/references/diagnostics.md +0 -36
  377. package/dist/skill-source/notifai/references/harness-setup.md +0 -384
  378. package/dist/skill-source/notifai/references/native-questions.md +0 -51
  379. package/dist/skill-source/notifai/references/notes-and-edits.md +0 -54
  380. package/dist/skill-source/notifai/references/send-details.md +0 -14
  381. package/dist/skill-source/notifai/references/updates.md +0 -116
  382. package/dist/skill-source/notifai/references/writing-examples.md +0 -56
  383. package/dist/sound-ref.d.ts +0 -23
  384. package/dist/sound-ref.js +0 -28
  385. package/dist/sound-ref.js.map +0 -1
  386. package/dist/ui/banner.d.ts +0 -22
  387. package/dist/ui/banner.js +0 -87
  388. package/dist/ui/banner.js.map +0 -1
  389. package/dist/ui/config-view.d.ts +0 -30
  390. package/dist/ui/config-view.js +0 -108
  391. package/dist/ui/config-view.js.map +0 -1
  392. package/dist/ui/help.d.ts +0 -44
  393. package/dist/ui/help.js +0 -107
  394. package/dist/ui/help.js.map +0 -1
  395. package/dist/ui/theme.d.ts +0 -90
  396. package/dist/ui/theme.js +0 -244
  397. package/dist/ui/theme.js.map +0 -1
  398. package/dist/update-handoff.d.ts +0 -29
  399. package/dist/update-handoff.js +0 -69
  400. package/dist/update-handoff.js.map +0 -1
  401. package/dist/url-policy.d.ts +0 -85
  402. package/dist/url-policy.js +0 -369
  403. package/dist/url-policy.js.map +0 -1
  404. package/dist/version.d.ts +0 -40
  405. package/dist/version.js +0 -132
  406. package/dist/version.js.map +0 -1
  407. package/dist/wake-support.d.ts +0 -40
  408. package/dist/wake-support.js +0 -95
  409. package/dist/wake-support.js.map +0 -1
@@ -0,0 +1,318 @@
1
+ #requires -Version 5.1
2
+ <# First execution trusts the HTTPS release channel. Hash checks detect changed
3
+ downloads; the installed verifier authenticates subsequent updates. This
4
+ script never changes execution policy or requires an installed Node runtime. #>
5
+ [CmdletBinding()]
6
+ param(
7
+ [string]$Version,
8
+ [ValidateSet('stable', 'beta')][string]$Channel,
9
+ [switch]$Json,
10
+ [switch]$NoInit,
11
+ [switch]$NoPath,
12
+ [switch]$MigrateNpm
13
+ )
14
+ Set-StrictMode -Version Latest
15
+ $ErrorActionPreference = 'Stop'
16
+
17
+ function Test-NotifaiVersion([string]$Value) {
18
+ return $Value.Length -le 100 -and $Value -cmatch '^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$'
19
+ }
20
+ function Get-NotifaiHash([string]$File) {
21
+ $stream = [IO.File]::OpenRead($File)
22
+ $sha = [Security.Cryptography.SHA256]::Create()
23
+ try { return ([BitConverter]::ToString($sha.ComputeHash($stream))).Replace('-', '').ToLowerInvariant() }
24
+ finally { $sha.Dispose(); $stream.Dispose() }
25
+ }
26
+ function Get-NotifaiDownload([string]$Url, [string]$Destination, [long]$Limit) {
27
+ $uri = [Uri]$Url
28
+ for ($redirect = 0; $redirect -le 5; $redirect++) {
29
+ if ($uri.Scheme -cne 'https' -or -not $uri.IsDefaultPort -or $uri.UserInfo -or
30
+ $uri.Host -notin @('github.com', 'raw.githubusercontent.com', 'release-assets.githubusercontent.com')) {
31
+ throw 'Release download left its trusted HTTPS origins'
32
+ }
33
+ $request = [Net.HttpWebRequest]::Create($uri)
34
+ $request.AllowAutoRedirect = $false
35
+ $request.Timeout = 30000
36
+ $request.ReadWriteTimeout = 30000
37
+ $request.UserAgent = 'notifai-installer'
38
+ $response = $request.GetResponse()
39
+ try {
40
+ $status = [int]$response.StatusCode
41
+ if ($status -in @(301, 302, 303, 307, 308)) {
42
+ if ($redirect -eq 5 -or -not $response.Headers['Location']) { throw 'Release download has too many redirects' }
43
+ $uri = [Uri]::new($uri, $response.Headers['Location'])
44
+ continue
45
+ }
46
+ if ($status -ne 200 -or $response.ContentLength -gt $Limit) { throw 'Release download was unavailable or too large' }
47
+ $inputStream = $response.GetResponseStream()
48
+ $outputStream = [IO.File]::Open($Destination, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None)
49
+ try {
50
+ $buffer = New-Object byte[] 65536
51
+ [long]$total = 0
52
+ while (($count = $inputStream.Read($buffer, 0, $buffer.Length)) -gt 0) {
53
+ $total += $count
54
+ if ($total -gt $Limit) { throw 'Release download exceeded its size limit' }
55
+ $outputStream.Write($buffer, 0, $count)
56
+ }
57
+ $outputStream.Flush($true)
58
+ } finally { $outputStream.Dispose(); $inputStream.Dispose() }
59
+ return
60
+ } finally { $response.Dispose() }
61
+ }
62
+ }
63
+ function Read-NotifaiChannel([string]$File, [string]$SelectedChannel) {
64
+ $lines = [IO.File]::ReadAllLines($File)
65
+ if ($lines.Length -lt 1 -or $lines.Length -gt 1001) { throw 'Invalid channel metadata' }
66
+ $header = $lines[0].Split([char]9)
67
+ if ($header.Length -ne 5 -or $header[0] -cne 'notifai-channel-v1' -or $header[1] -cne $SelectedChannel -or
68
+ $header[2] -cnotmatch '^[1-9][0-9]{0,15}$' -or -not (Test-NotifaiVersion $header[3]) -or $header[4] -cnotmatch '^[a-f0-9]{64}$') {
69
+ throw 'Invalid channel metadata'
70
+ }
71
+ $withdrawn = @()
72
+ for ($i = 1; $i -lt $lines.Length; $i++) {
73
+ $fields = $lines[$i].Split([char]9)
74
+ if ($fields.Length -ne 2 -or $fields[0] -cne 'withdrawn' -or -not (Test-NotifaiVersion $fields[1])) { throw 'Invalid channel withdrawal' }
75
+ $withdrawn += $fields[1]
76
+ }
77
+ if ($header[3] -cin $withdrawn -or ($SelectedChannel -eq 'stable' -and $header[3].Split('+')[0].Contains('-'))) { throw 'Channel recommends an ineligible release' }
78
+ return @{ Version = $header[3]; InventoryHash = $header[4]; Withdrawn = $withdrawn }
79
+ }
80
+ function Read-NotifaiArtifact([string]$File, [string]$SelectedVersion, [string]$Target) {
81
+ $lines = [IO.File]::ReadAllLines($File)
82
+ if ($lines.Length -lt 2 -or $lines.Length -gt 7) { throw 'Invalid release metadata' }
83
+ $header = $lines[0].Split([char]9)
84
+ if ($header.Length -ne 3 -or $header[0] -cne 'notifai-bootstrap-v1' -or $header[1] -cne $SelectedVersion -or $header[2] -cnotmatch '^[a-f0-9]{64}$') {
85
+ throw 'Release metadata identity differs'
86
+ }
87
+ $found = $null
88
+ $seen = @{}
89
+ for ($i = 1; $i -lt $lines.Length; $i++) {
90
+ $fields = $lines[$i].Split([char]9)
91
+ if ($fields.Length -ne 7 -or $fields[0] -cne 'artifact' -or
92
+ $fields[1] -cnotmatch '^bun-(darwin|linux|windows)-(arm64|x64)$' -or $seen.ContainsKey($fields[1]) -or
93
+ $fields[3] -cnotmatch '^[1-9][0-9]{0,8}$' -or [long]$fields[3] -gt 268435456 -or
94
+ $fields[4] -cnotmatch '^[a-f0-9]{64}$' -or $fields[5] -cnotmatch '^[a-f0-9]{64}$' -or $fields[6] -cnotmatch '^[a-f0-9]{64}$') {
95
+ throw 'Invalid release artifact metadata'
96
+ }
97
+ $suffix = if ($fields[1].StartsWith('bun-windows-')) { 'zip' } else { 'tar.gz' }
98
+ if ($fields[2] -cne "notifai-$SelectedVersion-$($fields[1].Substring(4)).$suffix") { throw 'Invalid release artifact filename' }
99
+ $seen[$fields[1]] = $true
100
+ if ($fields[1] -ceq $Target) {
101
+ $found = @{ Filename = $fields[2]; Bytes = [long]$fields[3]; Hash = $fields[4]; LauncherHash = $fields[5]; RuntimeHash = $fields[6]; InventoryHash = $header[2] }
102
+ }
103
+ }
104
+ if ($null -eq $found) { throw 'This release does not support the native Windows architecture' }
105
+ return $found
106
+ }
107
+ function Expand-NotifaiArchive([string]$Archive, [string]$Destination) {
108
+ Add-Type -AssemblyName System.IO.Compression, System.IO.Compression.FileSystem
109
+ $zip = [IO.Compression.ZipFile]::OpenRead($Archive)
110
+ try {
111
+ if ($zip.Entries.Count -lt 2 -or $zip.Entries.Count -gt 130) { throw 'Invalid release archive entry count' }
112
+ $seen = @{}
113
+ [long]$expanded = 0
114
+ foreach ($entry in $zip.Entries) {
115
+ $name = $entry.FullName
116
+ if ($name.Length -gt 240 -or $name.Split('/').Length -gt 8) { throw 'Invalid release archive path' }
117
+ foreach ($part in $name.Split('/')) {
118
+ if ($part -cnotmatch '^[A-Za-z0-9_-][A-Za-z0-9._-]*$' -or $part.EndsWith('.') -or $part -imatch '^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\.|$)') { throw 'Unsafe release archive path' }
119
+ }
120
+ $type = ($entry.ExternalAttributes -shr 16) -band 61440
121
+ if ($type -notin @(0, 32768) -or $seen.ContainsKey($name) -or $entry.Length -gt 536870912) { throw 'Unsafe release archive member' }
122
+ foreach ($prior in $seen.Keys) {
123
+ if ($name.StartsWith("$prior/", [StringComparison]::OrdinalIgnoreCase) -or $prior.StartsWith("$name/", [StringComparison]::OrdinalIgnoreCase)) { throw 'Conflicting release archive paths' }
124
+ }
125
+ $seen[$name] = $true
126
+ $expanded += $entry.Length
127
+ if ($expanded -gt 805306368) { throw 'Expanded release archive exceeds its size limit' }
128
+ }
129
+ if (-not $seen.ContainsKey('notifai.exe') -or -not $seen.ContainsKey('notifai-runtime.exe')) { throw 'Release executables are missing' }
130
+ [void][IO.Directory]::CreateDirectory($Destination)
131
+ foreach ($entry in $zip.Entries) {
132
+ $file = [IO.Path]::Combine($Destination, $entry.FullName.Replace('/', [IO.Path]::DirectorySeparatorChar))
133
+ [void][IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($file))
134
+ $inputStream = $entry.Open()
135
+ $outputStream = [IO.File]::Open($file, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None)
136
+ try {
137
+ $buffer = New-Object byte[] 65536
138
+ [long]$total = 0
139
+ while (($count = $inputStream.Read($buffer, 0, $buffer.Length)) -gt 0) {
140
+ $total += $count
141
+ if ($total -gt $entry.Length) { throw 'Release archive member exceeded its declared size' }
142
+ $outputStream.Write($buffer, 0, $count)
143
+ }
144
+ if ($total -ne $entry.Length) { throw 'Release archive member is truncated' }
145
+ $outputStream.Flush($true)
146
+ } finally { $outputStream.Dispose(); $inputStream.Dispose() }
147
+ }
148
+ } finally { $zip.Dispose() }
149
+ }
150
+ function Get-NotifaiWindowsTarget {
151
+ if (-not ('NotifaiBootstrap.Native' -as [type])) {
152
+ Add-Type -TypeDefinition @'
153
+ using System;
154
+ using System.Runtime.InteropServices;
155
+ namespace NotifaiBootstrap {
156
+ public static class Native {
157
+ [DllImport("kernel32.dll", SetLastError=true)]
158
+ [return: MarshalAs(UnmanagedType.Bool)]
159
+ public static extern bool IsWow64Process2(IntPtr process, out ushort processMachine, out ushort nativeMachine);
160
+ }
161
+ }
162
+ '@
163
+ }
164
+ [UInt16]$processMachine = 0
165
+ [UInt16]$nativeMachine = 0
166
+ if (-not [NotifaiBootstrap.Native]::IsWow64Process2([IntPtr](-1), [ref]$processMachine, [ref]$nativeMachine)) { throw 'Cannot establish native Windows architecture' }
167
+ switch ($nativeMachine) {
168
+ 34404 { return 'bun-windows-x64' }
169
+ 43620 { return 'bun-windows-arm64' }
170
+ default { throw 'This native Windows architecture is not supported' }
171
+ }
172
+ }
173
+ function Get-NotifaiAccessControl([string]$File, [IO.FileAttributes]$Attributes) {
174
+ $info = if (($Attributes -band [IO.FileAttributes]::Directory) -ne 0) { [IO.DirectoryInfo]::new($File) } else { [IO.FileInfo]::new($File) }
175
+ # Keep this bootstrap lookup independent of filesystem/security cmdlet
176
+ # module discovery. Windows PowerShell and PowerShell use different .NET APIs.
177
+ if ($PSVersionTable.PSEdition -eq 'Desktop') { return $info.GetAccessControl() }
178
+ return [IO.FileSystemAclExtensions]::GetAccessControl($info)
179
+ }
180
+ function New-NotifaiPrivateDirectory([string]$Directory) {
181
+ if ([IO.Directory]::Exists($Directory) -or [IO.File]::Exists($Directory)) { throw 'Installer temporary directory already exists' }
182
+ $user = [Security.Principal.WindowsIdentity]::GetCurrent().User
183
+ $security = New-Object Security.AccessControl.DirectorySecurity
184
+ $security.SetOwner($user)
185
+ $security.SetAccessRuleProtection($true, $false)
186
+ foreach ($sid in @($user, [Security.Principal.SecurityIdentifier]::new('S-1-5-18'), [Security.Principal.SecurityIdentifier]::new('S-1-5-32-544'))) {
187
+ $rule = [Security.AccessControl.FileSystemAccessRule]::new($sid, [Security.AccessControl.FileSystemRights]::FullControl,
188
+ [Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit', [Security.AccessControl.PropagationFlags]::None,
189
+ [Security.AccessControl.AccessControlType]::Allow)
190
+ [void]$security.AddAccessRule($rule)
191
+ }
192
+ $overload = [IO.Directory].GetMethods() | Where-Object { $_.Name -eq 'CreateDirectory' -and $_.GetParameters().Length -eq 2 -and $_.GetParameters()[1].ParameterType -eq [Security.AccessControl.DirectorySecurity] }
193
+ if ($overload) { [void][IO.Directory]::CreateDirectory($Directory, $security) }
194
+ else { [IO.FileSystemAclExtensions]::Create([IO.DirectoryInfo]::new($Directory), $security) }
195
+ $attributes = [IO.File]::GetAttributes($Directory)
196
+ $actual = Get-NotifaiAccessControl $Directory $attributes
197
+ if (($attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0 -or -not $actual.AreAccessRulesProtected -or
198
+ $actual.GetOwner([Security.Principal.SecurityIdentifier]).Value -ne $user.Value) { throw 'Installer temporary directory is not privately owned' }
199
+ foreach ($rule in $actual.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
200
+ if ($rule.AccessControlType -eq [Security.AccessControl.AccessControlType]::Allow -and $rule.IdentityReference.Value -notin @($user.Value, 'S-1-5-18', 'S-1-5-32-544')) { throw 'Installer temporary directory permits another account' }
201
+ }
202
+ }
203
+ function Invoke-NotifaiCandidate([string]$Launcher, [string[]]$NativeArgs) {
204
+ & $Launcher @NativeArgs
205
+ $script:NotifaiBootstrapExitCode = $LASTEXITCODE
206
+ }
207
+ function Get-NotifaiAccountHome {
208
+ $accountHome = [Environment]::GetFolderPath([Environment+SpecialFolder]::UserProfile)
209
+ if (-not $accountHome -or -not [IO.Path]::IsPathRooted($accountHome)) { throw 'Cannot resolve this account home' }
210
+ foreach ($value in @($env:USERPROFILE, $env:HOME)) {
211
+ # Git Bash's POSIX HOME is not a Windows account relocation.
212
+ if ($value -and $value -match '^(?:[A-Za-z]:[\\/]|\\\\)') {
213
+ if (-not [String]::Equals([IO.Path]::GetFullPath($value).TrimEnd('\', '/'), $accountHome.TrimEnd('\', '/'), [StringComparison]::OrdinalIgnoreCase)) { throw 'HOME or USERPROFILE differs from the OS account home' }
214
+ }
215
+ }
216
+ return $accountHome
217
+ }
218
+ # Read-only inspection of an existing path. npm can inherit a token's default
219
+ # owner. The OS-confirmed profile can belong to Windows itself; this exception
220
+ # must never admit a system-owned npm package or managed installation path.
221
+ function Assert-NotifaiPathAccess([string]$File, [switch]$AllowDefaultOwner, [switch]$RequireProtected, [switch]$AccountHome) {
222
+ $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
223
+ $user = $identity.User.Value
224
+ $attributes = [IO.File]::GetAttributes($File)
225
+ $acl = Get-NotifaiAccessControl $File $attributes
226
+ $owner = $acl.GetOwner([Security.Principal.SecurityIdentifier]).Value
227
+ $defaultOwner = $AllowDefaultOwner -and $identity.Owner.Value -eq 'S-1-5-32-544' -and $owner -eq $identity.Owner.Value
228
+ $profileOwner = $false
229
+ if ($AccountHome) {
230
+ $expectedHome = Get-NotifaiAccountHome
231
+ if (-not [String]::Equals([IO.Path]::GetFullPath($File).TrimEnd('\', '/'), $expectedHome.TrimEnd('\', '/'), [StringComparison]::OrdinalIgnoreCase) -or
232
+ ($attributes -band [IO.FileAttributes]::Directory) -eq 0) { throw 'Account home access check requires the exact OS profile directory' }
233
+ $profileOwner = $owner -in @('S-1-5-18', 'S-1-5-32-544')
234
+ }
235
+ if (($attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0 -or
236
+ ($owner -ne $user -and -not $defaultOwner -and -not $profileOwner) -or
237
+ ($RequireProtected -and -not $acl.AreAccessRulesProtected)) { throw 'Existing path is not privately owned; inspect it before repair' }
238
+ $writes = [int64][Security.AccessControl.FileSystemRights]'Write, Delete, DeleteSubdirectoriesAndFiles, ChangePermissions, TakeOwnership' -bor 0x50000000
239
+ foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
240
+ if ($rule.AccessControlType -eq [Security.AccessControl.AccessControlType]::Allow -and
241
+ ([int64]$rule.FileSystemRights -band $writes) -ne 0 -and
242
+ $rule.IdentityReference.Value -notin @($user, 'S-1-5-18', 'S-1-5-32-544')) { throw 'Existing path permits another writer; inspect it before repair' }
243
+ }
244
+ }
245
+ function Get-NotifaiInstalledCommand {
246
+ $accountHome = Get-NotifaiAccountHome
247
+ $managed = [IO.Path]::Combine($accountHome, '.notifai')
248
+ $bin = [IO.Path]::Combine($managed, 'bin')
249
+ $command = [IO.Path]::Combine($bin, 'notifai.exe')
250
+ try { [void][IO.File]::GetAttributes($command) }
251
+ catch [IO.FileNotFoundException] { return $null }
252
+ catch [IO.DirectoryNotFoundException] { return $null }
253
+ foreach ($file in @($accountHome, $managed, $bin, $command)) {
254
+ Assert-NotifaiPathAccess $file -AccountHome:($file -eq $accountHome) -RequireProtected:($file -eq $managed -or $file -eq $bin)
255
+ }
256
+ if (-not [IO.File]::Exists($command)) { throw 'Existing launcher is not a regular file; repair it explicitly' }
257
+ return $command
258
+ }
259
+ function Get-NotifaiInstallArguments {
260
+ $nativeArgs = @('install', '--source', 'powershell')
261
+ if ($Channel) { $nativeArgs += @('--channel', $Channel) }
262
+ if ($Version) { $nativeArgs += @('--version', $Version) }
263
+ if ($Json) { $nativeArgs += '--json' }
264
+ if ($NoInit) { $nativeArgs += '--no-init' }
265
+ if ($NoPath) { $nativeArgs += '--no-path' }
266
+ if ($MigrateNpm) { $nativeArgs += '--migrate-npm' }
267
+ return $nativeArgs
268
+ }
269
+ function Invoke-NotifaiBootstrap {
270
+ $selectedChannel = if ($Channel) { $Channel } else { 'stable' }
271
+ if ($Version -and -not (Test-NotifaiVersion $Version)) { throw 'Version must be an exact semantic version' }
272
+ $existing = Get-NotifaiInstalledCommand
273
+ if ($existing) {
274
+ Invoke-NotifaiCandidate $existing (Get-NotifaiInstallArguments)
275
+ return
276
+ }
277
+ if ($selectedChannel -eq 'stable' -and $Version -and $Version.Split('+')[0].Contains('-')) { throw 'A prerelease requires -Channel beta' }
278
+ $target = Get-NotifaiWindowsTarget
279
+ $temporary = [IO.Path]::Combine([IO.Path]::GetTempPath(), "notifai-install-$([Guid]::NewGuid().ToString('N'))")
280
+ New-NotifaiPrivateDirectory $temporary
281
+ try {
282
+ $channelFile = [IO.Path]::Combine($temporary, 'channel.tsv')
283
+ Get-NotifaiDownload "https://raw.githubusercontent.com/Raidiant-io/notifai/release-metadata/$selectedChannel.bootstrap.tsv" $channelFile 262144
284
+ $release = Read-NotifaiChannel $channelFile $selectedChannel
285
+ $selectedVersion = if ($Version) { $Version } else { $release.Version }
286
+ if ($selectedVersion -cin $release.Withdrawn) { throw 'The requested release has been withdrawn' }
287
+ $base = "https://github.com/Raidiant-io/notifai/releases/download/v$selectedVersion"
288
+ $artifactFile = [IO.Path]::Combine($temporary, 'bootstrap.tsv')
289
+ Get-NotifaiDownload "$base/bootstrap.tsv" $artifactFile 262144
290
+ $artifact = Read-NotifaiArtifact $artifactFile $selectedVersion $target
291
+ if ($selectedVersion -ceq $release.Version -and $artifact.InventoryHash -cne $release.InventoryHash) { throw 'Channel and release inventory differ' }
292
+ $inventory = [IO.Path]::Combine($temporary, 'inventory.json')
293
+ Get-NotifaiDownload "$base/inventory.json" $inventory 262144
294
+ if ((Get-NotifaiHash $inventory) -cne $artifact.InventoryHash) { throw 'Release inventory digest differs' }
295
+ $archive = [IO.Path]::Combine($temporary, $artifact.Filename)
296
+ Get-NotifaiDownload "$base/$($artifact.Filename)" $archive $artifact.Bytes
297
+ if ((Get-Item -LiteralPath $archive).Length -ne $artifact.Bytes -or (Get-NotifaiHash $archive) -cne $artifact.Hash) { throw 'Release archive digest or size differs' }
298
+ $extracted = [IO.Path]::Combine($temporary, 'release')
299
+ Expand-NotifaiArchive $archive $extracted
300
+ $launcher = [IO.Path]::Combine($extracted, 'notifai.exe')
301
+ if ((Get-NotifaiHash $launcher) -cne $artifact.LauncherHash -or (Get-NotifaiHash ([IO.Path]::Combine($extracted, 'notifai-runtime.exe'))) -cne $artifact.RuntimeHash) { throw 'Release executable digests differ' }
302
+ $nativeArgs = @(Get-NotifaiInstallArguments) + @('--directory', $extracted, '--inventory', $inventory)
303
+ Invoke-NotifaiCandidate $launcher $nativeArgs
304
+ } finally {
305
+ if ([IO.Directory]::Exists($temporary)) {
306
+ try { [IO.Directory]::Delete($temporary, $true) }
307
+ catch { [Console]::Error.WriteLine("Temporary installer files remain at $temporary; remove them after running commands finish.") }
308
+ }
309
+ }
310
+ }
311
+ if ($MyInvocation.InvocationName -ne '.') {
312
+ try { Invoke-NotifaiBootstrap; exit $script:NotifaiBootstrapExitCode }
313
+ catch {
314
+ if ($Json) { @{ ok = $false; code = 'bootstrap_failed'; message = $_.Exception.Message } | ConvertTo-Json -Compress }
315
+ else { [Console]::Error.WriteLine("Notifai installation failed: $($_.Exception.Message)") }
316
+ exit 1
317
+ }
318
+ }
@@ -0,0 +1 @@
1
+ {"version":"12.0.0-beta.11","source_revision":"29b033b35eb72cf2c4235a604d865b70bb9c516a"}
package/inventory.json ADDED
@@ -0,0 +1 @@
1
+ {"key_id":"notifai-release-2026-10","payload":"eyJzY2hlbWEiOjEsInZlcnNpb24iOiIxMi4wLjAtYmV0YS4xMSIsInNvdXJjZV9yZXZpc2lvbiI6IjI5YjAzM2IzNWViNzJjZjJjNDIzNWE2MDRkODY1YjcwYmI5YzUxNmEiLCJzdG9yZV9zY2hlbWEiOjEsImxhdW5jaGVyX3NjaGVtYSI6MSwiYXJ0aWZhY3RzIjpbeyJ0YXJnZXQiOiJidW4tZGFyd2luLWFybTY0IiwiZmlsZW5hbWUiOiJub3RpZmFpLTEyLjAuMC1iZXRhLjExLWRhcndpbi1hcm02NC50YXIuZ3oiLCJieXRlcyI6Mjc3NjkwMzgsInNoYTI1NiI6IjFiZWQ1MmRlOGQ4NzhmNmE2OWU4ZmNmYTNjZTFmYjZlZDE4ZGEwNTg3YjZjODFmNDFlYTcyM2Q0MmRkOWVhMDQiLCJydW50aW1lX3NoYTI1NiI6IjdmNDYwYjlkYmUzMDUzYWJlODdkZWJmODZiMTFkZjVlMzZjMmZhYjI3ZmVkMTI5NWM4MTg1NjkyNjM2YmQxMmQiLCJsYXVuY2hlcl9zaGEyNTYiOiI3ZWYxNDdiNmUxZTIxMDIzY2QwN2ZhNmQ3Y2Y5NzJlOWFhZDljNjFmMmMzZTZjNGM0NzFkZGJkMmJlYWRkZTNkIiwibWF0ZXJpYWxzIjpbeyJwYXRoIjoiQlVOLUxJQ0VOU0UubWQiLCJieXRlcyI6NTYxMywic2hhMjU2IjoiYjljYWY1MjcyODY5MWI0MDU3ZTM3MTIzMmMyMjFhMTMyODgzMTk4YmUyZjNkMmRkZjkyYzkwNDA0Yzk4NGIxYSJ9LHsicGF0aCI6IkNPUlJFU1BPTkRJTkctU09VUkNFUy5qc29uIiwiYnl0ZXMiOjIwMjAsInNoYTI1NiI6ImZhNGMzNDQ4MDExNTQ4NzJkNjE3OWVlMmVmNDk5MjNkYzlmODkwOWVmMDFlNTNiODZlOGY1N2M2MjU4MjMyNzQifSx7InBhdGgiOiJMSUNFTlNFLnR4dCIsImJ5dGVzIjoxMTM0Niwic2hhMjU2IjoiOTQ0YzEzZmYwZmU3OTVlMjkxZmQxYzQ5NDczZjk4ZDRmZGYxZjc0NjM4ZTAxZjg4Mjc2OWNkNGNhZTc4YjczZCJ9LHsicGF0aCI6Ik5PVElDRS1QUk9WRU5BTkNFLmpzb24iLCJieXRlcyI6NDUwMjY0LCJzaGEyNTYiOiI1MzRkZDU5ZmQ0YzE1ZGQxMzgyZTgyN2YwYjg1YzE5ZjdjNjk4ZTIzNWY5Mjk5ZWFhMjAyZGI1NDAwODM0Mjg4In0seyJwYXRoIjoiTk9USUNFLnR4dCIsImJ5dGVzIjo2MjYsInNoYTI1NiI6IjFkZmJmNDQ5OGRjMDI2YjIwNTljMGIwYjVlYjVmYTFkODJhZTMzNGU1OGZmMTFlN2MyOTczMzMyN2YyNWM0ZWIifSx7InBhdGgiOiJSRUJVSUxESU5HLm1kIiwiYnl0ZXMiOjM4NDIsInNoYTI1NiI6ImNlNjA1YjVmZGIwMzE5MzM5ZjlmODNmMmZlN2NjY2JjN2U1NzI2ZmRmNDk0ZGE2ZTI4NDMzYmVmODI5ZWIwYmUifSx7InBhdGgiOiJTT1VSQ0UtTk9USUNFUy50eHQiLCJieXRlcyI6OTAxNzc3MSwic2hhMjU2IjoiODk5NzZiZWNjMjU2NTQwZTZkMmU4MDdiNDdhNGUwNWU4ODk5ODJjMDYyMmZjMDQ0MTNhN2JmN2U3N2E3N2UzNyJ9LHsicGF0aCI6IlRISVJELVBBUlRZLU5PVElDRVMudHh0IiwiYnl0ZXMiOjI0OTE0OTYsInNoYTI1NiI6IjExNjQ0N2VmZjc3ODkzNTExNzk3ZWY0NzYwMTFkZWM4MDAyMjRmOTFlMzM0MmUzZDY1NzA3MDg3MTJiNGI3NzIifSx7InBhdGgiOiJsaWNlbnNlcy9ucG0tY21kLXNoaW0udHh0IiwiYnl0ZXMiOjgxMywic2hhMjU2IjoiYWZmZmRmMTIwODExMjI3NDljNGI3MWM1YjFjMTFiYzY1OWQ3OTI0MmQxOWUxOGY1ZThkYmFiMDRhNDVlMzZiYiJ9LHsicGF0aCI6Im5wbS1hZGFwdGVyLWZpbGVzLmpzb24iLCJieXRlcyI6MTUyNCwic2hhMjU2IjoiZmYxMzFiMDMxNTkyOGNhY2FkNjY5MzcxNTQ2MTk4MzcwNWRkOWI3YTY0NDU1YzQ3M2NjN2YxZmY5ZjVmNmFlOSJ9XX0seyJ0YXJnZXQiOiJidW4tZGFyd2luLXg2NCIsImZpbGVuYW1lIjoibm90aWZhaS0xMi4wLjAtYmV0YS4xMS1kYXJ3aW4teDY0LnRhci5neiIsImJ5dGVzIjozMDAwNzMzNywic2hhMjU2IjoiMzI3MjEzMjdlNmQ5Y2NjNjZiMmMyMmI4MGQwZjgyMzEyOTMzMjM2NDgzNDRiOTZjYjcwNDlkMmJmYmIwY2FlYiIsInJ1bnRpbWVfc2hhMjU2IjoiMTFlODgwNTA3YzVmMjc0NjM1YzdkMzdlN2UzZDhkMDg5ZjE5Mjc3MDE2YzdlMzlkNjU4OWE2OGZjZWM1ZTA4MiIsImxhdW5jaGVyX3NoYTI1NiI6ImJiNDM3YTQ2NmFiMWM2YTRiZjU0Nzk0MDg3NmZhMTMwMTZlNmYwZTlhNjljODU3NzM0YjllNmViNWExZjNiYmYiLCJtYXRlcmlhbHMiOlt7InBhdGgiOiJCVU4tTElDRU5TRS5tZCIsImJ5dGVzIjo1NjEzLCJzaGEyNTYiOiJiOWNhZjUyNzI4NjkxYjQwNTdlMzcxMjMyYzIyMWExMzI4ODMxOThiZTJmM2QyZGRmOTJjOTA0MDRjOTg0YjFhIn0seyJwYXRoIjoiQ09SUkVTUE9ORElORy1TT1VSQ0VTLmpzb24iLCJieXRlcyI6MjAyMCwic2hhMjU2IjoiZmE0YzM0NDgwMTE1NDg3MmQ2MTc5ZWUyZWY0OTkyM2RjOWY4OTA5ZWYwMWU1M2I4NmU4ZjU3YzYyNTgyMzI3NCJ9LHsicGF0aCI6IkxJQ0VOU0UudHh0IiwiYnl0ZXMiOjExMzQ2LCJzaGEyNTYiOiI5NDRjMTNmZjBmZTc5NWUyOTFmZDFjNDk0NzNmOThkNGZkZjFmNzQ2MzhlMDFmODgyNzY5Y2Q0Y2FlNzhiNzNkIn0seyJwYXRoIjoiTk9USUNFLVBST1ZFTkFOQ0UuanNvbiIsImJ5dGVzIjo0NTAyNjQsInNoYTI1NiI6IjUzNGRkNTlmZDRjMTVkZDEzODJlODI3ZjBiODVjMTlmN2M2OThlMjM1ZjkyOTllYWEyMDJkYjU0MDA4MzQyODgifSx7InBhdGgiOiJOT1RJQ0UudHh0IiwiYnl0ZXMiOjYyNiwic2hhMjU2IjoiMWRmYmY0NDk4ZGMwMjZiMjA1OWMwYjBiNWViNWZhMWQ4MmFlMzM0ZTU4ZmYxMWU3YzI5NzMzMzI3ZjI1YzRlYiJ9LHsicGF0aCI6IlJFQlVJTERJTkcubWQiLCJieXRlcyI6Mzg0Miwic2hhMjU2IjoiY2U2MDViNWZkYjAzMTkzMzlmOWY4M2YyZmU3Y2NjYmM3ZTU3MjZmZGY0OTRkYTZlMjg0MzNiZWY4MjllYjBiZSJ9LHsicGF0aCI6IlNPVVJDRS1OT1RJQ0VTLnR4dCIsImJ5dGVzIjo5MDE3NzcxLCJzaGEyNTYiOiI4OTk3NmJlY2MyNTY1NDBlNmQyZTgwN2I0N2E0ZTA1ZTg4OTk4MmMwNjIyZmMwNDQxM2E3YmY3ZTc3YTc3ZTM3In0seyJwYXRoIjoiVEhJUkQtUEFSVFktTk9USUNFUy50eHQiLCJieXRlcyI6MjQ5MTQ5Niwic2hhMjU2IjoiMTE2NDQ3ZWZmNzc4OTM1MTE3OTdlZjQ3NjAxMWRlYzgwMDIyNGY5MWUzMzQyZTNkNjU3MDcwODcxMmI0Yjc3MiJ9LHsicGF0aCI6ImxpY2Vuc2VzL25wbS1jbWQtc2hpbS50eHQiLCJieXRlcyI6ODEzLCJzaGEyNTYiOiJhZmZmZGYxMjA4MTEyMjc0OWM0YjcxYzViMWMxMWJjNjU5ZDc5MjQyZDE5ZTE4ZjVlOGRiYWIwNGE0NWUzNmJiIn0seyJwYXRoIjoibnBtLWFkYXB0ZXItZmlsZXMuanNvbiIsImJ5dGVzIjoxNTI0LCJzaGEyNTYiOiJmZjEzMWIwMzE1OTI4Y2FjYWQ2NjkzNzE1NDYxOTgzNzA1ZGQ5YjdhNjQ0NTVjNDczY2M3ZjFmZjlmNWY2YWU5In1dfSx7InRhcmdldCI6ImJ1bi1saW51eC1hcm02NCIsImZpbGVuYW1lIjoibm90aWZhaS0xMi4wLjAtYmV0YS4xMS1saW51eC1hcm02NC50YXIuZ3oiLCJieXRlcyI6MzkzMTY2NjgsInNoYTI1NiI6IjE4ODhjZWNmNzMwMDZlMTgwMGU2NWZmODJiZTA3NGQ5ZjE5NzRkMzdiNmYwNjQwNWUyY2RmMDkzZmUzOGUzYzAiLCJydW50aW1lX3NoYTI1NiI6IjBkY2E2YmQxMmM5YmRmNzBlMzNiMzI3N2JkYTA4NjdiMDQ3OTcwZjlmN2ZkMWMwODRjYTczZDAyODJkMTBiNDgiLCJsYXVuY2hlcl9zaGEyNTYiOiJjMTllMzMyYzgyMWI3MTI4Y2IyNWY2MWU0YWI3ZTBiM2M2MzM0NWYwNGUyYWI1YWI5NWQ0NTFhNGE2ZmJkYzQ1IiwibWF0ZXJpYWxzIjpbeyJwYXRoIjoiQlVOLUxJQ0VOU0UubWQiLCJieXRlcyI6NTYxMywic2hhMjU2IjoiYjljYWY1MjcyODY5MWI0MDU3ZTM3MTIzMmMyMjFhMTMyODgzMTk4YmUyZjNkMmRkZjkyYzkwNDA0Yzk4NGIxYSJ9LHsicGF0aCI6IkNPUlJFU1BPTkRJTkctU09VUkNFUy5qc29uIiwiYnl0ZXMiOjIwMjAsInNoYTI1NiI6ImZhNGMzNDQ4MDExNTQ4NzJkNjE3OWVlMmVmNDk5MjNkYzlmODkwOWVmMDFlNTNiODZlOGY1N2M2MjU4MjMyNzQifSx7InBhdGgiOiJMSUNFTlNFLnR4dCIsImJ5dGVzIjoxMTM0Niwic2hhMjU2IjoiOTQ0YzEzZmYwZmU3OTVlMjkxZmQxYzQ5NDczZjk4ZDRmZGYxZjc0NjM4ZTAxZjg4Mjc2OWNkNGNhZTc4YjczZCJ9LHsicGF0aCI6Ik5PVElDRS1QUk9WRU5BTkNFLmpzb24iLCJieXRlcyI6NDUwMjY0LCJzaGEyNTYiOiI1MzRkZDU5ZmQ0YzE1ZGQxMzgyZTgyN2YwYjg1YzE5ZjdjNjk4ZTIzNWY5Mjk5ZWFhMjAyZGI1NDAwODM0Mjg4In0seyJwYXRoIjoiTk9USUNFLnR4dCIsImJ5dGVzIjo2MjYsInNoYTI1NiI6IjFkZmJmNDQ5OGRjMDI2YjIwNTljMGIwYjVlYjVmYTFkODJhZTMzNGU1OGZmMTFlN2MyOTczMzMyN2YyNWM0ZWIifSx7InBhdGgiOiJSRUJVSUxESU5HLm1kIiwiYnl0ZXMiOjM4NDIsInNoYTI1NiI6ImNlNjA1YjVmZGIwMzE5MzM5ZjlmODNmMmZlN2NjY2JjN2U1NzI2ZmRmNDk0ZGE2ZTI4NDMzYmVmODI5ZWIwYmUifSx7InBhdGgiOiJTT1VSQ0UtTk9USUNFUy50eHQiLCJieXRlcyI6OTAxNzc3MSwic2hhMjU2IjoiODk5NzZiZWNjMjU2NTQwZTZkMmU4MDdiNDdhNGUwNWU4ODk5ODJjMDYyMmZjMDQ0MTNhN2JmN2U3N2E3N2UzNyJ9LHsicGF0aCI6IlRISVJELVBBUlRZLU5PVElDRVMudHh0IiwiYnl0ZXMiOjI0OTE0OTYsInNoYTI1NiI6IjExNjQ0N2VmZjc3ODkzNTExNzk3ZWY0NzYwMTFkZWM4MDAyMjRmOTFlMzM0MmUzZDY1NzA3MDg3MTJiNGI3NzIifSx7InBhdGgiOiJsaWNlbnNlcy9ucG0tY21kLXNoaW0udHh0IiwiYnl0ZXMiOjgxMywic2hhMjU2IjoiYWZmZmRmMTIwODExMjI3NDljNGI3MWM1YjFjMTFiYzY1OWQ3OTI0MmQxOWUxOGY1ZThkYmFiMDRhNDVlMzZiYiJ9LHsicGF0aCI6Im5wbS1hZGFwdGVyLWZpbGVzLmpzb24iLCJieXRlcyI6MTUyNCwic2hhMjU2IjoiZmYxMzFiMDMxNTkyOGNhY2FkNjY5MzcxNTQ2MTk4MzcwNWRkOWI3YTY0NDU1YzQ3M2NjN2YxZmY5ZjVmNmFlOSJ9XX0seyJ0YXJnZXQiOiJidW4tbGludXgteDY0IiwiZmlsZW5hbWUiOiJub3RpZmFpLTEyLjAuMC1iZXRhLjExLWxpbnV4LXg2NC50YXIuZ3oiLCJieXRlcyI6Mzg4Nzk2MDcsInNoYTI1NiI6IjU3M2Y2M2ZjNDBjNzU2NzM4YTkwMzYzY2I3ZDQ3ZDQ4Y2E1N2RjZTlmYWYxYjc2MGM0Y2M4ZWRmZTY3ZDY3NzkiLCJydW50aW1lX3NoYTI1NiI6IjYwMDJlYWI0ZTMwM2JkMGYwZGE2OWY3MWIzYTNjYmM5ODNhYjA4M2FlMmZmNDcyMmIwMjE0ZTAzZGJmZWE0ZDUiLCJsYXVuY2hlcl9zaGEyNTYiOiJiZGY4ZDQ3ZGY4NTgxYWNlMjliNTc5MDQ1N2NiYzZjMjZkMTJiM2NiMTRjMGRkYWIzMzc5YTcyNzVkOWVhNGIxIiwibWF0ZXJpYWxzIjpbeyJwYXRoIjoiQlVOLUxJQ0VOU0UubWQiLCJieXRlcyI6NTYxMywic2hhMjU2IjoiYjljYWY1MjcyODY5MWI0MDU3ZTM3MTIzMmMyMjFhMTMyODgzMTk4YmUyZjNkMmRkZjkyYzkwNDA0Yzk4NGIxYSJ9LHsicGF0aCI6IkNPUlJFU1BPTkRJTkctU09VUkNFUy5qc29uIiwiYnl0ZXMiOjIwMjAsInNoYTI1NiI6ImZhNGMzNDQ4MDExNTQ4NzJkNjE3OWVlMmVmNDk5MjNkYzlmODkwOWVmMDFlNTNiODZlOGY1N2M2MjU4MjMyNzQifSx7InBhdGgiOiJMSUNFTlNFLnR4dCIsImJ5dGVzIjoxMTM0Niwic2hhMjU2IjoiOTQ0YzEzZmYwZmU3OTVlMjkxZmQxYzQ5NDczZjk4ZDRmZGYxZjc0NjM4ZTAxZjg4Mjc2OWNkNGNhZTc4YjczZCJ9LHsicGF0aCI6Ik5PVElDRS1QUk9WRU5BTkNFLmpzb24iLCJieXRlcyI6NDUwMjY0LCJzaGEyNTYiOiI1MzRkZDU5ZmQ0YzE1ZGQxMzgyZTgyN2YwYjg1YzE5ZjdjNjk4ZTIzNWY5Mjk5ZWFhMjAyZGI1NDAwODM0Mjg4In0seyJwYXRoIjoiTk9USUNFLnR4dCIsImJ5dGVzIjo2MjYsInNoYTI1NiI6IjFkZmJmNDQ5OGRjMDI2YjIwNTljMGIwYjVlYjVmYTFkODJhZTMzNGU1OGZmMTFlN2MyOTczMzMyN2YyNWM0ZWIifSx7InBhdGgiOiJSRUJVSUxESU5HLm1kIiwiYnl0ZXMiOjM4NDIsInNoYTI1NiI6ImNlNjA1YjVmZGIwMzE5MzM5ZjlmODNmMmZlN2NjY2JjN2U1NzI2ZmRmNDk0ZGE2ZTI4NDMzYmVmODI5ZWIwYmUifSx7InBhdGgiOiJTT1VSQ0UtTk9USUNFUy50eHQiLCJieXRlcyI6OTAxNzc3MSwic2hhMjU2IjoiODk5NzZiZWNjMjU2NTQwZTZkMmU4MDdiNDdhNGUwNWU4ODk5ODJjMDYyMmZjMDQ0MTNhN2JmN2U3N2E3N2UzNyJ9LHsicGF0aCI6IlRISVJELVBBUlRZLU5PVElDRVMudHh0IiwiYnl0ZXMiOjI0OTE0OTYsInNoYTI1NiI6IjExNjQ0N2VmZjc3ODkzNTExNzk3ZWY0NzYwMTFkZWM4MDAyMjRmOTFlMzM0MmUzZDY1NzA3MDg3MTJiNGI3NzIifSx7InBhdGgiOiJsaWNlbnNlcy9ucG0tY21kLXNoaW0udHh0IiwiYnl0ZXMiOjgxMywic2hhMjU2IjoiYWZmZmRmMTIwODExMjI3NDljNGI3MWM1YjFjMTFiYzY1OWQ3OTI0MmQxOWUxOGY1ZThkYmFiMDRhNDVlMzZiYiJ9LHsicGF0aCI6Im5wbS1hZGFwdGVyLWZpbGVzLmpzb24iLCJieXRlcyI6MTUyNCwic2hhMjU2IjoiZmYxMzFiMDMxNTkyOGNhY2FkNjY5MzcxNTQ2MTk4MzcwNWRkOWI3YTY0NDU1YzQ3M2NjN2YxZmY5ZjVmNmFlOSJ9XX0seyJ0YXJnZXQiOiJidW4td2luZG93cy1hcm02NCIsImZpbGVuYW1lIjoibm90aWZhaS0xMi4wLjAtYmV0YS4xMS13aW5kb3dzLWFybTY0LnppcCIsImJ5dGVzIjozODcxMTIyNSwic2hhMjU2IjoiMzIwMDgzM2U5MmQ0ZGUyNGY0ZWQ0YzdkY2JlYTE3ZjBmODE0NzdhZWIzOTIzMGQ3OWQ4YmI0NmFiOTUyNzU3YyIsInJ1bnRpbWVfc2hhMjU2IjoiY2E3ZTIxMDA3ZmY5NTM5NjRjNDdhZjM2OGNmZDAxOGMyMTg4Nzc5OTdlY2Y4OWQxNTQxMGRkOTU2MjZiMjgxYSIsImxhdW5jaGVyX3NoYTI1NiI6ImQ0N2MyMGFmYjQxYzQ0MzA5OTE0NjRmM2RjNjg1OTMzNDU0MmI0ZDE0Yzg5ZGI4MjZiOTk4M2Q1ZmE0YWZjMjciLCJtYXRlcmlhbHMiOlt7InBhdGgiOiJCVU4tTElDRU5TRS5tZCIsImJ5dGVzIjo1NjEzLCJzaGEyNTYiOiJiOWNhZjUyNzI4NjkxYjQwNTdlMzcxMjMyYzIyMWExMzI4ODMxOThiZTJmM2QyZGRmOTJjOTA0MDRjOTg0YjFhIn0seyJwYXRoIjoiQ09SUkVTUE9ORElORy1TT1VSQ0VTLmpzb24iLCJieXRlcyI6MjAyMCwic2hhMjU2IjoiZmE0YzM0NDgwMTE1NDg3MmQ2MTc5ZWUyZWY0OTkyM2RjOWY4OTA5ZWYwMWU1M2I4NmU4ZjU3YzYyNTgyMzI3NCJ9LHsicGF0aCI6IkxJQ0VOU0UudHh0IiwiYnl0ZXMiOjExMzQ2LCJzaGEyNTYiOiI5NDRjMTNmZjBmZTc5NWUyOTFmZDFjNDk0NzNmOThkNGZkZjFmNzQ2MzhlMDFmODgyNzY5Y2Q0Y2FlNzhiNzNkIn0seyJwYXRoIjoiTk9USUNFLVBST1ZFTkFOQ0UuanNvbiIsImJ5dGVzIjo0NTAyNjQsInNoYTI1NiI6IjUzNGRkNTlmZDRjMTVkZDEzODJlODI3ZjBiODVjMTlmN2M2OThlMjM1ZjkyOTllYWEyMDJkYjU0MDA4MzQyODgifSx7InBhdGgiOiJOT1RJQ0UudHh0IiwiYnl0ZXMiOjYyNiwic2hhMjU2IjoiMWRmYmY0NDk4ZGMwMjZiMjA1OWMwYjBiNWViNWZhMWQ4MmFlMzM0ZTU4ZmYxMWU3YzI5NzMzMzI3ZjI1YzRlYiJ9LHsicGF0aCI6IlJFQlVJTERJTkcubWQiLCJieXRlcyI6Mzg0Miwic2hhMjU2IjoiY2U2MDViNWZkYjAzMTkzMzlmOWY4M2YyZmU3Y2NjYmM3ZTU3MjZmZGY0OTRkYTZlMjg0MzNiZWY4MjllYjBiZSJ9LHsicGF0aCI6IlNPVVJDRS1OT1RJQ0VTLnR4dCIsImJ5dGVzIjo5MDE3NzcxLCJzaGEyNTYiOiI4OTk3NmJlY2MyNTY1NDBlNmQyZTgwN2I0N2E0ZTA1ZTg4OTk4MmMwNjIyZmMwNDQxM2E3YmY3ZTc3YTc3ZTM3In0seyJwYXRoIjoiVEhJUkQtUEFSVFktTk9USUNFUy50eHQiLCJieXRlcyI6MjQ5MTQ5Niwic2hhMjU2IjoiMTE2NDQ3ZWZmNzc4OTM1MTE3OTdlZjQ3NjAxMWRlYzgwMDIyNGY5MWUzMzQyZTNkNjU3MDcwODcxMmI0Yjc3MiJ9LHsicGF0aCI6ImxpY2Vuc2VzL25wbS1jbWQtc2hpbS50eHQiLCJieXRlcyI6ODEzLCJzaGEyNTYiOiJhZmZmZGYxMjA4MTEyMjc0OWM0YjcxYzViMWMxMWJjNjU5ZDc5MjQyZDE5ZTE4ZjVlOGRiYWIwNGE0NWUzNmJiIn0seyJwYXRoIjoibnBtLWFkYXB0ZXItZmlsZXMuanNvbiIsImJ5dGVzIjoxNTI0LCJzaGEyNTYiOiJmZjEzMWIwMzE1OTI4Y2FjYWQ2NjkzNzE1NDYxOTgzNzA1ZGQ5YjdhNjQ0NTVjNDczY2M3ZjFmZjlmNWY2YWU5In1dfSx7InRhcmdldCI6ImJ1bi13aW5kb3dzLXg2NCIsImZpbGVuYW1lIjoibm90aWZhaS0xMi4wLjAtYmV0YS4xMS13aW5kb3dzLXg2NC56aXAiLCJieXRlcyI6NDE4NTcwNDEsInNoYTI1NiI6IjJiZjJkN2EyZTRhNTY5NzkyNmZmZDRjMGU4NDk2MWYwMzRjODdkNzBiYTMxOTMxMWYwMjM4ODhmNWJmMjJhMjkiLCJydW50aW1lX3NoYTI1NiI6ImRlMDkzMTc2YzM1MGRjMzYyMzQzMGJiMTdiN2M3NWEyODc1ZjdiNWI1MTEwMmZiYjg3ODYxODRkMjA0ZGI4YTUiLCJsYXVuY2hlcl9zaGEyNTYiOiJlMzNhZGU2MjJhOTQ3NDczMmRiMDdmNzE3ZGI4NzdhODFjYzkzM2I2OTM5ODJiNDFlMWFlNTc5MTMwM2ExYjQ4IiwibWF0ZXJpYWxzIjpbeyJwYXRoIjoiQlVOLUxJQ0VOU0UubWQiLCJieXRlcyI6NTYxMywic2hhMjU2IjoiYjljYWY1MjcyODY5MWI0MDU3ZTM3MTIzMmMyMjFhMTMyODgzMTk4YmUyZjNkMmRkZjkyYzkwNDA0Yzk4NGIxYSJ9LHsicGF0aCI6IkNPUlJFU1BPTkRJTkctU09VUkNFUy5qc29uIiwiYnl0ZXMiOjIwMjAsInNoYTI1NiI6ImZhNGMzNDQ4MDExNTQ4NzJkNjE3OWVlMmVmNDk5MjNkYzlmODkwOWVmMDFlNTNiODZlOGY1N2M2MjU4MjMyNzQifSx7InBhdGgiOiJMSUNFTlNFLnR4dCIsImJ5dGVzIjoxMTM0Niwic2hhMjU2IjoiOTQ0YzEzZmYwZmU3OTVlMjkxZmQxYzQ5NDczZjk4ZDRmZGYxZjc0NjM4ZTAxZjg4Mjc2OWNkNGNhZTc4YjczZCJ9LHsicGF0aCI6Ik5PVElDRS1QUk9WRU5BTkNFLmpzb24iLCJieXRlcyI6NDUwMjY0LCJzaGEyNTYiOiI1MzRkZDU5ZmQ0YzE1ZGQxMzgyZTgyN2YwYjg1YzE5ZjdjNjk4ZTIzNWY5Mjk5ZWFhMjAyZGI1NDAwODM0Mjg4In0seyJwYXRoIjoiTk9USUNFLnR4dCIsImJ5dGVzIjo2MjYsInNoYTI1NiI6IjFkZmJmNDQ5OGRjMDI2YjIwNTljMGIwYjVlYjVmYTFkODJhZTMzNGU1OGZmMTFlN2MyOTczMzMyN2YyNWM0ZWIifSx7InBhdGgiOiJSRUJVSUxESU5HLm1kIiwiYnl0ZXMiOjM4NDIsInNoYTI1NiI6ImNlNjA1YjVmZGIwMzE5MzM5ZjlmODNmMmZlN2NjY2JjN2U1NzI2ZmRmNDk0ZGE2ZTI4NDMzYmVmODI5ZWIwYmUifSx7InBhdGgiOiJTT1VSQ0UtTk9USUNFUy50eHQiLCJieXRlcyI6OTAxNzc3MSwic2hhMjU2IjoiODk5NzZiZWNjMjU2NTQwZTZkMmU4MDdiNDdhNGUwNWU4ODk5ODJjMDYyMmZjMDQ0MTNhN2JmN2U3N2E3N2UzNyJ9LHsicGF0aCI6IlRISVJELVBBUlRZLU5PVElDRVMudHh0IiwiYnl0ZXMiOjI0OTE0OTYsInNoYTI1NiI6IjExNjQ0N2VmZjc3ODkzNTExNzk3ZWY0NzYwMTFkZWM4MDAyMjRmOTFlMzM0MmUzZDY1NzA3MDg3MTJiNGI3NzIifSx7InBhdGgiOiJsaWNlbnNlcy9ucG0tY21kLXNoaW0udHh0IiwiYnl0ZXMiOjgxMywic2hhMjU2IjoiYWZmZmRmMTIwODExMjI3NDljNGI3MWM1YjFjMTFiYzY1OWQ3OTI0MmQxOWUxOGY1ZThkYmFiMDRhNDVlMzZiYiJ9LHsicGF0aCI6Im5wbS1hZGFwdGVyLWZpbGVzLmpzb24iLCJieXRlcyI6MTUyNCwic2hhMjU2IjoiZmYxMzFiMDMxNTkyOGNhY2FkNjY5MzcxNTQ2MTk4MzcwNWRkOWI3YTY0NDU1YzQ3M2NjN2YxZmY5ZjVmNmFlOSJ9XX1dfQ==","signature":"JZNPkt8v63dNCXxEZyQ9yDXRhJeCn1btpbH3lN1BucKFnRUWAAC7hnHq++5heCzDv4no4yy06y0PPiLA6EYTCA=="}
@@ -0,0 +1,52 @@
1
+ {
2
+ "schema": 1,
3
+ "package": "@raidiant/notifai",
4
+ "adapter_version": "12.0.0-beta.11",
5
+ "native": {
6
+ "version": "12.0.0-beta.11",
7
+ "source_revision": "29b033b35eb72cf2c4235a604d865b70bb9c516a",
8
+ "inventory_url": "https://github.com/Raidiant-io/notifai/releases/download/v12.0.0-beta.11/inventory.json"
9
+ },
10
+ "files": [
11
+ {
12
+ "path": "CHANGELOG.md",
13
+ "bytes": 61471,
14
+ "sha256": "5cafd85af6f1b7a64e74d8b7a4b415d7aa206d0b0bd05c46510e47f20aacced3"
15
+ },
16
+ {
17
+ "path": "LICENSE",
18
+ "bytes": 11346,
19
+ "sha256": "944c13ff0fe795e291fd1c49473f98d4fdf1f74638e01f882769cd4cae78b73d"
20
+ },
21
+ {
22
+ "path": "NOTICE",
23
+ "bytes": 626,
24
+ "sha256": "1dfbf4498dc026b2059c0b0b5eb5fa1d82ae334e58ff11e7c29733327f25c4eb"
25
+ },
26
+ {
27
+ "path": "THIRD_PARTY_NOTICES",
28
+ "bytes": 39652,
29
+ "sha256": "4639bc49701f661f67baf3d0408436d2cb80fd0c9799e68b9be3684f5ad69b91"
30
+ },
31
+ {
32
+ "path": "bin/notifai.mjs",
33
+ "bytes": 520496,
34
+ "sha256": "94eb5ae58a5ee49e7cd07552806a93d17bf83038c221a477c82c8341a9ae5d04"
35
+ },
36
+ {
37
+ "path": "data/install.ps1",
38
+ "bytes": 18811,
39
+ "sha256": "2925b84fb7890110695249d7f651a4ca0878f6ace2e127f44b7b4ad835073c5f"
40
+ },
41
+ {
42
+ "path": "data/release.json",
43
+ "bytes": 90,
44
+ "sha256": "ac4bc6b446c4eac56f8e7b9e01c6eed6844bb646908ae6913986de3db6dd1bb6"
45
+ },
46
+ {
47
+ "path": "package.json",
48
+ "bytes": 815,
49
+ "sha256": "d06b32f9a60aee9048f22a063e49a19f5ef3cd85a64ad7d2d86aa4967c088be9"
50
+ }
51
+ ]
52
+ }
package/package.json CHANGED
@@ -1,34 +1,22 @@
1
1
  {
2
2
  "name": "@raidiant/notifai",
3
- "version": "11.7.1",
3
+ "version": "12.0.0-beta.11",
4
4
  "type": "module",
5
- "description": "Send native device notifications from agents and local programs",
5
+ "description": "Launch the independently managed native Notifai CLI",
6
6
  "bin": {
7
- "notifai": "dist/main.js"
7
+ "notifai": "bin/notifai.mjs"
8
8
  },
9
9
  "files": [
10
- "dist",
10
+ "bin",
11
+ "data",
12
+ "package.json",
13
+ "npm-adapter-files.json",
14
+ "inventory.json",
15
+ "LICENSE",
16
+ "NOTICE",
17
+ "THIRD_PARTY_NOTICES",
11
18
  "CHANGELOG.md"
12
19
  ],
13
- "dependencies": {
14
- "@clack/prompts": "^1.7.0",
15
- "@raidiant/notifai-protocol": "8.2.1",
16
- "commander": "^14.0.0",
17
- "jsonc-parser": "^3.3.1",
18
- "picocolors": "^1.1.1",
19
- "qrcode": "1.5.4",
20
- "smol-toml": "^1.4.0",
21
- "ws": "8.21.0"
22
- },
23
- "devDependencies": {
24
- "@types/pngjs": "6.0.5",
25
- "@types/qrcode": "1.5.6",
26
- "@types/ws": "8.18.1",
27
- "jsqr": "1.4.0",
28
- "pngjs": "7.0.0",
29
- "typescript": "^5.8.0",
30
- "vitest": "4.1.11"
31
- },
32
20
  "engines": {
33
21
  "node": ">=20.12.0"
34
22
  },
@@ -38,30 +26,12 @@
38
26
  "bugs": {
39
27
  "url": "https://github.com/Raidiant-io/notifai/issues"
40
28
  },
41
- "publishConfig": {
42
- "access": "public"
43
- },
44
29
  "repository": {
45
30
  "type": "git",
46
31
  "url": "git+https://github.com/Raidiant-io/notifai.git",
47
32
  "directory": "apps/cli"
48
33
  },
49
- "keywords": [
50
- "notifications",
51
- "cli",
52
- "agents",
53
- "apns",
54
- "fcm",
55
- "android",
56
- "push",
57
- "ai",
58
- "claude",
59
- "codex"
60
- ],
61
- "scripts": {
62
- "build": "node ../../scripts/clean-dist.mjs && tsc -p tsconfig.json && node ../../scripts/copy-shipped-skill.mjs && node ../../scripts/chmod-cli-bin.mjs",
63
- "pretest": "pnpm run build",
64
- "typecheck": "tsc -p tsconfig.json --noEmit",
65
- "test": "node ../../scripts/run-cli-tests.mjs"
34
+ "publishConfig": {
35
+ "access": "public"
66
36
  }
67
- }
37
+ }
package/README.md DELETED
@@ -1,168 +0,0 @@
1
- # notifai
2
-
3
- Send native phone notifications from agents and local programs.
4
-
5
- An agent working while you are away has no way to reach you, so it either
6
- guesses or sits blocked in a terminal nobody is watching. `notifai` gives
7
- it a way to tell you something finished, and a way to ask you a question
8
- and get your answer back as a banner on your phone.
9
-
10
- ```sh
11
- npm install -g @raidiant/notifai
12
- notifai init
13
- ```
14
-
15
- The `notifai` command is always a machine-wide install. Setup scope (this
16
- project vs this machine) does not change that. If you do not want a global
17
- bin, `npx --yes @raidiant/notifai@<version>` is supported. Pin the version.
18
- `hooks install` then writes that same pinned npx invocation into the harness
19
- adapter. This is slower than a real install and is not the default path.
20
-
21
- Run `notifai doctor` or `notifai update --check --json` to check for a newer
22
- CLI and inspect release notes, guidance, and session requirements. Enabled
23
- Projects give root agents a quiet update offer at most once every seven days
24
- across the machine. A release does not install itself or restart an Agent
25
- Session automatically. The package includes its changelog.
26
-
27
- Use `notifai update` for later global updates. It repairs the installation the
28
- shell actually selects and keeps the stable hook adapter on that same CLI. It
29
- fails instead of moving the command to a different PATH slot when it cannot
30
- verify the selected installation or retarget an existing adapter safely.
31
-
32
- `init` walks the setup one step at a time and tells you the single next
33
- thing to do. Run it again after each step; it works out what remains.
34
-
35
- At a human terminal, `init` asks once whether this setup is for this project
36
- or for every project on this machine. That answer is skill, hooks, and
37
- config together. Pairing, devices, and credentials stay on this machine
38
- either way. An unattended caller passes the same choice as a flag:
39
- `notifai init --setup-scope project` or `notifai init --setup-scope global`.
40
- `--skills-scope` is an alias of that flag when `--skills` is set. Shared
41
- project config may live in the repo; personal project preferences live under
42
- the user config directory and never require a `.gitignore` edit.
43
-
44
- ## Telling you something happened
45
-
46
- ```sh
47
- notifai send --kind done \
48
- --title "Deploy finished" \
49
- --summary "The staging deployment is live." \
50
- --body "The staging deployment is live and ready for review."
51
- ```
52
-
53
- Write a brief title whose substance is immediately understandable; type lives
54
- in `--kind`, and Project identity is inferred from the invocation directory.
55
- Every Notification Request has a purpose-written, one-line plain-text Summary
56
- for native banners and list views. It is required and limited to 240 Unicode
57
- characters. Body is optional standalone Markdown for focused detail; when it is
58
- absent, the focused view shows Summary. Use `--body-file <path|->` for long
59
- content. Repeat `--image` for an ordered image
60
- collection (up to eight) and pair each with `--image-alt`. Every attached
61
- image appears in the gallery; to place one where the words refer to it, write
62
- Markdown image syntax with its 1-based position, `![what it shows](media:1)`.
63
- A bare `media:1` or a link to it is refused before sending.
64
-
65
- ## Asking you a question
66
-
67
- ```sh
68
- notifai ask "Deploy the migration to production?" \
69
- --choice Yes --choice No
70
- ```
71
-
72
- The agent registers the question and starts background submission immediately;
73
- it can continue independent work while your answer is outstanding. Registration
74
- alone does not prove Provider Acceptance. Question Routing keeps the exact
75
- Agent Session's answer path for the complete answer window. Claude Code on
76
- macOS/Linux and Codex observe answers out of band; Claude Code on Windows
77
- returns answers through a held Stop. Codex queues a wake-up, then drains current
78
- notes and answers together at a supported hook or `notifai receive` boundary.
79
- Queue success proves wake storage, not presentation.
80
-
81
- By default submission begins without waiting for the turn to end
82
- (`ask_grace_seconds = 0`). Set a positive grace period for a terminal-only
83
- answer window first.
84
-
85
- When you answer, the agent acknowledges it before it does anything else, so you
86
- find out your reply landed and what it set in motion — not just that you sent
87
- it. Answering from your phone and wondering whether anything happened is the
88
- whole problem this solves.
89
-
90
- For a harness that cannot resume an idle agent turn, `notifai send --reply`
91
- owns the complete answer window in the foreground: keep it alive and set
92
- `--reply-timeout` equal to `--reply-window`. After a timeout, retain the request
93
- ID and inspect that original with `notifai replies` and `notifai status`; never
94
- send a duplicate.
95
-
96
- ## Agent harnesses
97
-
98
- The CLI and managed hook adapters support macOS, Linux, and Windows. iPhone
99
- and Android Companion Apps are both active: Android is distributed as a
100
- directly downloadable signed APK (no Google Play listing yet), with a separate
101
- invitation-only Firebase App Distribution test lane. Native desktop Companion
102
- Apps are not shipped.
103
-
104
- ```sh
105
- notifai hooks install
106
- ```
107
-
108
- Wires lifecycle hooks into every supported harness detected on this
109
- machine (Claude Code, Codex, Cursor, OpenCode, OpenClaw, Grok). `notifai init` does the
110
- same and, at a terminal, lets you keep the detected set, pick a subset,
111
- or add one it did not see. This is what lets an agent's question reach
112
- your phone without the agent having to cooperate — no question detection,
113
- no state in a context window that compaction will eat. Grok's managed hooks
114
- observe lifecycle events and hold Stop through the complete answer window,
115
- then return the answer to the same Agent Session. They cannot inject activation
116
- guidance; load the Notifai skill directly. Exact Source Context comes from
117
- `GROK_SESSION_ID`.
118
-
119
- Every harness definition calls one stable user-level adapter under the account
120
- home (`~/.notifai/bin/hook-adapter` on macOS/Linux and the corresponding user
121
- profile path on Windows). Node, package manager, CLI version, checkout,
122
- configuration directories, and notification preferences are resolved behind
123
- it, so upgrades and configuration changes do not rewrite trusted hook
124
- definitions. Windows invokes its JavaScript adapter through the registered Node
125
- executable; macOS/Linux retain the POSIX adapter and its stable command bytes.
126
- Codex SessionStart guidance stays within Codex's built-in inline-context budget,
127
- so its stable definition does not need an output-limit override that would
128
- create a different approval identity.
129
- Claude Code Stop returns immediately into the live inbox route on macOS/Linux;
130
- on Windows, where upstream exposes no inbox socket, Stop stays open and returns
131
- the accepted answer through the harness continuation. The first migration may
132
- require one Codex `/hooks` approval; later repairs keep the same source and
133
- definition identity.
134
- Codex's Stop definition declares the full-window timeout explicitly; that
135
- one-time definition change is why the migration needs approval. Prompt-submit
136
- and session-end retain fixed short limits.
137
-
138
- `notifai doctor` compares Codex trust on a best-effort basis against Codex's
139
- current persisted representation. Notifai never writes that trust store;
140
- Codex's `/hooks` review is authoritative if the diagnostic and UI disagree.
141
-
142
- Uninstall removes only the selected harness definition. It intentionally keeps
143
- the shared adapter because definitions for other harnesses or projects may
144
- still invoke it and cannot all be discovered from one working directory.
145
-
146
- ## Checking it works
147
-
148
- ```sh
149
- notifai doctor
150
- ```
151
-
152
- Reports every part of the setup and names where to start if something is
153
- wrong. Any `FAIL` line makes the command exit nonzero; informational `--` lines
154
- do not. `--json` emits the same result with an explicit `exit_code`.
155
-
156
- ## Reference
157
-
158
- `notifai <command> --help` is the exhaustive and current flag surface.
159
- Everything useful is possible non-interactively, so an agent never
160
- reaches a prompt and hangs.
161
-
162
- Source, issues and the public/private boundary policy:
163
- <https://github.com/Raidiant-io/notifai>
164
-
165
- The URL, self-host exception, guidance-authority and non-exfiltration policy is
166
- documented in [`docs/TRUST.md`](https://github.com/Raidiant-io/notifai/blob/main/docs/TRUST.md).
167
-
168
- Apache-2.0.
@@ -1,7 +0,0 @@
1
- /** One optional notice per machine-local state directory, across roots and harnesses. */
2
- export declare function agentUpdateNotice(options: {
3
- env: NodeJS.ProcessEnv;
4
- now: number;
5
- updateCommand: string;
6
- fetchImpl?: typeof fetch;
7
- }): Promise<string | undefined>;