reflectt-node 0.1.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 (486) hide show
  1. package/LICENSE +178 -0
  2. package/README.md +188 -0
  3. package/dist/activationEvents.d.ts +110 -0
  4. package/dist/activationEvents.d.ts.map +1 -0
  5. package/dist/activationEvents.js +378 -0
  6. package/dist/activationEvents.js.map +1 -0
  7. package/dist/activity-signal.d.ts +30 -0
  8. package/dist/activity-signal.d.ts.map +1 -0
  9. package/dist/activity-signal.js +93 -0
  10. package/dist/activity-signal.js.map +1 -0
  11. package/dist/alert-integrity.d.ts +100 -0
  12. package/dist/alert-integrity.d.ts.map +1 -0
  13. package/dist/alert-integrity.js +333 -0
  14. package/dist/alert-integrity.js.map +1 -0
  15. package/dist/alert-preflight.d.ts +40 -0
  16. package/dist/alert-preflight.d.ts.map +1 -0
  17. package/dist/alert-preflight.js +235 -0
  18. package/dist/alert-preflight.js.map +1 -0
  19. package/dist/analytics.d.ts +131 -0
  20. package/dist/analytics.d.ts.map +1 -0
  21. package/dist/analytics.js +371 -0
  22. package/dist/analytics.js.map +1 -0
  23. package/dist/artifact-mirror.d.ts +26 -0
  24. package/dist/artifact-mirror.d.ts.map +1 -0
  25. package/dist/artifact-mirror.js +170 -0
  26. package/dist/artifact-mirror.js.map +1 -0
  27. package/dist/artifact-resolver.d.ts +48 -0
  28. package/dist/artifact-resolver.d.ts.map +1 -0
  29. package/dist/artifact-resolver.js +164 -0
  30. package/dist/artifact-resolver.js.map +1 -0
  31. package/dist/assignment.d.ts +116 -0
  32. package/dist/assignment.d.ts.map +1 -0
  33. package/dist/assignment.js +475 -0
  34. package/dist/assignment.js.map +1 -0
  35. package/dist/auditLedger.d.ts +50 -0
  36. package/dist/auditLedger.d.ts.map +1 -0
  37. package/dist/auditLedger.js +136 -0
  38. package/dist/auditLedger.js.map +1 -0
  39. package/dist/boardHealthWorker.d.ts +134 -0
  40. package/dist/boardHealthWorker.d.ts.map +1 -0
  41. package/dist/boardHealthWorker.js +882 -0
  42. package/dist/boardHealthWorker.js.map +1 -0
  43. package/dist/bootstrap-team.d.ts +42 -0
  44. package/dist/bootstrap-team.d.ts.map +1 -0
  45. package/dist/bootstrap-team.js +111 -0
  46. package/dist/bootstrap-team.js.map +1 -0
  47. package/dist/buildInfo.d.ts +17 -0
  48. package/dist/buildInfo.d.ts.map +1 -0
  49. package/dist/buildInfo.js +56 -0
  50. package/dist/buildInfo.js.map +1 -0
  51. package/dist/calendar-events.d.ts +133 -0
  52. package/dist/calendar-events.d.ts.map +1 -0
  53. package/dist/calendar-events.js +615 -0
  54. package/dist/calendar-events.js.map +1 -0
  55. package/dist/calendar-ical.d.ts +41 -0
  56. package/dist/calendar-ical.d.ts.map +1 -0
  57. package/dist/calendar-ical.js +413 -0
  58. package/dist/calendar-ical.js.map +1 -0
  59. package/dist/calendar-reminder-engine.d.ts +10 -0
  60. package/dist/calendar-reminder-engine.d.ts.map +1 -0
  61. package/dist/calendar-reminder-engine.js +143 -0
  62. package/dist/calendar-reminder-engine.js.map +1 -0
  63. package/dist/calendar.d.ts +75 -0
  64. package/dist/calendar.d.ts.map +1 -0
  65. package/dist/calendar.js +391 -0
  66. package/dist/calendar.js.map +1 -0
  67. package/dist/canvas-multiplexer.d.ts +44 -0
  68. package/dist/canvas-multiplexer.d.ts.map +1 -0
  69. package/dist/canvas-multiplexer.js +150 -0
  70. package/dist/canvas-multiplexer.js.map +1 -0
  71. package/dist/canvas-slots.d.ts +83 -0
  72. package/dist/canvas-slots.d.ts.map +1 -0
  73. package/dist/canvas-slots.js +144 -0
  74. package/dist/canvas-slots.js.map +1 -0
  75. package/dist/canvas-types.d.ts +56 -0
  76. package/dist/canvas-types.d.ts.map +1 -0
  77. package/dist/canvas-types.js +54 -0
  78. package/dist/canvas-types.js.map +1 -0
  79. package/dist/cf-keepalive.d.ts +40 -0
  80. package/dist/cf-keepalive.d.ts.map +1 -0
  81. package/dist/cf-keepalive.js +153 -0
  82. package/dist/cf-keepalive.js.map +1 -0
  83. package/dist/changeFeed.d.ts +38 -0
  84. package/dist/changeFeed.d.ts.map +1 -0
  85. package/dist/changeFeed.js +324 -0
  86. package/dist/changeFeed.js.map +1 -0
  87. package/dist/channels.d.ts +28 -0
  88. package/dist/channels.d.ts.map +1 -0
  89. package/dist/channels.js +23 -0
  90. package/dist/channels.js.map +1 -0
  91. package/dist/chat-approval-detector.d.ts +47 -0
  92. package/dist/chat-approval-detector.d.ts.map +1 -0
  93. package/dist/chat-approval-detector.js +224 -0
  94. package/dist/chat-approval-detector.js.map +1 -0
  95. package/dist/chat.d.ts +119 -0
  96. package/dist/chat.d.ts.map +1 -0
  97. package/dist/chat.js +666 -0
  98. package/dist/chat.js.map +1 -0
  99. package/dist/cli.d.ts +3 -0
  100. package/dist/cli.d.ts.map +1 -0
  101. package/dist/cli.js +1142 -0
  102. package/dist/cli.js.map +1 -0
  103. package/dist/cloud.d.ts +45 -0
  104. package/dist/cloud.d.ts.map +1 -0
  105. package/dist/cloud.js +962 -0
  106. package/dist/cloud.js.map +1 -0
  107. package/dist/config.d.ts +17 -0
  108. package/dist/config.d.ts.map +1 -0
  109. package/dist/config.js +33 -0
  110. package/dist/config.js.map +1 -0
  111. package/dist/connectivity.d.ts +59 -0
  112. package/dist/connectivity.d.ts.map +1 -0
  113. package/dist/connectivity.js +173 -0
  114. package/dist/connectivity.js.map +1 -0
  115. package/dist/contacts.d.ts +59 -0
  116. package/dist/contacts.d.ts.map +1 -0
  117. package/dist/contacts.js +183 -0
  118. package/dist/contacts.js.map +1 -0
  119. package/dist/content.d.ts +130 -0
  120. package/dist/content.d.ts.map +1 -0
  121. package/dist/content.js +186 -0
  122. package/dist/content.js.map +1 -0
  123. package/dist/context-budget.d.ts +87 -0
  124. package/dist/context-budget.d.ts.map +1 -0
  125. package/dist/context-budget.js +459 -0
  126. package/dist/context-budget.js.map +1 -0
  127. package/dist/continuity-loop.d.ts +55 -0
  128. package/dist/continuity-loop.d.ts.map +1 -0
  129. package/dist/continuity-loop.js +267 -0
  130. package/dist/continuity-loop.js.map +1 -0
  131. package/dist/dashboard.d.ts +6 -0
  132. package/dist/dashboard.d.ts.map +1 -0
  133. package/dist/dashboard.js +2348 -0
  134. package/dist/dashboard.js.map +1 -0
  135. package/dist/db.d.ts +44 -0
  136. package/dist/db.d.ts.map +1 -0
  137. package/dist/db.js +648 -0
  138. package/dist/db.js.map +1 -0
  139. package/dist/doctor.d.ts +30 -0
  140. package/dist/doctor.d.ts.map +1 -0
  141. package/dist/doctor.js +159 -0
  142. package/dist/doctor.js.map +1 -0
  143. package/dist/duplicateClosureGuard.d.ts +31 -0
  144. package/dist/duplicateClosureGuard.d.ts.map +1 -0
  145. package/dist/duplicateClosureGuard.js +83 -0
  146. package/dist/duplicateClosureGuard.js.map +1 -0
  147. package/dist/embeddings.d.ts +13 -0
  148. package/dist/embeddings.d.ts.map +1 -0
  149. package/dist/embeddings.js +78 -0
  150. package/dist/embeddings.js.map +1 -0
  151. package/dist/escalation.d.ts +80 -0
  152. package/dist/escalation.d.ts.map +1 -0
  153. package/dist/escalation.js +213 -0
  154. package/dist/escalation.js.map +1 -0
  155. package/dist/events.d.ts +130 -0
  156. package/dist/events.d.ts.map +1 -0
  157. package/dist/events.js +382 -0
  158. package/dist/events.js.map +1 -0
  159. package/dist/executionSweeper.d.ts +97 -0
  160. package/dist/executionSweeper.d.ts.map +1 -0
  161. package/dist/executionSweeper.js +875 -0
  162. package/dist/executionSweeper.js.map +1 -0
  163. package/dist/experiments.d.ts +47 -0
  164. package/dist/experiments.d.ts.map +1 -0
  165. package/dist/experiments.js +133 -0
  166. package/dist/experiments.js.map +1 -0
  167. package/dist/feedback.d.ts +179 -0
  168. package/dist/feedback.d.ts.map +1 -0
  169. package/dist/feedback.js +397 -0
  170. package/dist/feedback.js.map +1 -0
  171. package/dist/files.d.ts +52 -0
  172. package/dist/files.d.ts.map +1 -0
  173. package/dist/files.js +172 -0
  174. package/dist/files.js.map +1 -0
  175. package/dist/format-duration.d.ts +19 -0
  176. package/dist/format-duration.d.ts.map +1 -0
  177. package/dist/format-duration.js +33 -0
  178. package/dist/format-duration.js.map +1 -0
  179. package/dist/github-actor-auth.d.ts +20 -0
  180. package/dist/github-actor-auth.d.ts.map +1 -0
  181. package/dist/github-actor-auth.js +54 -0
  182. package/dist/github-actor-auth.js.map +1 -0
  183. package/dist/github-ci.d.ts +16 -0
  184. package/dist/github-ci.d.ts.map +1 -0
  185. package/dist/github-ci.js +37 -0
  186. package/dist/github-ci.js.map +1 -0
  187. package/dist/github-identity.d.ts +30 -0
  188. package/dist/github-identity.d.ts.map +1 -0
  189. package/dist/github-identity.js +96 -0
  190. package/dist/github-identity.js.map +1 -0
  191. package/dist/github-reviews.d.ts +24 -0
  192. package/dist/github-reviews.d.ts.map +1 -0
  193. package/dist/github-reviews.js +56 -0
  194. package/dist/github-reviews.js.map +1 -0
  195. package/dist/health.d.ts +391 -0
  196. package/dist/health.d.ts.map +1 -0
  197. package/dist/health.js +1841 -0
  198. package/dist/health.js.map +1 -0
  199. package/dist/host-keepalive.d.ts +22 -0
  200. package/dist/host-keepalive.d.ts.map +1 -0
  201. package/dist/host-keepalive.js +126 -0
  202. package/dist/host-keepalive.js.map +1 -0
  203. package/dist/host-registry.d.ts +43 -0
  204. package/dist/host-registry.d.ts.map +1 -0
  205. package/dist/host-registry.js +93 -0
  206. package/dist/host-registry.js.map +1 -0
  207. package/dist/inbox.d.ts +87 -0
  208. package/dist/inbox.d.ts.map +1 -0
  209. package/dist/inbox.js +410 -0
  210. package/dist/inbox.js.map +1 -0
  211. package/dist/index.d.ts +2 -0
  212. package/dist/index.d.ts.map +1 -0
  213. package/dist/index.js +306 -0
  214. package/dist/index.js.map +1 -0
  215. package/dist/insight-mutation.d.ts +32 -0
  216. package/dist/insight-mutation.d.ts.map +1 -0
  217. package/dist/insight-mutation.js +160 -0
  218. package/dist/insight-mutation.js.map +1 -0
  219. package/dist/insight-promotion.d.ts +89 -0
  220. package/dist/insight-promotion.d.ts.map +1 -0
  221. package/dist/insight-promotion.js +278 -0
  222. package/dist/insight-promotion.js.map +1 -0
  223. package/dist/insight-task-bridge.d.ts +77 -0
  224. package/dist/insight-task-bridge.d.ts.map +1 -0
  225. package/dist/insight-task-bridge.js +556 -0
  226. package/dist/insight-task-bridge.js.map +1 -0
  227. package/dist/insights.d.ts +222 -0
  228. package/dist/insights.d.ts.map +1 -0
  229. package/dist/insights.js +871 -0
  230. package/dist/insights.js.map +1 -0
  231. package/dist/intake-pipeline.d.ts +74 -0
  232. package/dist/intake-pipeline.d.ts.map +1 -0
  233. package/dist/intake-pipeline.js +199 -0
  234. package/dist/intake-pipeline.js.map +1 -0
  235. package/dist/intensity.d.ts +31 -0
  236. package/dist/intensity.d.ts.map +1 -0
  237. package/dist/intensity.js +94 -0
  238. package/dist/intensity.js.map +1 -0
  239. package/dist/knowledge-auto-index.d.ts +37 -0
  240. package/dist/knowledge-auto-index.d.ts.map +1 -0
  241. package/dist/knowledge-auto-index.js +149 -0
  242. package/dist/knowledge-auto-index.js.map +1 -0
  243. package/dist/knowledge-docs.d.ts +45 -0
  244. package/dist/knowledge-docs.d.ts.map +1 -0
  245. package/dist/knowledge-docs.js +188 -0
  246. package/dist/knowledge-docs.js.map +1 -0
  247. package/dist/lane-config.d.ts +25 -0
  248. package/dist/lane-config.d.ts.map +1 -0
  249. package/dist/lane-config.js +105 -0
  250. package/dist/lane-config.js.map +1 -0
  251. package/dist/lineage.d.ts +86 -0
  252. package/dist/lineage.d.ts.map +1 -0
  253. package/dist/lineage.js +303 -0
  254. package/dist/lineage.js.map +1 -0
  255. package/dist/logStore.d.ts +25 -0
  256. package/dist/logStore.d.ts.map +1 -0
  257. package/dist/logStore.js +83 -0
  258. package/dist/logStore.js.map +1 -0
  259. package/dist/manage.d.ts +12 -0
  260. package/dist/manage.d.ts.map +1 -0
  261. package/dist/manage.js +253 -0
  262. package/dist/manage.js.map +1 -0
  263. package/dist/mcp.d.ts +5 -0
  264. package/dist/mcp.d.ts.map +1 -0
  265. package/dist/mcp.js +604 -0
  266. package/dist/mcp.js.map +1 -0
  267. package/dist/memory.d.ts +47 -0
  268. package/dist/memory.d.ts.map +1 -0
  269. package/dist/memory.js +149 -0
  270. package/dist/memory.js.map +1 -0
  271. package/dist/mention-ack.d.ts +80 -0
  272. package/dist/mention-ack.d.ts.map +1 -0
  273. package/dist/mention-ack.js +175 -0
  274. package/dist/mention-ack.js.map +1 -0
  275. package/dist/messageRouter.d.ts +60 -0
  276. package/dist/messageRouter.d.ts.map +1 -0
  277. package/dist/messageRouter.js +309 -0
  278. package/dist/messageRouter.js.map +1 -0
  279. package/dist/mutationAlert.d.ts +44 -0
  280. package/dist/mutationAlert.d.ts.map +1 -0
  281. package/dist/mutationAlert.js +174 -0
  282. package/dist/mutationAlert.js.map +1 -0
  283. package/dist/noise-budget.d.ts +136 -0
  284. package/dist/noise-budget.d.ts.map +1 -0
  285. package/dist/noise-budget.js +340 -0
  286. package/dist/noise-budget.js.map +1 -0
  287. package/dist/notifications.d.ts +67 -0
  288. package/dist/notifications.d.ts.map +1 -0
  289. package/dist/notifications.js +253 -0
  290. package/dist/notifications.js.map +1 -0
  291. package/dist/openclaw.d.ts +34 -0
  292. package/dist/openclaw.d.ts.map +1 -0
  293. package/dist/openclaw.js +208 -0
  294. package/dist/openclaw.js.map +1 -0
  295. package/dist/pause-controls.d.ts +31 -0
  296. package/dist/pause-controls.d.ts.map +1 -0
  297. package/dist/pause-controls.js +130 -0
  298. package/dist/pause-controls.js.map +1 -0
  299. package/dist/pidlock.d.ts +25 -0
  300. package/dist/pidlock.d.ts.map +1 -0
  301. package/dist/pidlock.js +179 -0
  302. package/dist/pidlock.js.map +1 -0
  303. package/dist/policy.d.ts +139 -0
  304. package/dist/policy.d.ts.map +1 -0
  305. package/dist/policy.js +264 -0
  306. package/dist/policy.js.map +1 -0
  307. package/dist/polls.d.ts +47 -0
  308. package/dist/polls.d.ts.map +1 -0
  309. package/dist/polls.js +162 -0
  310. package/dist/polls.js.map +1 -0
  311. package/dist/portability.d.ts +55 -0
  312. package/dist/portability.d.ts.map +1 -0
  313. package/dist/portability.js +292 -0
  314. package/dist/portability.js.map +1 -0
  315. package/dist/pr-integrity.d.ts +45 -0
  316. package/dist/pr-integrity.d.ts.map +1 -0
  317. package/dist/pr-integrity.js +124 -0
  318. package/dist/pr-integrity.js.map +1 -0
  319. package/dist/prAutoMerge.d.ts +62 -0
  320. package/dist/prAutoMerge.d.ts.map +1 -0
  321. package/dist/prAutoMerge.js +493 -0
  322. package/dist/prAutoMerge.js.map +1 -0
  323. package/dist/preflight.d.ts +66 -0
  324. package/dist/preflight.d.ts.map +1 -0
  325. package/dist/preflight.js +864 -0
  326. package/dist/preflight.js.map +1 -0
  327. package/dist/presence.d.ts +98 -0
  328. package/dist/presence.d.ts.map +1 -0
  329. package/dist/presence.js +347 -0
  330. package/dist/presence.js.map +1 -0
  331. package/dist/provisioning.d.ts +101 -0
  332. package/dist/provisioning.d.ts.map +1 -0
  333. package/dist/provisioning.js +430 -0
  334. package/dist/provisioning.js.map +1 -0
  335. package/dist/reflection-automation.d.ts +59 -0
  336. package/dist/reflection-automation.d.ts.map +1 -0
  337. package/dist/reflection-automation.js +350 -0
  338. package/dist/reflection-automation.js.map +1 -0
  339. package/dist/reflections.d.ts +65 -0
  340. package/dist/reflections.d.ts.map +1 -0
  341. package/dist/reflections.js +306 -0
  342. package/dist/reflections.js.map +1 -0
  343. package/dist/release.d.ts +67 -0
  344. package/dist/release.d.ts.map +1 -0
  345. package/dist/release.js +275 -0
  346. package/dist/release.js.map +1 -0
  347. package/dist/request-tracker.d.ts +36 -0
  348. package/dist/request-tracker.d.ts.map +1 -0
  349. package/dist/request-tracker.js +109 -0
  350. package/dist/request-tracker.js.map +1 -0
  351. package/dist/research.d.ts +75 -0
  352. package/dist/research.d.ts.map +1 -0
  353. package/dist/research.js +171 -0
  354. package/dist/research.js.map +1 -0
  355. package/dist/routing-approvals.d.ts +73 -0
  356. package/dist/routing-approvals.d.ts.map +1 -0
  357. package/dist/routing-approvals.js +88 -0
  358. package/dist/routing-approvals.js.map +1 -0
  359. package/dist/routing-override.d.ts +94 -0
  360. package/dist/routing-override.d.ts.map +1 -0
  361. package/dist/routing-override.js +290 -0
  362. package/dist/routing-override.js.map +1 -0
  363. package/dist/scope-routing.d.ts +18 -0
  364. package/dist/scope-routing.d.ts.map +1 -0
  365. package/dist/scope-routing.js +29 -0
  366. package/dist/scope-routing.js.map +1 -0
  367. package/dist/secrets.d.ts +77 -0
  368. package/dist/secrets.d.ts.map +1 -0
  369. package/dist/secrets.js +287 -0
  370. package/dist/secrets.js.map +1 -0
  371. package/dist/server.d.ts +3 -0
  372. package/dist/server.d.ts.map +1 -0
  373. package/dist/server.js +10887 -0
  374. package/dist/server.js.map +1 -0
  375. package/dist/service-probe.d.ts +53 -0
  376. package/dist/service-probe.d.ts.map +1 -0
  377. package/dist/service-probe.js +225 -0
  378. package/dist/service-probe.js.map +1 -0
  379. package/dist/shared-workspace-api.d.ts +73 -0
  380. package/dist/shared-workspace-api.d.ts.map +1 -0
  381. package/dist/shared-workspace-api.js +281 -0
  382. package/dist/shared-workspace-api.js.map +1 -0
  383. package/dist/shipped-heartbeat.d.ts +91 -0
  384. package/dist/shipped-heartbeat.d.ts.map +1 -0
  385. package/dist/shipped-heartbeat.js +272 -0
  386. package/dist/shipped-heartbeat.js.map +1 -0
  387. package/dist/starter-team.d.ts +23 -0
  388. package/dist/starter-team.d.ts.map +1 -0
  389. package/dist/starter-team.js +88 -0
  390. package/dist/starter-team.js.map +1 -0
  391. package/dist/suppression-ledger.d.ts +73 -0
  392. package/dist/suppression-ledger.d.ts.map +1 -0
  393. package/dist/suppression-ledger.js +125 -0
  394. package/dist/suppression-ledger.js.map +1 -0
  395. package/dist/system-loop-state.d.ts +4 -0
  396. package/dist/system-loop-state.d.ts.map +1 -0
  397. package/dist/system-loop-state.js +40 -0
  398. package/dist/system-loop-state.js.map +1 -0
  399. package/dist/taskCommentIngest.d.ts +43 -0
  400. package/dist/taskCommentIngest.d.ts.map +1 -0
  401. package/dist/taskCommentIngest.js +59 -0
  402. package/dist/taskCommentIngest.js.map +1 -0
  403. package/dist/taskPrecheck.d.ts +20 -0
  404. package/dist/taskPrecheck.d.ts.map +1 -0
  405. package/dist/taskPrecheck.js +329 -0
  406. package/dist/taskPrecheck.js.map +1 -0
  407. package/dist/taskStateSync.d.ts +8 -0
  408. package/dist/taskStateSync.d.ts.map +1 -0
  409. package/dist/taskStateSync.js +79 -0
  410. package/dist/taskStateSync.js.map +1 -0
  411. package/dist/tasks.d.ts +140 -0
  412. package/dist/tasks.d.ts.map +1 -0
  413. package/dist/tasks.js +1281 -0
  414. package/dist/tasks.js.map +1 -0
  415. package/dist/team-config.d.ts +24 -0
  416. package/dist/team-config.d.ts.map +1 -0
  417. package/dist/team-config.js +221 -0
  418. package/dist/team-config.js.map +1 -0
  419. package/dist/team-doctor.d.ts +22 -0
  420. package/dist/team-doctor.d.ts.map +1 -0
  421. package/dist/team-doctor.js +270 -0
  422. package/dist/team-doctor.js.map +1 -0
  423. package/dist/team-pulse.d.ts +52 -0
  424. package/dist/team-pulse.d.ts.map +1 -0
  425. package/dist/team-pulse.js +176 -0
  426. package/dist/team-pulse.js.map +1 -0
  427. package/dist/telemetry.d.ts +74 -0
  428. package/dist/telemetry.d.ts.map +1 -0
  429. package/dist/telemetry.js +256 -0
  430. package/dist/telemetry.js.map +1 -0
  431. package/dist/test-task-filter.d.ts +21 -0
  432. package/dist/test-task-filter.d.ts.map +1 -0
  433. package/dist/test-task-filter.js +48 -0
  434. package/dist/test-task-filter.js.map +1 -0
  435. package/dist/types.d.ts +126 -0
  436. package/dist/types.d.ts.map +1 -0
  437. package/dist/types.js +4 -0
  438. package/dist/types.js.map +1 -0
  439. package/dist/usage-tracking.d.ts +101 -0
  440. package/dist/usage-tracking.d.ts.map +1 -0
  441. package/dist/usage-tracking.js +325 -0
  442. package/dist/usage-tracking.js.map +1 -0
  443. package/dist/vector-store.d.ts +87 -0
  444. package/dist/vector-store.d.ts.map +1 -0
  445. package/dist/vector-store.js +247 -0
  446. package/dist/vector-store.js.map +1 -0
  447. package/dist/watchdog/idleNudgeLane.d.ts +22 -0
  448. package/dist/watchdog/idleNudgeLane.d.ts.map +1 -0
  449. package/dist/watchdog/idleNudgeLane.js +98 -0
  450. package/dist/watchdog/idleNudgeLane.js.map +1 -0
  451. package/dist/webhooks.d.ts +103 -0
  452. package/dist/webhooks.d.ts.map +1 -0
  453. package/dist/webhooks.js +398 -0
  454. package/dist/webhooks.js.map +1 -0
  455. package/dist/working-contract.d.ts +42 -0
  456. package/dist/working-contract.d.ts.map +1 -0
  457. package/dist/working-contract.js +228 -0
  458. package/dist/working-contract.js.map +1 -0
  459. package/dist/ws-heartbeat.d.ts +66 -0
  460. package/dist/ws-heartbeat.d.ts.map +1 -0
  461. package/dist/ws-heartbeat.js +174 -0
  462. package/dist/ws-heartbeat.js.map +1 -0
  463. package/package.json +87 -0
  464. package/plugins/reflectt-channel/README.md +96 -0
  465. package/plugins/reflectt-channel/index.ts +789 -0
  466. package/plugins/reflectt-channel/openclaw.plugin.json +23 -0
  467. package/plugins/reflectt-channel/package.json +23 -0
  468. package/plugins/reflectt-channel/src/channel.ts +433 -0
  469. package/plugins/reflectt-channel/src/types.ts +29 -0
  470. package/public/avatars/echo.png +0 -0
  471. package/public/avatars/harmony.png +0 -0
  472. package/public/avatars/kai.png +0 -0
  473. package/public/avatars/link.png +0 -0
  474. package/public/avatars/pixel.png +0 -0
  475. package/public/avatars/rhythm.png +0 -0
  476. package/public/avatars/ryan.png +0 -0
  477. package/public/avatars/sage.png +0 -0
  478. package/public/avatars/scout.png +0 -0
  479. package/public/avatars/spark.png +0 -0
  480. package/public/dashboard-animations.css +381 -0
  481. package/public/dashboard.js +3479 -0
  482. package/public/docs.md +1062 -0
  483. package/public/file-upload-mock.html +1097 -0
  484. package/public/og-card.png +0 -0
  485. package/public/ui-kit.html +318 -0
  486. package/public/widget/feedback.js +194 -0
