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
package/dist/cli.js ADDED
@@ -0,0 +1,1142 @@
1
+ #!/usr/bin/env node
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Copyright (c) Reflectt AI
4
+ /**
5
+ * reflectt CLI - Command line interface for reflectt-node
6
+ */
7
+ import { Command } from 'commander';
8
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync } from 'fs';
9
+ import { collectDoctorReport, formatDoctorHuman } from './doctor.js';
10
+ import { homedir, hostname } from 'os';
11
+ import { join, dirname } from 'path';
12
+ import { spawn, execSync } from 'child_process';
13
+ import { fileURLToPath } from 'url';
14
+ const REFLECTT_HOME = process.env.REFLECTT_HOME || join(homedir(), '.reflectt');
15
+ const CONFIG_PATH = join(REFLECTT_HOME, 'config.json');
16
+ const DATA_DIR = join(REFLECTT_HOME, 'data');
17
+ const PID_FILE = join(REFLECTT_HOME, 'server.pid');
18
+ function loadConfig() {
19
+ if (existsSync(CONFIG_PATH)) {
20
+ try {
21
+ return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
22
+ }
23
+ catch (err) {
24
+ console.error('⚠️ Failed to parse config.json, using defaults');
25
+ }
26
+ }
27
+ return { port: 4445, host: '127.0.0.1' };
28
+ }
29
+ function saveConfig(config) {
30
+ writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
31
+ }
32
+ function ensureReflecttHome() {
33
+ mkdirSync(REFLECTT_HOME, { recursive: true });
34
+ mkdirSync(DATA_DIR, { recursive: true });
35
+ mkdirSync(join(DATA_DIR, 'inbox'), { recursive: true });
36
+ }
37
+ function isServerRunning() {
38
+ if (!existsSync(PID_FILE))
39
+ return false;
40
+ try {
41
+ const pid = Number(readFileSync(PID_FILE, 'utf-8').trim());
42
+ process.kill(pid, 0);
43
+ return true;
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ }
49
+ function getRuntimePaths() {
50
+ const __filename = fileURLToPath(import.meta.url);
51
+ const __dirname = dirname(__filename);
52
+ const projectRoot = join(__dirname, '..');
53
+ const serverPath = join(projectRoot, 'src', 'index.ts');
54
+ return { projectRoot, serverPath };
55
+ }
56
+ function buildServerEnv(config) {
57
+ const env = {
58
+ ...process.env,
59
+ REFLECTT_HOME,
60
+ PORT: String(config.port),
61
+ HOST: config.host,
62
+ };
63
+ if (config.cloud) {
64
+ env.REFLECTT_CLOUD_URL = config.cloud.cloudUrl;
65
+ env.REFLECTT_HOST_NAME = config.cloud.hostName;
66
+ env.REFLECTT_HOST_TYPE = config.cloud.hostType;
67
+ env.REFLECTT_HOST_ID = config.cloud.hostId;
68
+ env.REFLECTT_HOST_CREDENTIAL = config.cloud.credential;
69
+ env.REFLECTT_HOST_TOKEN = config.cloud.credential;
70
+ }
71
+ return env;
72
+ }
73
+ function startServerDetached(config) {
74
+ const { projectRoot, serverPath } = getRuntimePaths();
75
+ if (!existsSync(serverPath)) {
76
+ throw new Error(`Server file not found: ${serverPath}`);
77
+ }
78
+ const child = spawn('npx', ['tsx', serverPath], {
79
+ env: buildServerEnv(config),
80
+ detached: true,
81
+ stdio: 'ignore',
82
+ cwd: projectRoot,
83
+ });
84
+ child.unref();
85
+ writeFileSync(PID_FILE, String(child.pid));
86
+ return child.pid ?? -1;
87
+ }
88
+ function stopServerIfRunning() {
89
+ if (!existsSync(PID_FILE))
90
+ return;
91
+ const pidRaw = readFileSync(PID_FILE, 'utf-8').trim();
92
+ const pid = Number(pidRaw);
93
+ if (!Number.isFinite(pid)) {
94
+ unlinkSync(PID_FILE);
95
+ return;
96
+ }
97
+ try {
98
+ process.kill(pid, 'SIGTERM');
99
+ }
100
+ catch {
101
+ // process already gone
102
+ }
103
+ try {
104
+ unlinkSync(PID_FILE);
105
+ }
106
+ catch {
107
+ // ignore cleanup errors
108
+ }
109
+ }
110
+ async function tryApiRequest(path, options = {}) {
111
+ const config = loadConfig();
112
+ const url = `http://${config.host}:${config.port}${path}`;
113
+ try {
114
+ const response = await fetch(url, options);
115
+ if (!response.ok)
116
+ return null;
117
+ return await response.json();
118
+ }
119
+ catch {
120
+ return null;
121
+ }
122
+ }
123
+ async function enrollHostWithApiKey(input) {
124
+ const url = `${input.cloudUrl.replace(/\/+$/, '')}/api/hosts/enroll`;
125
+ const response = await fetch(url, {
126
+ method: 'POST',
127
+ headers: {
128
+ 'content-type': 'application/json',
129
+ authorization: `Bearer ${input.apiKey}`,
130
+ },
131
+ body: JSON.stringify({
132
+ name: input.hostName,
133
+ capabilities: [input.hostType],
134
+ }),
135
+ });
136
+ const payload = await response.json().catch(() => ({}));
137
+ const hostId = payload?.host?.id;
138
+ const credential = payload?.credential?.token;
139
+ if (response.ok && hostId && credential) {
140
+ return { hostId: String(hostId), credential: String(credential) };
141
+ }
142
+ throw new Error(`API key enrollment failed: ${payload?.error || `${response.status} ${response.statusText}`}`);
143
+ }
144
+ async function registerHostWithCloud(input) {
145
+ const cloudBase = input.cloudUrl.replace(/\/+$/, '');
146
+ // New cloud API path (reflectt-cloud): /api/hosts/claim
147
+ // Legacy path (older API): /v1/hosts/register
148
+ const attempts = [
149
+ {
150
+ name: 'claim-join-token',
151
+ url: `${cloudBase}/api/hosts/claim`,
152
+ bearer: input.joinToken,
153
+ body: {
154
+ joinToken: input.joinToken,
155
+ name: input.hostName,
156
+ hostName: input.hostName,
157
+ hostType: input.hostType,
158
+ },
159
+ },
160
+ ...(input.authToken
161
+ ? [{
162
+ name: 'claim-user-jwt',
163
+ url: `${cloudBase}/api/hosts/claim`,
164
+ bearer: input.authToken,
165
+ body: {
166
+ joinToken: input.joinToken,
167
+ name: input.hostName,
168
+ hostName: input.hostName,
169
+ hostType: input.hostType,
170
+ },
171
+ }]
172
+ : []),
173
+ {
174
+ name: 'legacy-register',
175
+ url: `${cloudBase}/v1/hosts/register`,
176
+ bearer: input.joinToken,
177
+ body: {
178
+ joinToken: input.joinToken,
179
+ hostName: input.hostName,
180
+ hostType: input.hostType,
181
+ },
182
+ },
183
+ ];
184
+ const errors = [];
185
+ for (const attempt of attempts) {
186
+ try {
187
+ const response = await fetch(attempt.url, {
188
+ method: 'POST',
189
+ headers: {
190
+ 'content-type': 'application/json',
191
+ authorization: `Bearer ${attempt.bearer}`,
192
+ },
193
+ body: JSON.stringify(attempt.body),
194
+ });
195
+ const payload = await response.json().catch(() => ({}));
196
+ // Current cloud response shape
197
+ const hostId = payload?.host?.id || payload?.data?.hostId;
198
+ const credential = payload?.credential?.token || payload?.data?.credential;
199
+ if (response.ok && hostId && credential) {
200
+ return {
201
+ hostId: String(hostId),
202
+ credential: String(credential),
203
+ };
204
+ }
205
+ const detail = payload?.error || payload?.message || `${response.status} ${response.statusText}`;
206
+ errors.push(`${attempt.name}: ${detail}`);
207
+ }
208
+ catch (err) {
209
+ errors.push(`${attempt.name}: ${err?.message || 'request failed'}`);
210
+ }
211
+ }
212
+ throw new Error(`Cloud registration failed (${errors.join(' | ')})`);
213
+ }
214
+ async function waitForCloudHeartbeat(timeoutMs = 45_000) {
215
+ const started = Date.now();
216
+ while (Date.now() - started < timeoutMs) {
217
+ const status = await tryApiRequest('/cloud/status');
218
+ if (status?.registered && typeof status.hostId === 'string' && (status.heartbeatCount || 0) > 0) {
219
+ return { hostId: status.hostId, heartbeatCount: status.heartbeatCount };
220
+ }
221
+ await new Promise(resolve => setTimeout(resolve, 1500));
222
+ }
223
+ return null;
224
+ }
225
+ async function apiRequest(path, options = {}) {
226
+ const config = loadConfig();
227
+ const url = `http://${config.host}:${config.port}${path}`;
228
+ try {
229
+ const response = await fetch(url, options);
230
+ if (!response.ok) {
231
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
232
+ }
233
+ return await response.json();
234
+ }
235
+ catch (err) {
236
+ if (err.code === 'ECONNREFUSED') {
237
+ console.error('❌ Server is not running. Start it with: reflectt start');
238
+ }
239
+ else {
240
+ console.error('❌ Request failed:', err.message);
241
+ }
242
+ process.exit(1);
243
+ }
244
+ }
245
+ async function cloudRequest(url, token, method, body) {
246
+ const response = await fetch(url, {
247
+ method,
248
+ headers: {
249
+ 'content-type': 'application/json',
250
+ authorization: `Bearer ${token}`,
251
+ },
252
+ body: body === undefined ? undefined : JSON.stringify(body),
253
+ });
254
+ const json = await response.json().catch(() => ({}));
255
+ return { status: response.status, json };
256
+ }
257
+ function printStep(name, pass, detail) {
258
+ const icon = pass ? '✅' : '❌';
259
+ console.log(`${icon} ${name} — ${detail}`);
260
+ }
261
+ const program = new Command();
262
+ program
263
+ .name('reflectt')
264
+ .description('CLI for reflectt-node - local agent communication server')
265
+ .version('0.1.0');
266
+ // ============ INIT COMMAND ============
267
+ program
268
+ .command('init')
269
+ .description('Initialize reflectt team ops directory (~/.reflectt/)')
270
+ .option('--no-git', 'Skip git init and initial commit')
271
+ .option('--force', 'Overwrite existing team files with defaults')
272
+ .action((opts) => {
273
+ const isNew = !existsSync(REFLECTT_HOME);
274
+ let filesCreated = 0;
275
+ let filesSkipped = 0;
276
+ // Create directories
277
+ mkdirSync(REFLECTT_HOME, { recursive: true });
278
+ mkdirSync(DATA_DIR, { recursive: true });
279
+ mkdirSync(join(DATA_DIR, 'inbox'), { recursive: true });
280
+ // Create default config if missing
281
+ if (!existsSync(CONFIG_PATH)) {
282
+ const config = { port: 4445, host: '127.0.0.1' };
283
+ saveConfig(config);
284
+ filesCreated++;
285
+ console.log(' ✅ config.json');
286
+ }
287
+ else {
288
+ filesSkipped++;
289
+ console.log(' ⏭️ config.json (exists)');
290
+ }
291
+ // Copy default team files from defaults/ directory
292
+ const __filename = fileURLToPath(import.meta.url);
293
+ const __dirname = dirname(__filename);
294
+ const defaultsDir = join(__dirname, '..', 'defaults');
295
+ const teamFiles = [
296
+ { src: 'TEAM.md', desc: 'Team culture and principles' },
297
+ { src: 'TEAM-ROLES.yaml', desc: 'Agent role registry' },
298
+ { src: 'TEAM-STANDARDS.md', desc: 'Operational standards' },
299
+ { src: '.gitignore', desc: 'Git exclusions for runtime data' },
300
+ ];
301
+ for (const file of teamFiles) {
302
+ const destPath = join(REFLECTT_HOME, file.src);
303
+ const srcPath = join(defaultsDir, file.src);
304
+ if (existsSync(destPath) && !opts.force) {
305
+ filesSkipped++;
306
+ console.log(` ⏭️ ${file.src} (exists)`);
307
+ }
308
+ else if (existsSync(srcPath)) {
309
+ const content = readFileSync(srcPath, 'utf-8');
310
+ writeFileSync(destPath, content);
311
+ filesCreated++;
312
+ console.log(` ✅ ${file.src} — ${file.desc}`);
313
+ }
314
+ else {
315
+ console.log(` ⚠️ ${file.src} — default template not found`);
316
+ }
317
+ }
318
+ // Copy starter templates into ~/.reflectt/templates
319
+ const templatesSrcDir = join(__dirname, '..', 'templates');
320
+ const templatesDestDir = join(REFLECTT_HOME, 'templates');
321
+ mkdirSync(templatesDestDir, { recursive: true });
322
+ const templates = [
323
+ { src: 'task-template.md', desc: 'Task template' },
324
+ { src: 'review-packet.md', desc: 'Review packet template' },
325
+ { src: 'incident-template.md', desc: 'Incident template' },
326
+ ];
327
+ for (const file of templates) {
328
+ const destPath = join(templatesDestDir, file.src);
329
+ const srcPath = join(templatesSrcDir, file.src);
330
+ if (existsSync(destPath) && !opts.force) {
331
+ filesSkipped++;
332
+ console.log(` ⏭️ templates/${file.src} (exists)`);
333
+ }
334
+ else if (existsSync(srcPath)) {
335
+ const content = readFileSync(srcPath, 'utf-8');
336
+ writeFileSync(destPath, content);
337
+ filesCreated++;
338
+ console.log(` ✅ templates/${file.src} — ${file.desc}`);
339
+ }
340
+ else {
341
+ console.log(` ⚠️ templates/${file.src} — template not found in package`);
342
+ }
343
+ }
344
+ // Git init
345
+ if (opts.git !== false) {
346
+ const gitDir = join(REFLECTT_HOME, '.git');
347
+ if (!existsSync(gitDir)) {
348
+ try {
349
+ execSync('git init', { cwd: REFLECTT_HOME, stdio: 'pipe' });
350
+ execSync('git add -A', { cwd: REFLECTT_HOME, stdio: 'pipe' });
351
+ execSync('git commit -m "chore: initialize team ops directory"', {
352
+ cwd: REFLECTT_HOME,
353
+ stdio: 'pipe',
354
+ env: {
355
+ ...process.env,
356
+ GIT_AUTHOR_NAME: 'reflectt',
357
+ GIT_AUTHOR_EMAIL: 'init@reflectt.ai',
358
+ GIT_COMMITTER_NAME: 'reflectt',
359
+ GIT_COMMITTER_EMAIL: 'init@reflectt.ai',
360
+ },
361
+ });
362
+ console.log(' ✅ git repo initialized with initial commit');
363
+ }
364
+ catch (err) {
365
+ console.log(' ⚠️ git init failed (git may not be installed)');
366
+ }
367
+ }
368
+ else {
369
+ console.log(' ⏭️ .git (exists)');
370
+ }
371
+ }
372
+ console.log('');
373
+ if (isNew) {
374
+ console.log('🎉 Team ops directory initialized!');
375
+ }
376
+ else {
377
+ console.log(`✅ Init complete (${filesCreated} created, ${filesSkipped} existing)`);
378
+ }
379
+ console.log(` Home: ${REFLECTT_HOME}`);
380
+ console.log('');
381
+ console.log('Next steps:');
382
+ console.log(' 1. Edit TEAM.md with your team\'s mission and values');
383
+ console.log(' 2. Edit TEAM-ROLES.yaml with your agent roster');
384
+ console.log(' 3. Start the server: reflectt start');
385
+ });
386
+ // ============ START COMMAND ============
387
+ program
388
+ .command('start')
389
+ .description('Start the reflectt server')
390
+ .option('-d, --detach', 'Run in background')
391
+ .action(async (options) => {
392
+ if (!existsSync(REFLECTT_HOME)) {
393
+ console.error('❌ reflectt not initialized. Run: reflectt init');
394
+ process.exit(1);
395
+ }
396
+ // Check if already running
397
+ if (existsSync(PID_FILE)) {
398
+ const pid = readFileSync(PID_FILE, 'utf-8').trim();
399
+ try {
400
+ process.kill(Number(pid), 0); // Check if process exists
401
+ console.log(`⚠️ Server already running (PID: ${pid})`);
402
+ console.log(' Stop it first with: reflectt stop');
403
+ process.exit(1);
404
+ }
405
+ catch (err) {
406
+ // Process doesn't exist, clean up stale PID file
407
+ console.log('🧹 Cleaning up stale PID file...');
408
+ const { unlinkSync } = await import('fs');
409
+ unlinkSync(PID_FILE);
410
+ }
411
+ }
412
+ const config = loadConfig();
413
+ const { projectRoot, serverPath } = getRuntimePaths();
414
+ if (!existsSync(serverPath)) {
415
+ console.error(`❌ Server file not found: ${serverPath}`);
416
+ process.exit(1);
417
+ }
418
+ const env = buildServerEnv(config);
419
+ if (options.detach) {
420
+ const pid = startServerDetached(config);
421
+ console.log('✅ Server started in background');
422
+ console.log(` PID: ${pid}`);
423
+ console.log(` URL: http://${config.host}:${config.port}`);
424
+ console.log(` Dashboard: http://${config.host}:${config.port}/dashboard`);
425
+ if (config.cloud) {
426
+ console.log(` Cloud: ${config.cloud.cloudUrl} (host: ${config.cloud.hostName})`);
427
+ }
428
+ console.log('\nCheck status: reflectt status');
429
+ }
430
+ else {
431
+ // Foreground mode
432
+ console.log('🚀 Starting reflectt server...');
433
+ console.log(` URL: http://${config.host}:${config.port}`);
434
+ console.log(` Dashboard: http://${config.host}:${config.port}/dashboard`);
435
+ if (config.cloud) {
436
+ console.log(` Cloud: ${config.cloud.cloudUrl} (host: ${config.cloud.hostName})`);
437
+ }
438
+ console.log(' Press Ctrl+C to stop\n');
439
+ const child = spawn('npx', ['tsx', serverPath], {
440
+ env,
441
+ stdio: 'inherit',
442
+ cwd: projectRoot,
443
+ });
444
+ writeFileSync(PID_FILE, String(child.pid));
445
+ child.on('exit', (code) => {
446
+ if (existsSync(PID_FILE)) {
447
+ unlinkSync(PID_FILE);
448
+ }
449
+ process.exit(code || 0);
450
+ });
451
+ }
452
+ });
453
+ // ============ STOP COMMAND ============
454
+ program
455
+ .command('stop')
456
+ .description('Stop the reflectt server')
457
+ .action(() => {
458
+ if (!existsSync(PID_FILE)) {
459
+ console.log('⚠️ Server is not running');
460
+ process.exit(0);
461
+ }
462
+ const pid = readFileSync(PID_FILE, 'utf-8').trim();
463
+ try {
464
+ process.kill(Number(pid), 'SIGTERM');
465
+ console.log('✅ Server stopped');
466
+ unlinkSync(PID_FILE);
467
+ }
468
+ catch (err) {
469
+ if (err.code === 'ESRCH') {
470
+ console.log('⚠️ Process not found (already stopped?)');
471
+ unlinkSync(PID_FILE);
472
+ }
473
+ else {
474
+ console.error('❌ Failed to stop server:', err.message);
475
+ process.exit(1);
476
+ }
477
+ }
478
+ });
479
+ // ============ STATUS COMMAND ============
480
+ program
481
+ .command('status')
482
+ .description('Check server health and status')
483
+ .action(async () => {
484
+ const config = loadConfig();
485
+ // Check PID file
486
+ const isRunning = existsSync(PID_FILE);
487
+ const pid = isRunning ? readFileSync(PID_FILE, 'utf-8').trim() : null;
488
+ console.log('📊 reflectt Status');
489
+ console.log(` Config: ${CONFIG_PATH}`);
490
+ console.log(` URL: http://${config.host}:${config.port}`);
491
+ if (pid) {
492
+ try {
493
+ process.kill(Number(pid), 0); // Check if process exists
494
+ console.log(` Process: Running (PID: ${pid})`);
495
+ }
496
+ catch (err) {
497
+ console.log(` Process: Not found (stale PID file)`);
498
+ return;
499
+ }
500
+ }
501
+ else {
502
+ console.log(` Process: Not running`);
503
+ return;
504
+ }
505
+ // Try to get health status
506
+ try {
507
+ const health = await apiRequest('/health');
508
+ console.log('\n✅ Server Health');
509
+ console.log(` Status: ${health.status}`);
510
+ console.log(` Chat messages: ${health.chat?.messageCount || 0}`);
511
+ console.log(` Tasks: ${health.tasks?.taskCount || 0}`);
512
+ }
513
+ catch (err) {
514
+ console.log('\n⚠️ Server process exists but not responding');
515
+ }
516
+ });
517
+ // ============ DOCTOR COMMAND ============
518
+ program
519
+ .command('doctor')
520
+ .description('Run self-serve diagnostics (onboarding + support bundle)')
521
+ .option('--url <baseUrl>', 'Override base URL (default from ~/.reflectt/config.json)')
522
+ .option('--json', 'Print JSON output')
523
+ .option('--timeout <ms>', 'Per-request timeout in ms', '4000')
524
+ .action(async (options) => {
525
+ const config = loadConfig();
526
+ const clientHost = (config.host === '0.0.0.0' || config.host === '::') ? '127.0.0.1' : config.host;
527
+ const baseUrl = String(options.url || `http://${clientHost}:${config.port}`).replace(/\/+$/, '');
528
+ const timeoutMs = Math.max(250, Number(options.timeout || 4000));
529
+ const report = await collectDoctorReport({ baseUrl, timeoutMs });
530
+ if (options.json) {
531
+ console.log(JSON.stringify(report, null, 2));
532
+ if (report.overall === 'fail')
533
+ process.exit(2);
534
+ if (report.overall === 'warn')
535
+ process.exit(1);
536
+ return;
537
+ }
538
+ console.log(formatDoctorHuman(report));
539
+ if (report.overall === 'fail')
540
+ process.exit(2);
541
+ if (report.overall === 'warn')
542
+ process.exit(1);
543
+ });
544
+ // ============ CHAT COMMANDS ============
545
+ const chat = program.command('chat').description('Chat commands');
546
+ chat
547
+ .command('send')
548
+ .description('Send a message')
549
+ .requiredOption('--from <agent>', 'Sender agent name')
550
+ .requiredOption('--content <text>', 'Message content')
551
+ .option('--to <agent>', 'Recipient agent')
552
+ .option('--channel <name>', 'Channel name')
553
+ .option('--thread <id>', 'Thread ID to reply to')
554
+ .action(async (options) => {
555
+ const body = {
556
+ from: options.from,
557
+ content: options.content,
558
+ };
559
+ if (options.to)
560
+ body.to = options.to;
561
+ if (options.channel)
562
+ body.channel = options.channel;
563
+ if (options.thread)
564
+ body.threadId = options.thread;
565
+ const result = await apiRequest('/chat/messages', {
566
+ method: 'POST',
567
+ headers: { 'Content-Type': 'application/json' },
568
+ body: JSON.stringify(body),
569
+ });
570
+ console.log('✅ Message sent');
571
+ console.log(` ID: ${result.message.id}`);
572
+ console.log(` From: ${result.message.from}`);
573
+ if (result.message.channel)
574
+ console.log(` Channel: ${result.message.channel}`);
575
+ });
576
+ chat
577
+ .command('list')
578
+ .description('List messages')
579
+ .option('--channel <name>', 'Filter by channel')
580
+ .option('--from <agent>', 'Filter by sender')
581
+ .option('--to <agent>', 'Filter by recipient')
582
+ .option('--limit <n>', 'Maximum number of messages', '20')
583
+ .action(async (options) => {
584
+ const query = new URLSearchParams();
585
+ if (options.channel)
586
+ query.set('channel', options.channel);
587
+ if (options.from)
588
+ query.set('from', options.from);
589
+ if (options.to)
590
+ query.set('to', options.to);
591
+ if (options.limit)
592
+ query.set('limit', options.limit);
593
+ const result = await apiRequest(`/chat/messages?${query}`);
594
+ if (result.messages.length === 0) {
595
+ console.log('No messages found');
596
+ return;
597
+ }
598
+ console.log(`\n📬 Messages (${result.messages.length})\n`);
599
+ for (const msg of result.messages) {
600
+ const timestamp = new Date(msg.timestamp).toLocaleString();
601
+ const channel = msg.channel ? `[${msg.channel}]` : '';
602
+ console.log(`${timestamp} ${channel}`);
603
+ console.log(` ${msg.from} → ${msg.to || 'broadcast'}: ${msg.content}`);
604
+ console.log();
605
+ }
606
+ });
607
+ // ============ TASKS COMMANDS ============
608
+ const tasks = program.command('tasks').description('Task commands');
609
+ tasks
610
+ .command('list')
611
+ .description('List tasks')
612
+ .option('--status <status>', 'Filter by status (todo, doing, blocked, validating, done)')
613
+ .option('--assignee <agent>', 'Filter by assignee')
614
+ .option('--priority <p>', 'Filter by priority (P0, P1, P2, P3)')
615
+ .action(async (options) => {
616
+ const query = new URLSearchParams();
617
+ if (options.status)
618
+ query.set('status', options.status);
619
+ if (options.assignee)
620
+ query.set('assignee', options.assignee);
621
+ if (options.priority)
622
+ query.set('priority', options.priority);
623
+ const result = await apiRequest(`/tasks?${query}`);
624
+ if (result.tasks.length === 0) {
625
+ console.log('No tasks found');
626
+ return;
627
+ }
628
+ console.log(`\n📋 Tasks (${result.tasks.length})\n`);
629
+ for (const task of result.tasks) {
630
+ const status = task.status.toUpperCase().padEnd(10);
631
+ const priority = task.priority ? `[${task.priority}]` : '';
632
+ const assignee = task.assignee ? `→ ${task.assignee}` : '';
633
+ console.log(`${status} ${priority} ${task.title} ${assignee}`);
634
+ if (task.description) {
635
+ console.log(` ${task.description}`);
636
+ }
637
+ console.log();
638
+ }
639
+ });
640
+ tasks
641
+ .command('next')
642
+ .description('Get next available task')
643
+ .option('--agent <name>', 'Agent requesting the task')
644
+ .action(async (options) => {
645
+ const query = new URLSearchParams();
646
+ if (options.agent)
647
+ query.set('agent', options.agent);
648
+ const result = await apiRequest(`/tasks/next?${query}`);
649
+ if (!result.task) {
650
+ console.log('🎉 No tasks available!');
651
+ return;
652
+ }
653
+ const task = result.task;
654
+ console.log('\n📌 Next Task\n');
655
+ console.log(` ID: ${task.id}`);
656
+ console.log(` Title: ${task.title}`);
657
+ if (task.description)
658
+ console.log(` Description: ${task.description}`);
659
+ console.log(` Status: ${task.status}`);
660
+ if (task.priority)
661
+ console.log(` Priority: ${task.priority}`);
662
+ if (task.assignee)
663
+ console.log(` Assignee: ${task.assignee}`);
664
+ });
665
+ tasks
666
+ .command('create')
667
+ .description('Create a new task')
668
+ .requiredOption('--title <text>', 'Task title')
669
+ .requiredOption('--created-by <agent>', 'Agent creating the task')
670
+ .requiredOption('--assignee <agent>', 'Task owner/assignee')
671
+ .requiredOption('--reviewer <agent>', 'Task reviewer')
672
+ .requiredOption('--done-criteria <items...>', 'Done criteria (space-separated; quote each item)')
673
+ .requiredOption('--eta <text>', 'ETA (e.g., "30m" or "2026-02-15T18:00Z")')
674
+ .option('--description <text>', 'Task description')
675
+ .option('--status <status>', 'Initial status', 'todo')
676
+ .option('--priority <p>', 'Priority (P0, P1, P2, P3)')
677
+ .action(async (options) => {
678
+ const body = {
679
+ title: options.title,
680
+ createdBy: options.createdBy,
681
+ status: options.status,
682
+ assignee: options.assignee,
683
+ reviewer: options.reviewer,
684
+ done_criteria: options.doneCriteria,
685
+ eta: options.eta,
686
+ };
687
+ if (options.description)
688
+ body.description = options.description;
689
+ if (options.priority)
690
+ body.priority = options.priority;
691
+ const result = await apiRequest('/tasks', {
692
+ method: 'POST',
693
+ headers: { 'Content-Type': 'application/json' },
694
+ body: JSON.stringify(body),
695
+ });
696
+ console.log('✅ Task created');
697
+ console.log(` ID: ${result.task.id}`);
698
+ console.log(` Title: ${result.task.title}`);
699
+ console.log(` Status: ${result.task.status}`);
700
+ });
701
+ // ============ DOGFOOD COMMANDS ============
702
+ const dogfood = program.command('dogfood').description('Dogfood verification commands');
703
+ dogfood
704
+ .command('smoke')
705
+ .description('Run end-to-end cloud enrollment chain verification')
706
+ .requiredOption('--team-id <id>', 'Cloud team id to target')
707
+ .requiredOption('--token <jwt>', 'Bearer token for cloud API auth (team admin/owner)')
708
+ .option('--cloud-url <url>', 'Cloud API base URL', process.env.REFLECTT_CLOUD_URL || 'https://api.reflectt.ai')
709
+ .option('--dashboard-url <url>', 'Dashboard base URL', process.env.REFLECTT_APP_URL || 'https://app.reflectt.ai')
710
+ .option('--host-name <name>', 'Host name to register', `dogfood-${process.pid}`)
711
+ .option('--capability <value...>', 'Host capabilities', ['openclaw', 'dogfood-smoke'])
712
+ .action(async (options) => {
713
+ const cloudBase = String(options.cloudUrl || '').replace(/\/+$/, '');
714
+ const dashboardBase = String(options.dashboardUrl || '').replace(/\/+$/, '');
715
+ const teamId = String(options.teamId);
716
+ const token = String(options.token);
717
+ const hostName = String(options.hostName);
718
+ const capabilities = Array.isArray(options.capability) ? options.capability.map((v) => String(v).trim()).filter(Boolean) : ['openclaw'];
719
+ if (!cloudBase || !token || !teamId) {
720
+ console.error('❌ Missing required inputs: --cloud-url, --token, --team-id');
721
+ process.exit(1);
722
+ }
723
+ let failed = false;
724
+ let hostId = '';
725
+ console.log('🧪 Running dogfood smoke chain\n');
726
+ console.log(` Cloud API: ${cloudBase}`);
727
+ console.log(` Dashboard: ${dashboardBase}`);
728
+ console.log(` Team ID: ${teamId}`);
729
+ console.log(` Host Name: ${hostName}\n`);
730
+ // 1) register host token
731
+ const register = await cloudRequest(`${cloudBase}/api/hosts/register-token`, token, 'POST', { teamId });
732
+ const joinToken = register.json?.registerToken?.joinToken;
733
+ const registerOk = register.status === 201 && typeof joinToken === 'string' && joinToken.length > 0;
734
+ printStep('register host token', registerOk, registerOk ? 'join token issued' : `status ${register.status} ${(register.json?.error || '').toString()}`);
735
+ failed = failed || !registerOk;
736
+ // 2) claim host
737
+ let credential = '';
738
+ if (registerOk) {
739
+ const claim = await cloudRequest(`${cloudBase}/api/hosts/claim`, token, 'POST', {
740
+ joinToken,
741
+ name: hostName,
742
+ capabilities,
743
+ });
744
+ hostId = String(claim.json?.host?.id || '');
745
+ credential = String(claim.json?.credential?.token || '');
746
+ const claimOk = claim.status === 201 && Boolean(hostId);
747
+ printStep('claim host', claimOk, claimOk ? `hostId=${hostId}` : `status ${claim.status} ${(claim.json?.error || '').toString()}`);
748
+ failed = failed || !claimOk;
749
+ }
750
+ // 3) heartbeat
751
+ if (hostId) {
752
+ const heartbeat = await cloudRequest(`${cloudBase}/api/hosts/${encodeURIComponent(hostId)}/heartbeat`, token, 'POST', {
753
+ status: 'online',
754
+ agents: [{ id: 'dogfood-smoke', state: 'active' }],
755
+ activeTasks: [{ id: `smoke-${Date.now()}`, status: 'doing' }],
756
+ });
757
+ const heartbeatOk = heartbeat.status === 200 && String(heartbeat.json?.host?.status || '') === 'online';
758
+ printStep('heartbeat', heartbeatOk, heartbeatOk ? 'cloud accepted heartbeat' : `status ${heartbeat.status} ${(heartbeat.json?.error || '').toString()}`);
759
+ failed = failed || !heartbeatOk;
760
+ }
761
+ // 4) verify cloud state
762
+ let cloudHostSeen = false;
763
+ if (hostId) {
764
+ const verify = await cloudRequest(`${cloudBase}/api/hosts?teamId=${encodeURIComponent(teamId)}`, token, 'GET');
765
+ const hosts = Array.isArray(verify.json?.hosts) ? verify.json.hosts : [];
766
+ const match = hosts.find((h) => String(h?.id || '') === hostId);
767
+ cloudHostSeen = Boolean(match);
768
+ const verifyOk = verify.status === 200 && cloudHostSeen;
769
+ printStep('verify cloud state', verifyOk, verifyOk ? 'host visible in /api/hosts' : `status ${verify.status} host missing`);
770
+ failed = failed || !verifyOk;
771
+ }
772
+ // 5) verify dashboard reachability + data source alignment
773
+ if (hostId) {
774
+ const dashboardProbe = await fetch(`${dashboardBase}/dashboard/hosts`, { method: 'GET' })
775
+ .then((res) => ({ ok: res.status < 500, status: res.status }))
776
+ .catch(() => ({ ok: false, status: 0 }));
777
+ const dashboardOk = dashboardProbe.ok && cloudHostSeen;
778
+ printStep('verify dashboard reflection path', dashboardOk, dashboardOk
779
+ ? `dashboard reachable (HTTP ${dashboardProbe.status}); host present in dashboard source endpoint`
780
+ : `dashboard probe HTTP ${dashboardProbe.status}; or host missing from source endpoint`);
781
+ failed = failed || !dashboardOk;
782
+ }
783
+ console.log('');
784
+ if (failed) {
785
+ console.error('❌ Dogfood smoke FAILED');
786
+ process.exit(1);
787
+ }
788
+ console.log('✅ Dogfood smoke PASSED');
789
+ if (hostId) {
790
+ console.log(` hostId: ${hostId}`);
791
+ if (credential) {
792
+ console.log(' credential: issued (shown once)');
793
+ }
794
+ }
795
+ });
796
+ // ============ HOST COMMANDS ============
797
+ // ============ BOOTSTRAP (one-shot install + connect + start) ============
798
+ program
799
+ .command('bootstrap')
800
+ .description('One-shot setup: init + connect to cloud + start server (for npx/agent use)')
801
+ .option('--join-token <token>', 'Cloud host join token')
802
+ .option('--api-key <key>', 'Team API key (agent flow)')
803
+ .option('--cloud-url <url>', 'Cloud API base URL', 'https://api.reflectt.ai')
804
+ .option('--name <hostName>', 'Host display name', hostname())
805
+ .option('--type <hostType>', 'Host type', 'openclaw')
806
+ .action(async (options) => {
807
+ try {
808
+ if (!options.joinToken && !options.apiKey) {
809
+ console.error('❌ Either --join-token or --api-key is required');
810
+ console.error('');
811
+ console.error('Usage:');
812
+ console.error(' npx reflectt-node bootstrap --join-token <token>');
813
+ console.error(' npx reflectt-node bootstrap --api-key <key>');
814
+ process.exit(1);
815
+ }
816
+ // Step 0: Preflight checks
817
+ console.log('🔍 Preflight checks...');
818
+ try {
819
+ const { runPreflight, formatPreflightReport } = await import('./preflight.js');
820
+ const report = await runPreflight({
821
+ cloudUrl: options.cloudUrl,
822
+ joinToken: options.joinToken,
823
+ apiKey: options.apiKey,
824
+ });
825
+ console.log(formatPreflightReport(report));
826
+ console.log('');
827
+ if (!report.allPassed && report.firstBlocker) {
828
+ console.error(`❌ Preflight failed: ${report.firstBlocker.message}`);
829
+ console.error('');
830
+ console.error('Fix the issue above and retry.');
831
+ process.exit(1);
832
+ }
833
+ }
834
+ catch (err) {
835
+ console.log(' ⚠️ Preflight checks unavailable, proceeding...');
836
+ }
837
+ // Step 1: Init
838
+ console.log('📦 Step 1/3: Initializing reflectt home...');
839
+ ensureReflecttHome();
840
+ if (!existsSync(CONFIG_PATH)) {
841
+ saveConfig({ port: 4445, host: '127.0.0.1' });
842
+ }
843
+ console.log(` ✅ Home: ${REFLECTT_HOME}`);
844
+ // Step 2: Connect
845
+ console.log('☁️ Step 2/3: Connecting to Reflectt Cloud...');
846
+ const cloudUrl = String(options.cloudUrl || 'https://api.reflectt.ai').replace(/\/+$/, '');
847
+ const registered = options.apiKey
848
+ ? await enrollHostWithApiKey({
849
+ cloudUrl,
850
+ apiKey: options.apiKey,
851
+ hostName: options.name,
852
+ hostType: options.type,
853
+ })
854
+ : await registerHostWithCloud({
855
+ cloudUrl,
856
+ joinToken: options.joinToken,
857
+ hostName: options.name,
858
+ hostType: options.type,
859
+ });
860
+ const config = loadConfig();
861
+ const nextConfig = {
862
+ ...config,
863
+ cloud: {
864
+ cloudUrl,
865
+ hostName: options.name,
866
+ hostType: options.type,
867
+ hostId: registered.hostId,
868
+ credential: registered.credential,
869
+ connectedAt: Date.now(),
870
+ },
871
+ };
872
+ saveConfig(nextConfig);
873
+ console.log(` ✅ Registered (host: ${registered.hostId})`);
874
+ // Step 3: Start
875
+ console.log('🚀 Step 3/3: Starting reflectt server...');
876
+ if (isServerRunning()) {
877
+ console.log(' Server already running, reloading cloud config...');
878
+ const reloadResult = await tryApiRequest('/cloud/reload', { method: 'POST' });
879
+ if (reloadResult?.success) {
880
+ console.log(' ✅ Cloud config reloaded');
881
+ }
882
+ else {
883
+ console.log(' ⚠️ Reload failed, restarting...');
884
+ stopServerIfRunning();
885
+ startServerDetached(nextConfig);
886
+ }
887
+ }
888
+ else {
889
+ startServerDetached(nextConfig);
890
+ }
891
+ // Verify
892
+ const heartbeat = await waitForCloudHeartbeat();
893
+ if (heartbeat) {
894
+ const dashboardUrl = `http://127.0.0.1:${nextConfig?.port || 4445}/dashboard`;
895
+ console.log('');
896
+ console.log('✅ Bootstrap complete!');
897
+ console.log(` Host ID: ${registered.hostId}`);
898
+ console.log(` Cloud: ${cloudUrl}`);
899
+ console.log(` Heartbeats: ${heartbeat.heartbeatCount}`);
900
+ console.log('');
901
+ console.log('Your host is connected and reporting to Reflectt Cloud.');
902
+ console.log('');
903
+ console.log(`🖥️ Open your dashboard: ${dashboardUrl}`);
904
+ }
905
+ else {
906
+ const dashboardUrlTimeout = `http://127.0.0.1:${nextConfig?.port || 4445}/dashboard`;
907
+ console.log('');
908
+ console.log('⚠️ Bootstrap complete but heartbeat verification timed out.');
909
+ console.log(' Run `reflectt host status` to check.');
910
+ console.log('');
911
+ console.log(`🖥️ Open your dashboard: ${dashboardUrlTimeout}`);
912
+ process.exitCode = 1;
913
+ }
914
+ }
915
+ catch (err) {
916
+ console.error(`❌ Bootstrap failed: ${err?.message || err}`);
917
+ process.exit(1);
918
+ }
919
+ });
920
+ // ============ HOST COMMANDS ============
921
+ const host = program.command('host').description('Cloud host enrollment and status');
922
+ host
923
+ .command('connect')
924
+ .description('Enroll this reflectt-node host with Reflectt Cloud')
925
+ .option('--join-token <token>', 'Cloud host join token (from dashboard)')
926
+ .option('--api-key <key>', 'Team API key for agent-friendly enrollment (no browser needed)')
927
+ .option('--cloud-url <url>', 'Cloud API base URL', 'https://api.reflectt.ai')
928
+ .option('--name <hostName>', 'Host display name', hostname())
929
+ .option('--type <hostType>', 'Host type', 'openclaw')
930
+ .option('--auth-token <jwt>', 'Temporary user JWT for environments where claim endpoint is JWT-gated')
931
+ .option('--no-restart', 'Do not restart/start local reflectt server after enrollment')
932
+ .action(async (options) => {
933
+ try {
934
+ if (!options.joinToken && !options.apiKey) {
935
+ console.error('❌ Either --join-token or --api-key is required');
936
+ console.error(' --join-token <token> From dashboard (human flow)');
937
+ console.error(' --api-key <key> Team API key (agent flow)');
938
+ process.exit(1);
939
+ }
940
+ ensureReflecttHome();
941
+ const config = loadConfig();
942
+ const cloudUrl = String(options.cloudUrl || 'https://api.reflectt.ai').replace(/\/+$/, '');
943
+ console.log('☁️ Enrolling host with Reflectt Cloud...');
944
+ console.log(` Cloud: ${cloudUrl}`);
945
+ console.log(` Host: ${options.name} (${options.type})`);
946
+ console.log(` Method: ${options.apiKey ? 'API key' : 'join token'}`);
947
+ const registered = options.apiKey
948
+ ? await enrollHostWithApiKey({
949
+ cloudUrl,
950
+ apiKey: options.apiKey,
951
+ hostName: options.name,
952
+ hostType: options.type,
953
+ })
954
+ : await registerHostWithCloud({
955
+ cloudUrl,
956
+ joinToken: options.joinToken,
957
+ hostName: options.name,
958
+ hostType: options.type,
959
+ authToken: options.authToken,
960
+ });
961
+ const nextConfig = {
962
+ ...config,
963
+ cloud: {
964
+ cloudUrl,
965
+ hostName: options.name,
966
+ hostType: options.type,
967
+ hostId: registered.hostId,
968
+ credential: registered.credential,
969
+ connectedAt: Date.now(),
970
+ },
971
+ };
972
+ saveConfig(nextConfig);
973
+ console.log('✅ Cloud registration complete');
974
+ console.log(` Host ID: ${registered.hostId}`);
975
+ console.log(' Credential: received and stored in ~/.reflectt/config.json');
976
+ if (options.restart) {
977
+ if (isServerRunning()) {
978
+ // Try hot-reload first (avoids full restart)
979
+ console.log('🔄 Reloading cloud config on running server...');
980
+ const reloadResult = await tryApiRequest('/cloud/reload', { method: 'POST' });
981
+ if (reloadResult?.success) {
982
+ console.log('✅ Cloud config hot-reloaded');
983
+ const heartbeat = await waitForCloudHeartbeat();
984
+ if (heartbeat) {
985
+ console.log('✅ Heartbeat verified');
986
+ console.log(` Cloud host ID: ${heartbeat.hostId}`);
987
+ console.log(` Heartbeats sent: ${heartbeat.heartbeatCount}`);
988
+ }
989
+ else {
990
+ console.log('⚠️ Config reloaded, but heartbeat verification timed out');
991
+ console.log(' Check: reflectt host status');
992
+ process.exitCode = 1;
993
+ }
994
+ }
995
+ else {
996
+ // Fallback: full restart (older server without /cloud/reload)
997
+ console.log('⚠️ Hot-reload unavailable, falling back to full restart...');
998
+ stopServerIfRunning();
999
+ const pid = startServerDetached(nextConfig);
1000
+ console.log(` Server PID: ${pid}`);
1001
+ const heartbeat = await waitForCloudHeartbeat();
1002
+ if (heartbeat) {
1003
+ console.log('✅ Heartbeat verified');
1004
+ console.log(` Cloud host ID: ${heartbeat.hostId}`);
1005
+ console.log(` Heartbeats sent: ${heartbeat.heartbeatCount}`);
1006
+ }
1007
+ else {
1008
+ console.log('⚠️ Enrollment saved, but heartbeat verification timed out');
1009
+ console.log(' Check: reflectt status');
1010
+ console.log(' Check: reflectt host status');
1011
+ process.exitCode = 1;
1012
+ }
1013
+ }
1014
+ }
1015
+ else {
1016
+ console.log('🚀 Starting local reflectt server...');
1017
+ const pid = startServerDetached(nextConfig);
1018
+ console.log(` Server PID: ${pid}`);
1019
+ const heartbeat = await waitForCloudHeartbeat();
1020
+ if (heartbeat) {
1021
+ console.log('✅ Heartbeat verified');
1022
+ console.log(` Cloud host ID: ${heartbeat.hostId}`);
1023
+ console.log(` Heartbeats sent: ${heartbeat.heartbeatCount}`);
1024
+ }
1025
+ else {
1026
+ console.log('⚠️ Enrollment saved, but heartbeat verification timed out');
1027
+ console.log(' Check: reflectt status');
1028
+ console.log(' Check: reflectt host status');
1029
+ process.exitCode = 1;
1030
+ }
1031
+ }
1032
+ }
1033
+ else {
1034
+ console.log('ℹ️ Enrollment saved. Restart/start reflectt manually to begin heartbeats.');
1035
+ }
1036
+ }
1037
+ catch (err) {
1038
+ console.error(`❌ Host connect failed: ${err?.message || err}`);
1039
+ process.exit(1);
1040
+ }
1041
+ });
1042
+ host
1043
+ .command('status')
1044
+ .description('Show local host cloud enrollment + heartbeat status')
1045
+ .action(async () => {
1046
+ const config = loadConfig();
1047
+ if (!config.cloud) {
1048
+ console.log('Cloud enrollment not configured.');
1049
+ console.log('Run: reflectt host connect --join-token <token>');
1050
+ return;
1051
+ }
1052
+ console.log('☁️ Cloud Enrollment');
1053
+ console.log(` Cloud URL: ${config.cloud.cloudUrl}`);
1054
+ console.log(` Host ID: ${config.cloud.hostId}`);
1055
+ console.log(` Host Name: ${config.cloud.hostName}`);
1056
+ console.log(` Host Type: ${config.cloud.hostType}`);
1057
+ console.log(` Connected At: ${new Date(config.cloud.connectedAt).toLocaleString()}`);
1058
+ const status = await tryApiRequest('/cloud/status');
1059
+ if (!status) {
1060
+ console.log('\n⚠️ Local server not reachable (cloud runtime status unavailable)');
1061
+ return;
1062
+ }
1063
+ console.log('\n📡 Runtime Cloud Status');
1064
+ console.log(` Configured: ${status.configured ? 'yes' : 'no'}`);
1065
+ console.log(` Registered: ${status.registered ? 'yes' : 'no'}`);
1066
+ console.log(` Running: ${status.running ? 'yes' : 'no'}`);
1067
+ console.log(` Heartbeats: ${status.heartbeatCount || 0}`);
1068
+ if (status.lastHeartbeat) {
1069
+ console.log(` Last Heartbeat: ${new Date(status.lastHeartbeat).toLocaleString()}`);
1070
+ }
1071
+ if (status.errors) {
1072
+ console.log(` Errors: ${status.errors}`);
1073
+ }
1074
+ });
1075
+ // ============ MEMORY COMMANDS ============
1076
+ const memory = program.command('memory').description('Memory commands');
1077
+ memory
1078
+ .command('read')
1079
+ .description('Read memory for an agent')
1080
+ .argument('<agent>', 'Agent name')
1081
+ .action(async (agent) => {
1082
+ const result = await apiRequest(`/memory/${agent}`);
1083
+ if (!result.success) {
1084
+ console.error('❌', result.error);
1085
+ process.exit(1);
1086
+ }
1087
+ if (result.memories.length === 0) {
1088
+ console.log(`No memory files for agent: ${agent}`);
1089
+ return;
1090
+ }
1091
+ console.log(`\n🧠 Memory for ${agent} (${result.memories.length} files)\n`);
1092
+ for (const mem of result.memories) {
1093
+ console.log(`📄 ${mem.file}`);
1094
+ console.log(` Size: ${mem.size} bytes`);
1095
+ console.log(` Modified: ${new Date(mem.mtime).toLocaleString()}`);
1096
+ console.log();
1097
+ }
1098
+ });
1099
+ memory
1100
+ .command('write')
1101
+ .description('Append to daily memory file')
1102
+ .argument('<agent>', 'Agent name')
1103
+ .requiredOption('--content <text>', 'Content to append')
1104
+ .action(async (agent, options) => {
1105
+ const result = await apiRequest(`/memory/${agent}`, {
1106
+ method: 'POST',
1107
+ headers: { 'Content-Type': 'application/json' },
1108
+ body: JSON.stringify({ content: options.content }),
1109
+ });
1110
+ if (!result.success) {
1111
+ console.error('❌', result.error);
1112
+ process.exit(1);
1113
+ }
1114
+ console.log('✅ Memory written');
1115
+ console.log(` File: ${result.file}`);
1116
+ console.log(` Size: ${result.size} bytes`);
1117
+ });
1118
+ memory
1119
+ .command('search')
1120
+ .description('Search memory files')
1121
+ .argument('<agent>', 'Agent name')
1122
+ .requiredOption('--query <text>', 'Search query')
1123
+ .action(async (agent, options) => {
1124
+ const query = new URLSearchParams({ q: options.query });
1125
+ const result = await apiRequest(`/memory/${agent}/search?${query}`);
1126
+ if (!result.success) {
1127
+ console.error('❌', result.error);
1128
+ process.exit(1);
1129
+ }
1130
+ if (result.results.length === 0) {
1131
+ console.log('No matches found');
1132
+ return;
1133
+ }
1134
+ console.log(`\n🔍 Search Results (${result.count})\n`);
1135
+ for (const match of result.results) {
1136
+ console.log(`📄 ${match.file}`);
1137
+ console.log(` Line ${match.lineNumber}: ${match.line}`);
1138
+ console.log();
1139
+ }
1140
+ });
1141
+ program.parse();
1142
+ //# sourceMappingURL=cli.js.map