@@ -0,0 +1,864 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (c) Reflectt AI
3
+ /**
4
+ * BYOH Preflight Checks + Guided Recovery
5
+ *
6
+ * Validates host readiness before cloud enrollment:
7
+ * 1. Node.js version compatibility
8
+ * 2. Network connectivity to cloud
9
+ * 3. Auth token/key validity
10
+ * 4. Port availability
11
+ * 5. Disk space / home directory writability
12
+ *
13
+ * Each check returns a PreflightResult with pass/fail + recovery guidance.
14
+ */
15
+ import { existsSync, accessSync, constants } from 'node:fs';
16
+ import { join } from 'node:path';
17
+ import { hostname, homedir } from 'node:os';
18
+ import { execFile } from 'node:child_process';
19
+ import { REFLECTT_HOME } from './config.js';
20
+ import { emitActivationEvent } from './activationEvents.js';
21
+ // ── Check Definitions ──
22
+ const CHECKS = [
23
+ {
24
+ id: 'node-version',
25
+ name: 'Node.js Version',
26
+ description: 'Requires Node.js >= 20.0.0',
27
+ category: 'version',
28
+ },
29
+ {
30
+ id: 'home-writable',
31
+ name: 'Home Directory',
32
+ description: 'REFLECTT_HOME must exist and be writable',
33
+ category: 'system',
34
+ },
35
+ {
36
+ id: 'port-available',
37
+ name: 'Port Available',
38
+ description: 'Default port (4445) must not be in use',
39
+ category: 'system',
40
+ },
41
+ {
42
+ id: 'cloud-reachable',
43
+ name: 'Cloud Connectivity',
44
+ description: 'Can reach Reflectt Cloud API',
45
+ category: 'network',
46
+ },
47
+ {
48
+ id: 'auth-valid',
49
+ name: 'Auth Credentials',
50
+ description: 'Join token or API key is valid',
51
+ category: 'auth',
52
+ },
53
+ {
54
+ id: 'macos-screen-recording',
55
+ name: 'macOS Screen Recording Permission',
56
+ description: 'Required to capture screen context on macOS',
57
+ category: 'apple',
58
+ },
59
+ {
60
+ id: 'macos-accessibility',
61
+ name: 'macOS Accessibility Permission',
62
+ description: 'Required for local UI automation on macOS',
63
+ category: 'apple',
64
+ },
65
+ {
66
+ id: 'openclaw-gateway',
67
+ name: 'OpenClaw Gateway',
68
+ description: 'Gateway must be running and reachable for tool execution',
69
+ category: 'system',
70
+ },
71
+ {
72
+ id: 'github-identity',
73
+ name: 'GitHub Identity',
74
+ description: 'GitHub PAT or App installation token configured for PR operations',
75
+ category: 'auth',
76
+ },
77
+ ];
78
+ // ── Helpers ──
79
+ function inferLevel(result) {
80
+ if (result.level)
81
+ return result.level;
82
+ return result.passed ? 'pass' : 'fail';
83
+ }
84
+ async function execFileText(file, args, opts) {
85
+ const timeoutMs = opts?.timeoutMs ?? 6_000;
86
+ return await new Promise((resolve) => {
87
+ execFile(file, args, { timeout: timeoutMs }, (error, stdout, stderr) => {
88
+ if (error) {
89
+ const anyErr = error;
90
+ resolve({
91
+ ok: false,
92
+ stdout: String(stdout || ''),
93
+ stderr: String(stderr || anyErr.message || ''),
94
+ code: typeof anyErr.code === 'number' ? anyErr.code : undefined,
95
+ });
96
+ return;
97
+ }
98
+ resolve({ ok: true, stdout: String(stdout || ''), stderr: String(stderr || '') });
99
+ });
100
+ });
101
+ }
102
+ function extractJsonObject(text) {
103
+ const start = text.indexOf('{');
104
+ if (start === -1)
105
+ return null;
106
+ try {
107
+ return JSON.parse(text.slice(start));
108
+ }
109
+ catch {
110
+ const last = text.lastIndexOf('{');
111
+ if (last === -1)
112
+ return null;
113
+ try {
114
+ return JSON.parse(text.slice(last));
115
+ }
116
+ catch {
117
+ return null;
118
+ }
119
+ }
120
+ }
121
+ // ── Apple layer: macOS checks (best-effort) ──
122
+ async function checkMacTccPermission(opts) {
123
+ const start = Date.now();
124
+ const check = CHECKS.find(c => c.id === opts.checkId);
125
+ if (process.platform !== 'darwin') {
126
+ return { check, passed: true, level: 'pass', message: 'Not macOS (skipped)', durationMs: Date.now() - start };
127
+ }
128
+ const dbPath = join(homedir(), 'Library', 'Application Support', 'com.apple.TCC', 'TCC.db');
129
+ if (!existsSync(dbPath)) {
130
+ return {
131
+ check,
132
+ passed: true,
133
+ level: 'warn',
134
+ message: `TCC database not found; cannot verify ${opts.systemSettingsName}`,
135
+ recovery: [
136
+ `Open System Settings → Privacy & Security → ${opts.systemSettingsName}`,
137
+ 'Enable permission for the app you run Reflectt/OpenClaw from (often Terminal or iTerm).',
138
+ `Quick open: open "${opts.deepLink}"`,
139
+ ],
140
+ details: { dbPath },
141
+ durationMs: Date.now() - start,
142
+ };
143
+ }
144
+ const quotedClients = opts.clients.map(c => `'${c.replace(/'/g, "''")}'`).join(',');
145
+ const queries = [
146
+ `SELECT client,auth_value FROM access WHERE service='${opts.service}' AND client IN (${quotedClients});`,
147
+ `SELECT client,allowed FROM access WHERE service='${opts.service}' AND client IN (${quotedClients});`,
148
+ ];
149
+ let rows = [];
150
+ let lastErr = '';
151
+ for (const q of queries) {
152
+ const res = await execFileText('sqlite3', ['-readonly', '-separator', '|', dbPath, q], { timeoutMs: 2_500 });
153
+ if (!res.ok) {
154
+ lastErr = (res.stderr || res.stdout).trim() || lastErr;
155
+ continue;
156
+ }
157
+ const lines = res.stdout.split('\n').map(l => l.trim()).filter(Boolean);
158
+ rows = lines.map((line) => {
159
+ const [client, raw] = line.split('|');
160
+ const value = Number.parseInt(String(raw ?? '').trim(), 10);
161
+ return {
162
+ client: String(client || '').trim(),
163
+ value: Number.isFinite(value) ? value : 0,
164
+ };
165
+ }).filter(r => r.client);
166
+ break;
167
+ }
168
+ if (rows.length === 0) {
169
+ return {
170
+ check,
171
+ passed: true,
172
+ level: 'warn',
173
+ message: `${opts.systemSettingsName}: no permission record found for ${opts.clients.join(', ')}`,
174
+ recovery: [
175
+ `Open System Settings → Privacy & Security → ${opts.systemSettingsName}`,
176
+ `Enable for: ${opts.clients.join(', ')}`,
177
+ `Quick open: open "${opts.deepLink}"`,
178
+ 'Then restart the app (Terminal/iTerm) and re-run preflight.',
179
+ ],
180
+ details: { dbPath, service: opts.service, note: lastErr || 'no rows' },
181
+ durationMs: Date.now() - start,
182
+ };
183
+ }
184
+ // Heuristic: any positive value indicates granted.
185
+ const allowed = rows.some(r => r.value > 0);
186
+ const snapshot = rows.map(r => `${r.client}=${r.value}`).join(', ');
187
+ return {
188
+ check,
189
+ passed: true,
190
+ level: allowed ? 'pass' : 'warn',
191
+ message: allowed
192
+ ? `${opts.systemSettingsName}: granted (${snapshot}) ✓`
193
+ : `${opts.systemSettingsName}: not granted (${snapshot})`,
194
+ recovery: allowed
195
+ ? undefined
196
+ : [
197
+ `Open System Settings → Privacy & Security → ${opts.systemSettingsName}`,
198
+ `Enable for: ${opts.clients.join(', ')}`,
199
+ `Quick open: open "${opts.deepLink}"`,
200
+ 'Then restart the app (Terminal/iTerm) and re-run preflight.',
201
+ ],
202
+ details: { dbPath, service: opts.service, rows },
203
+ durationMs: Date.now() - start,
204
+ };
205
+ }
206
+ async function checkOpenClawGateway() {
207
+ const start = Date.now();
208
+ const check = CHECKS.find(c => c.id === 'openclaw-gateway');
209
+ if (process.platform !== 'darwin') {
210
+ return { check, passed: true, level: 'pass', message: 'Not macOS (skipped)', durationMs: Date.now() - start };
211
+ }
212
+ const res = await execFileText('openclaw', ['gateway', 'status', '--json', '--timeout', '5000'], { timeoutMs: 7_000 });
213
+ const text = `${res.stdout}\n${res.stderr}`;
214
+ const json = extractJsonObject(text);
215
+ if (!json) {
216
+ return {
217
+ check,
218
+ passed: true,
219
+ level: 'warn',
220
+ message: 'Could not parse `openclaw gateway status` output',
221
+ recovery: ['Run: openclaw gateway status', 'If not running: openclaw gateway start'],
222
+ details: { ok: res.ok, stderr: res.stderr.slice(0, 500) },
223
+ durationMs: Date.now() - start,
224
+ };
225
+ }
226
+ const status = json?.service?.runtime?.status;
227
+ const rpcOk = json?.rpc?.ok;
228
+ const url = json?.rpc?.url || json?.gateway?.probeUrl;
229
+ const pid = json?.service?.runtime?.pid;
230
+ const bindHost = json?.gateway?.bindHost;
231
+ const port = json?.gateway?.port;
232
+ const running = status === 'running' && rpcOk === true;
233
+ return {
234
+ check,
235
+ passed: true,
236
+ level: running ? 'pass' : 'warn',
237
+ message: running
238
+ ? `Gateway running (pid ${pid}) at ${String(url || `ws://${bindHost}:${port}`)} ✓`
239
+ : `Gateway not reachable (status=${String(status)} rpc.ok=${String(rpcOk)})`,
240
+ recovery: running
241
+ ? undefined
242
+ : ['Start the gateway:', ' openclaw gateway start', 'Then verify:', ' openclaw gateway status'],
243
+ details: { status, rpcOk, url, pid, bindHost, port },
244
+ durationMs: Date.now() - start,
245
+ };
246
+ }
247
+ // ── Individual Checks ──
248
+ function checkNodeVersion() {
249
+ const start = Date.now();
250
+ const check = CHECKS.find(c => c.id === 'node-version');
251
+ const [major, minor] = process.versions.node.split('.').map(Number);
252
+ const minMajor = 20;
253
+ if (major >= minMajor) {
254
+ return {
255
+ check,
256
+ passed: true,
257
+ message: `Node.js v${process.versions.node} ✓`,
258
+ details: { version: process.versions.node, required: `>=${minMajor}.0.0` },
259
+ durationMs: Date.now() - start,
260
+ };
261
+ }
262
+ return {
263
+ check,
264
+ passed: false,
265
+ message: `Node.js v${process.versions.node} is below minimum v${minMajor}.0.0`,
266
+ recovery: [
267
+ `Upgrade Node.js to v${minMajor} or later:`,
268
+ ' nvm install 22 && nvm use 22',
269
+ ' # or: brew install node@22',
270
+ `Current: v${process.versions.node}`,
271
+ ],
272
+ details: { version: process.versions.node, required: `>=${minMajor}.0.0` },
273
+ durationMs: Date.now() - start,
274
+ };
275
+ }
276
+ function checkHomeWritable() {
277
+ const start = Date.now();
278
+ const check = CHECKS.find(c => c.id === 'home-writable');
279
+ try {
280
+ if (!existsSync(REFLECTT_HOME)) {
281
+ return {
282
+ check,
283
+ passed: false,
284
+ message: `REFLECTT_HOME does not exist: ${REFLECTT_HOME}`,
285
+ recovery: [
286
+ `Create the directory:`,
287
+ ` mkdir -p ${REFLECTT_HOME}`,
288
+ 'Or run: npx reflectt-node init',
289
+ ],
290
+ details: { path: REFLECTT_HOME, exists: false },
291
+ durationMs: Date.now() - start,
292
+ };
293
+ }
294
+ accessSync(REFLECTT_HOME, constants.W_OK);
295
+ return {
296
+ check,
297
+ passed: true,
298
+ message: `${REFLECTT_HOME} exists and is writable ✓`,
299
+ details: { path: REFLECTT_HOME, writable: true },
300
+ durationMs: Date.now() - start,
301
+ };
302
+ }
303
+ catch (err) {
304
+ return {
305
+ check,
306
+ passed: false,
307
+ message: `Cannot write to ${REFLECTT_HOME}: ${err.message}`,
308
+ recovery: [
309
+ 'Fix permissions:',
310
+ ` chmod 755 ${REFLECTT_HOME}`,
311
+ ` # or: sudo chown $(whoami) ${REFLECTT_HOME}`,
312
+ ],
313
+ details: { path: REFLECTT_HOME, error: err.message },
314
+ durationMs: Date.now() - start,
315
+ };
316
+ }
317
+ }
318
+ async function checkPortAvailable(port = 4445) {
319
+ const start = Date.now();
320
+ const check = CHECKS.find(c => c.id === 'port-available');
321
+ try {
322
+ const { createServer } = await import('node:net');
323
+ const available = await new Promise((resolve) => {
324
+ const server = createServer();
325
+ server.once('error', () => resolve(false));
326
+ server.once('listening', () => {
327
+ server.close();
328
+ resolve(true);
329
+ });
330
+ server.listen(port, '127.0.0.1');
331
+ });
332
+ if (available) {
333
+ return {
334
+ check,
335
+ passed: true,
336
+ message: `Port ${port} is available ✓`,
337
+ details: { port, available: true },
338
+ durationMs: Date.now() - start,
339
+ };
340
+ }
341
+ return {
342
+ check,
343
+ passed: false,
344
+ message: `Port ${port} is already in use`,
345
+ recovery: [
346
+ `Check what's using port ${port}:`,
347
+ ` lsof -i :${port}`,
348
+ 'Options:',
349
+ ' 1. Stop the existing process',
350
+ ` 2. Use a different port: --port <number>`,
351
+ ' 3. If reflectt is already running, use: reflectt host status',
352
+ ],
353
+ details: { port, available: false },
354
+ durationMs: Date.now() - start,
355
+ };
356
+ }
357
+ catch (err) {
358
+ return {
359
+ check,
360
+ passed: true, // Can't check — assume available
361
+ message: `Port check inconclusive (${err.message}), proceeding`,
362
+ details: { port, error: err.message },
363
+ durationMs: Date.now() - start,
364
+ };
365
+ }
366
+ }
367
+ async function checkCloudReachable(cloudUrl = 'https://app.reflectt.ai') {
368
+ const start = Date.now();
369
+ const check = CHECKS.find(c => c.id === 'cloud-reachable');
370
+ const timeout = 10_000;
371
+ try {
372
+ const controller = new AbortController();
373
+ const timer = setTimeout(() => controller.abort(), timeout);
374
+ // Try the health/ping endpoint
375
+ const response = await fetch(`${cloudUrl}/api/health`, {
376
+ method: 'GET',
377
+ signal: controller.signal,
378
+ });
379
+ clearTimeout(timer);
380
+ if (response.ok || response.status === 404) {
381
+ // 404 is fine — means server is reachable, just no health endpoint
382
+ return {
383
+ check,
384
+ passed: true,
385
+ message: `Cloud reachable at ${cloudUrl} (${response.status}) ✓`,
386
+ details: { url: cloudUrl, status: response.status, latencyMs: Date.now() - start },
387
+ durationMs: Date.now() - start,
388
+ };
389
+ }
390
+ return {
391
+ check,
392
+ passed: false,
393
+ message: `Cloud returned ${response.status} ${response.statusText}`,
394
+ recovery: [
395
+ 'Check your network connection',
396
+ `Verify cloud URL: ${cloudUrl}`,
397
+ 'If behind a proxy, set HTTP_PROXY / HTTPS_PROXY env vars',
398
+ 'Try: curl -I ' + cloudUrl,
399
+ ],
400
+ details: { url: cloudUrl, status: response.status },
401
+ durationMs: Date.now() - start,
402
+ };
403
+ }
404
+ catch (err) {
405
+ const isTimeout = err.name === 'AbortError';
406
+ const isDns = err.code === 'ENOTFOUND';
407
+ return {
408
+ check,
409
+ passed: false,
410
+ message: isTimeout
411
+ ? `Cloud unreachable: connection timed out (${timeout}ms)`
412
+ : isDns
413
+ ? `DNS resolution failed for ${cloudUrl}`
414
+ : `Cloud unreachable: ${err.message}`,
415
+ recovery: isTimeout
416
+ ? [
417
+ 'Connection timed out — check your network:',
418
+ ' ping app.reflectt.ai',
419
+ ' curl -I ' + cloudUrl,
420
+ 'If behind a firewall, ensure outbound HTTPS is allowed',
421
+ ]
422
+ : isDns
423
+ ? [
424
+ 'DNS resolution failed:',
425
+ ' nslookup app.reflectt.ai',
426
+ ' # Check /etc/resolv.conf or DNS settings',
427
+ ` # Verify URL: ${cloudUrl}`,
428
+ ]
429
+ : [
430
+ 'Network error:',
431
+ ' ' + err.message,
432
+ ' Check your internet connection',
433
+ ' Try: curl -v ' + cloudUrl,
434
+ ],
435
+ details: { url: cloudUrl, error: err.message, code: err.code },
436
+ durationMs: Date.now() - start,
437
+ };
438
+ }
439
+ }
440
+ async function checkAuthValid(opts) {
441
+ const start = Date.now();
442
+ const check = CHECKS.find(c => c.id === 'auth-valid');
443
+ const cloudUrl = opts.cloudUrl || 'https://app.reflectt.ai';
444
+ if (!opts.joinToken && !opts.apiKey) {
445
+ return {
446
+ check,
447
+ passed: false,
448
+ message: 'No authentication credentials provided',
449
+ recovery: [
450
+ 'Provide either a join token or API key:',
451
+ ' --join-token <token> (from dashboard → Hosts → Add Host)',
452
+ ' --api-key <key> (from dashboard → Settings → API Keys)',
453
+ ],
454
+ durationMs: Date.now() - start,
455
+ };
456
+ }
457
+ // Validate format before making network call
458
+ if (opts.joinToken) {
459
+ // Join tokens are typically UUIDs or base64 strings
460
+ if (opts.joinToken.length < 8) {
461
+ return {
462
+ check,
463
+ passed: false,
464
+ message: 'Join token appears malformed (too short)',
465
+ recovery: [
466
+ 'Join tokens are generated from the dashboard:',
467
+ ' 1. Go to app.reflectt.ai → Hosts → Add Host',
468
+ ' 2. Copy the full token (usually 32+ characters)',
469
+ ' 3. Make sure no extra spaces or line breaks',
470
+ ],
471
+ durationMs: Date.now() - start,
472
+ };
473
+ }
474
+ }
475
+ if (opts.apiKey) {
476
+ if (opts.apiKey.length < 16) {
477
+ return {
478
+ check,
479
+ passed: false,
480
+ message: 'API key appears malformed (too short)',
481
+ recovery: [
482
+ 'API keys are generated from the dashboard:',
483
+ ' 1. Go to app.reflectt.ai → Settings → API Keys',
484
+ ' 2. Create a new key and copy the full value',
485
+ ' 3. Keys are shown only once — generate a new one if lost',
486
+ ],
487
+ durationMs: Date.now() - start,
488
+ };
489
+ }
490
+ }
491
+ // Try to validate with the cloud (non-blocking — network might be down)
492
+ try {
493
+ const controller = new AbortController();
494
+ const timer = setTimeout(() => controller.abort(), 8_000);
495
+ const endpoint = opts.joinToken
496
+ ? `${cloudUrl}/api/connect/validate`
497
+ : `${cloudUrl}/api/auth/validate`;
498
+ const response = await fetch(endpoint, {
499
+ method: 'POST',
500
+ headers: { 'Content-Type': 'application/json' },
501
+ body: JSON.stringify(opts.joinToken
502
+ ? { token: opts.joinToken }
503
+ : { apiKey: opts.apiKey }),
504
+ signal: controller.signal,
505
+ });
506
+ clearTimeout(timer);
507
+ if (response.ok) {
508
+ return {
509
+ check,
510
+ passed: true,
511
+ message: `${opts.joinToken ? 'Join token' : 'API key'} validated ✓`,
512
+ details: { method: opts.joinToken ? 'join-token' : 'api-key' },
513
+ durationMs: Date.now() - start,
514
+ };
515
+ }
516
+ const body = await response.json().catch(() => ({}));
517
+ if (response.status === 401 || response.status === 403) {
518
+ const isExpired = (body.error || '').toLowerCase().includes('expired');
519
+ return {
520
+ check,
521
+ passed: false,
522
+ message: isExpired
523
+ ? `${opts.joinToken ? 'Join token' : 'API key'} has expired`
524
+ : `${opts.joinToken ? 'Join token' : 'API key'} is invalid`,
525
+ recovery: isExpired
526
+ ? [
527
+ 'Token/key has expired. Generate a new one:',
528
+ ' 1. Go to app.reflectt.ai → Hosts → Add Host',
529
+ ' 2. Generate a fresh join token',
530
+ ' 3. Tokens expire after 24 hours',
531
+ ]
532
+ : [
533
+ `${opts.joinToken ? 'Join token' : 'API key'} was rejected:`,
534
+ ` ${body.error || 'Invalid credentials'}`,
535
+ ' 1. Verify you copied the full token/key',
536
+ ' 2. Check it hasn\'t been revoked',
537
+ ' 3. Generate a new one from the dashboard',
538
+ ],
539
+ details: { status: response.status, error: body.error },
540
+ durationMs: Date.now() - start,
541
+ };
542
+ }
543
+ // Non-auth error (404 = endpoint doesn't exist yet, etc.)
544
+ if (response.status === 404) {
545
+ return {
546
+ check,
547
+ passed: true, // Can't validate — assume OK
548
+ message: `Auth validation endpoint not available (format check passed) ✓`,
549
+ details: { method: opts.joinToken ? 'join-token' : 'api-key', validation: 'format-only' },
550
+ durationMs: Date.now() - start,
551
+ };
552
+ }
553
+ return {
554
+ check,
555
+ passed: false,
556
+ message: `Auth validation returned ${response.status}: ${body.error || 'unknown error'}`,
557
+ recovery: [
558
+ 'Unexpected response from cloud:',
559
+ ` Status: ${response.status}`,
560
+ ` Error: ${body.error || 'none'}`,
561
+ 'Try again in a few minutes, or contact support',
562
+ ],
563
+ details: { status: response.status, error: body.error },
564
+ durationMs: Date.now() - start,
565
+ };
566
+ }
567
+ catch (err) {
568
+ // Network error — can't validate, but format check passed
569
+ return {
570
+ check,
571
+ passed: true, // Don't block on network failures (cloud-reachable check handles that)
572
+ message: `Auth format valid (network validation skipped: ${err.message})`,
573
+ details: { method: opts.joinToken ? 'join-token' : 'api-key', validation: 'format-only', error: err.message },
574
+ durationMs: Date.now() - start,
575
+ };
576
+ }
577
+ }
578
+ async function checkGitHubIdentity(vault) {
579
+ const start = Date.now();
580
+ const check = CHECKS.find(c => c.id === 'github-identity');
581
+ const BLOCKED_CAPABILITIES = [
582
+ 'Approving pull requests',
583
+ 'Posting review comments',
584
+ 'Reporting CI status checks',
585
+ ];
586
+ const mode = (process.env.REFLECTT_GITHUB_IDENTITY_MODE || 'pat');
587
+ if (mode === 'app_installation') {
588
+ const privateKeySecretName = process.env.REFLECTT_GITHUB_APP_PRIVATE_KEY_SECRET || 'github.app.private_key_pem';
589
+ const appIdSecretName = process.env.REFLECTT_GITHUB_APP_ID_SECRET || 'github.app.app_id';
590
+ const installationIdSecretName = process.env.REFLECTT_GITHUB_APP_INSTALLATION_ID_SECRET || 'github.app.installation_id';
591
+ const requiredSecrets = [privateKeySecretName, appIdSecretName, installationIdSecretName];
592
+ if (!vault) {
593
+ return {
594
+ check,
595
+ passed: false,
596
+ level: 'warn',
597
+ message: 'app_installation mode configured but vault not available for preflight check',
598
+ recovery: [
599
+ 'Vault was not passed to preflight runner. This is a server configuration issue.',
600
+ 'Required vault secrets:',
601
+ ...requiredSecrets.map(s => ` reflectt-node vault write ${s}`),
602
+ ],
603
+ details: { mode, requiredSecrets },
604
+ durationMs: Date.now() - start,
605
+ };
606
+ }
607
+ let presentSecrets;
608
+ try {
609
+ const listed = vault.list().map(s => s.name);
610
+ presentSecrets = listed;
611
+ }
612
+ catch {
613
+ presentSecrets = [];
614
+ }
615
+ const missingSecrets = requiredSecrets.filter(s => !presentSecrets.includes(s));
616
+ if (missingSecrets.length > 0) {
617
+ return {
618
+ check,
619
+ passed: false,
620
+ level: 'fail',
621
+ message: `GitHub App secrets missing: ${missingSecrets.join(', ')}`,
622
+ recovery: [
623
+ 'Set the missing vault secrets:',
624
+ ...missingSecrets.map(s => ` reflectt-node vault write ${s}`),
625
+ '',
626
+ 'Without GitHub identity, the following are blocked:',
627
+ ...BLOCKED_CAPABILITIES.map(c => ` - ${c}`),
628
+ ],
629
+ details: { mode, requiredSecrets, missingSecrets, presentCount: presentSecrets.length },
630
+ durationMs: Date.now() - start,
631
+ };
632
+ }
633
+ return {
634
+ check,
635
+ passed: true,
636
+ level: 'pass',
637
+ message: `GitHub App secrets configured (${requiredSecrets.join(', ')}) ✓`,
638
+ details: { mode, configuredSecrets: requiredSecrets },
639
+ durationMs: Date.now() - start,
640
+ };
641
+ }
642
+ // PAT mode (default)
643
+ const patEnvKeys = ['GITHUB_TOKEN', 'GH_TOKEN'];
644
+ let tokenSource = null;
645
+ let tokenValue = null;
646
+ for (const key of patEnvKeys) {
647
+ const val = process.env[key];
648
+ if (val && val.trim()) {
649
+ tokenSource = key;
650
+ tokenValue = val.trim();
651
+ break;
652
+ }
653
+ }
654
+ if (!tokenValue || !tokenSource) {
655
+ return {
656
+ check,
657
+ passed: false,
658
+ level: 'fail',
659
+ message: 'No GitHub token found (GITHUB_TOKEN / GH_TOKEN not set)',
660
+ recovery: [
661
+ 'Set a GitHub Personal Access Token:',
662
+ ' export GITHUB_TOKEN=ghp_your_token_here',
663
+ ' # or: export GH_TOKEN=ghp_your_token_here',
664
+ '',
665
+ 'Create a token at: https://github.com/settings/tokens',
666
+ 'Required scopes: repo (for PR reviews and CI status)',
667
+ '',
668
+ 'Without GitHub identity, the following are blocked:',
669
+ ...BLOCKED_CAPABILITIES.map(c => ` - ${c}`),
670
+ ],
671
+ details: { mode, checkedEnvVars: patEnvKeys },
672
+ durationMs: Date.now() - start,
673
+ };
674
+ }
675
+ const redacted = `${tokenValue.slice(0, 4)}***`;
676
+ // Best-effort API validation
677
+ try {
678
+ const controller = new AbortController();
679
+ const timer = setTimeout(() => controller.abort(), 8_000);
680
+ const response = await fetch('https://api.github.com/user', {
681
+ headers: {
682
+ Authorization: `Bearer ${tokenValue}`,
683
+ Accept: 'application/vnd.github+json',
684
+ 'X-GitHub-Api-Version': '2022-11-28',
685
+ },
686
+ signal: controller.signal,
687
+ });
688
+ clearTimeout(timer);
689
+ if (response.ok) {
690
+ const scopes = response.headers.get('X-OAuth-Scopes') || '';
691
+ const hasRepoScope = scopes.split(',').map(s => s.trim()).includes('repo');
692
+ const json = await response.json().catch(() => ({}));
693
+ const login = typeof json.login === 'string' ? json.login : 'unknown';
694
+ return {
695
+ check,
696
+ passed: true,
697
+ level: 'pass',
698
+ message: `GitHub token valid (${tokenSource}=${redacted}, user=${login}) ✓`,
699
+ details: {
700
+ mode,
701
+ tokenSource,
702
+ redactedToken: redacted,
703
+ login,
704
+ scopes: scopes || '(none reported)',
705
+ hasRepoScope,
706
+ },
707
+ durationMs: Date.now() - start,
708
+ };
709
+ }
710
+ if (response.status === 401) {
711
+ return {
712
+ check,
713
+ passed: false,
714
+ level: 'fail',
715
+ message: `GitHub token invalid or expired (${tokenSource}=${redacted}, HTTP 401)`,
716
+ recovery: [
717
+ `Token in ${tokenSource} was rejected by GitHub.`,
718
+ 'Generate a new token at: https://github.com/settings/tokens',
719
+ `Then: export ${tokenSource}=ghp_your_new_token`,
720
+ '',
721
+ 'Without GitHub identity, the following are blocked:',
722
+ ...BLOCKED_CAPABILITIES.map(c => ` - ${c}`),
723
+ ],
724
+ details: { mode, tokenSource, redactedToken: redacted, status: 401 },
725
+ durationMs: Date.now() - start,
726
+ };
727
+ }
728
+ // Non-401 unexpected status — treat as warn (token present, validation unclear)
729
+ return {
730
+ check,
731
+ passed: true,
732
+ level: 'warn',
733
+ message: `GitHub token present (${tokenSource}=${redacted}) but validation returned HTTP ${response.status}`,
734
+ details: { mode, tokenSource, redactedToken: redacted, status: response.status },
735
+ durationMs: Date.now() - start,
736
+ };
737
+ }
738
+ catch (err) {
739
+ // Network error — token is present, just couldn't validate
740
+ return {
741
+ check,
742
+ passed: true,
743
+ level: 'warn',
744
+ message: `GitHub token present (${tokenSource}=${redacted}) — validation skipped: ${err.message}`,
745
+ details: { mode, tokenSource, redactedToken: redacted, validationError: err.message },
746
+ durationMs: Date.now() - start,
747
+ };
748
+ }
749
+ }
750
+ /**
751
+ * Run all preflight checks and return a report.
752
+ * Checks run in dependency order: system → network → auth
753
+ */
754
+ export async function runPreflight(opts = {}) {
755
+ const results = [];
756
+ // Phase 1: System checks (no network needed)
757
+ results.push(checkNodeVersion());
758
+ results.push(checkHomeWritable());
759
+ results.push(await checkPortAvailable(opts.port || 4445));
760
+ // Phase 1b: Apple layer checks (macOS-only, best-effort; do not block bootstrap)
761
+ if (process.platform === 'darwin') {
762
+ const commonClients = ['com.apple.Terminal', 'com.googlecode.iterm2'];
763
+ results.push(await checkMacTccPermission({
764
+ checkId: 'macos-screen-recording',
765
+ service: 'kTCCServiceScreenCapture',
766
+ systemSettingsName: 'Screen Recording',
767
+ deepLink: 'x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture',
768
+ clients: commonClients,
769
+ }));
770
+ results.push(await checkMacTccPermission({
771
+ checkId: 'macos-accessibility',
772
+ service: 'kTCCServiceAccessibility',
773
+ systemSettingsName: 'Accessibility',
774
+ deepLink: 'x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility',
775
+ clients: commonClients,
776
+ }));
777
+ results.push(await checkOpenClawGateway());
778
+ }
779
+ // Phase 2: Network checks
780
+ if (!opts.skipNetwork) {
781
+ results.push(await checkCloudReachable(opts.cloudUrl));
782
+ // Phase 3: Auth checks (depends on network)
783
+ if (opts.joinToken || opts.apiKey) {
784
+ results.push(await checkAuthValid({
785
+ cloudUrl: opts.cloudUrl,
786
+ joinToken: opts.joinToken,
787
+ apiKey: opts.apiKey,
788
+ }));
789
+ }
790
+ }
791
+ // Phase 4: GitHub identity (env/vault check is local; API validation is best-effort)
792
+ results.push(await checkGitHubIdentity(opts.vault));
793
+ const allPassed = results.every(r => r.passed);
794
+ const failures = results.filter(r => !r.passed);
795
+ const firstBlocker = failures[0];
796
+ const summary = allPassed
797
+ ? `All ${results.length} preflight checks passed ✓`
798
+ : `${failures.length}/${results.length} check(s) failed`;
799
+ // ── Onboarding drop-off instrumentation ──
800
+ // Emit activation events so the funnel tracks preflight pass/fail.
801
+ // Uses userId (from cloud auth) or a host-level fallback.
802
+ const hostId = `host-${hostname()}`;
803
+ const trackingId = opts.userId || hostId;
804
+ const failedCheckIds = failures.map(f => f.check.id);
805
+ const passedCheckIds = results.filter(r => r.passed).map(r => r.check.id);
806
+ if (allPassed) {
807
+ emitActivationEvent('host_preflight_passed', trackingId, {
808
+ checks_run: results.length,
809
+ passed_checks: passedCheckIds,
810
+ total_duration_ms: results.reduce((sum, r) => sum + r.durationMs, 0),
811
+ pid: process.pid,
812
+ }).catch(() => { }); // best-effort, never block preflight
813
+ }
814
+ else {
815
+ emitActivationEvent('host_preflight_failed', trackingId, {
816
+ checks_run: results.length,
817
+ failed_checks: failedCheckIds,
818
+ first_blocker: firstBlocker?.check.id,
819
+ passed_checks: passedCheckIds,
820
+ total_duration_ms: results.reduce((sum, r) => sum + r.durationMs, 0),
821
+ pid: process.pid,
822
+ }).catch(() => { }); // best-effort, never block preflight
823
+ }
824
+ return {
825
+ timestamp: Date.now(),
826
+ allPassed,
827
+ results,
828
+ summary,
829
+ firstBlocker: firstBlocker
830
+ ? {
831
+ check: firstBlocker.check.name,
832
+ message: firstBlocker.message,
833
+ recovery: firstBlocker.recovery || ['No specific recovery steps available'],
834
+ }
835
+ : undefined,
836
+ };
837
+ }
838
+ /**
839
+ * Format preflight report for CLI output.
840
+ */
841
+ export function formatPreflightReport(report) {
842
+ const lines = [];
843
+ lines.push('─── Preflight Checks ───');
844
+ lines.push('');
845
+ for (const result of report.results) {
846
+ const level = inferLevel(result);
847
+ const icon = level === 'pass' ? '✅' : level === 'warn' ? '⚠️' : '❌';
848
+ lines.push(`${icon} ${result.check.name}: ${result.message}`);
849
+ if (level !== 'pass' && result.recovery) {
850
+ lines.push('');
851
+ lines.push(' Recovery:');
852
+ for (const step of result.recovery) {
853
+ lines.push(` ${step}`);
854
+ }
855
+ lines.push('');
856
+ }
857
+ }
858
+ lines.push('────────────────────────');
859
+ lines.push(report.summary);
860
+ return lines.join('\n');
861
+ }
862
+ // Export individual checks for testing
863
+ export { checkNodeVersion as _checkNodeVersion, checkHomeWritable as _checkHomeWritable, checkPortAvailable as _checkPortAvailable, checkCloudReachable as _checkCloudReachable, checkAuthValid as _checkAuthValid, checkGitHubIdentity as _checkGitHubIdentity, };
864
+ //# sourceMappingURL=preflight.js.map