quoxcli 0.0.0-stage → 0.3.1

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 (516) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +144 -2
  3. package/bin/quox.js +265 -0
  4. package/bin/quoxon.js +8 -0
  5. package/lib/api/endpoints/admin.js +151 -0
  6. package/lib/api/endpoints/aee.js +38 -0
  7. package/lib/api/endpoints/agent-attach.js +126 -0
  8. package/lib/api/endpoints/agent-schedules.js +26 -0
  9. package/lib/api/endpoints/agents.js +63 -0
  10. package/lib/api/endpoints/assistants.js +62 -0
  11. package/lib/api/endpoints/audit.js +14 -0
  12. package/lib/api/endpoints/auth.js +50 -0
  13. package/lib/api/endpoints/awareness.js +34 -0
  14. package/lib/api/endpoints/away.js +15 -0
  15. package/lib/api/endpoints/backup-schedules.js +20 -0
  16. package/lib/api/endpoints/backups.js +86 -0
  17. package/lib/api/endpoints/brain.js +140 -0
  18. package/lib/api/endpoints/budgets.js +62 -0
  19. package/lib/api/endpoints/calendarq.js +71 -0
  20. package/lib/api/endpoints/catalog.js +14 -0
  21. package/lib/api/endpoints/chat.js +61 -0
  22. package/lib/api/endpoints/consent.js +26 -0
  23. package/lib/api/endpoints/contactsq.js +68 -0
  24. package/lib/api/endpoints/conversations.js +46 -0
  25. package/lib/api/endpoints/custom-roles.js +92 -0
  26. package/lib/api/endpoints/divisions.js +56 -0
  27. package/lib/api/endpoints/domains.js +38 -0
  28. package/lib/api/endpoints/engagement.js +231 -0
  29. package/lib/api/endpoints/engine.js +11 -0
  30. package/lib/api/endpoints/entity.js +50 -0
  31. package/lib/api/endpoints/executions.js +45 -0
  32. package/lib/api/endpoints/fetchAllowlist.js +27 -0
  33. package/lib/api/endpoints/file.js +20 -0
  34. package/lib/api/endpoints/files.js +40 -0
  35. package/lib/api/endpoints/github.js +21 -0
  36. package/lib/api/endpoints/governance.js +43 -0
  37. package/lib/api/endpoints/hat.js +66 -0
  38. package/lib/api/endpoints/inbox.js +52 -0
  39. package/lib/api/endpoints/inboxq.js +120 -0
  40. package/lib/api/endpoints/index.js +242 -0
  41. package/lib/api/endpoints/invites.js +19 -0
  42. package/lib/api/endpoints/llm-policy.js +43 -0
  43. package/lib/api/endpoints/lucid.js +89 -0
  44. package/lib/api/endpoints/members.js +32 -0
  45. package/lib/api/endpoints/memory.js +94 -0
  46. package/lib/api/endpoints/mfa.js +32 -0
  47. package/lib/api/endpoints/mind.js +13 -0
  48. package/lib/api/endpoints/mon.js +184 -0
  49. package/lib/api/endpoints/notesq.js +43 -0
  50. package/lib/api/endpoints/objectives.js +68 -0
  51. package/lib/api/endpoints/orgs.js +38 -0
  52. package/lib/api/endpoints/plugins.js +152 -0
  53. package/lib/api/endpoints/powers.js +75 -0
  54. package/lib/api/endpoints/presence.js +33 -0
  55. package/lib/api/endpoints/prompts.js +69 -0
  56. package/lib/api/endpoints/qlarity.js +122 -0
  57. package/lib/api/endpoints/quoxbox.js +55 -0
  58. package/lib/api/endpoints/quoxchat.js +54 -0
  59. package/lib/api/endpoints/quoxflow.js +32 -0
  60. package/lib/api/endpoints/quoxplan.js +121 -0
  61. package/lib/api/endpoints/quoxseo.js +114 -0
  62. package/lib/api/endpoints/reach.js +47 -0
  63. package/lib/api/endpoints/router.js +17 -0
  64. package/lib/api/endpoints/runs.js +38 -0
  65. package/lib/api/endpoints/safety.js +53 -0
  66. package/lib/api/endpoints/scim.js +46 -0
  67. package/lib/api/endpoints/scopes.js +14 -0
  68. package/lib/api/endpoints/security.js +69 -0
  69. package/lib/api/endpoints/setup.js +90 -0
  70. package/lib/api/endpoints/skills.js +200 -0
  71. package/lib/api/endpoints/sso.js +67 -0
  72. package/lib/api/endpoints/stepup.js +20 -0
  73. package/lib/api/endpoints/tags.js +32 -0
  74. package/lib/api/endpoints/teams.js +56 -0
  75. package/lib/api/endpoints/telephony.js +46 -0
  76. package/lib/api/endpoints/tg.js +56 -0
  77. package/lib/api/endpoints/tools.js +50 -0
  78. package/lib/api/endpoints/traces.js +157 -0
  79. package/lib/api/endpoints/triggers.js +96 -0
  80. package/lib/api/endpoints/user-library.js +41 -0
  81. package/lib/api/endpoints/users.js +20 -0
  82. package/lib/api/endpoints/v1.js +585 -0
  83. package/lib/api/endpoints/vault.js +192 -0
  84. package/lib/api/endpoints/voice.js +22 -0
  85. package/lib/api/endpoints/volt.js +84 -0
  86. package/lib/api/endpoints/ward.js +47 -0
  87. package/lib/api/endpoints/webhooks.js +46 -0
  88. package/lib/api/endpoints/workflows.js +169 -0
  89. package/lib/api/endpoints/x.js +32 -0
  90. package/lib/api/endpoints.js +15 -0
  91. package/lib/commands/actions.js +61 -0
  92. package/lib/commands/admin.js +375 -0
  93. package/lib/commands/aee.js +99 -0
  94. package/lib/commands/agent.js +337 -0
  95. package/lib/commands/agentAttach.js +1528 -0
  96. package/lib/commands/approvals.js +119 -0
  97. package/lib/commands/aside.js +24 -0
  98. package/lib/commands/ask.js +144 -0
  99. package/lib/commands/assistant.js +169 -0
  100. package/lib/commands/auth.js +464 -0
  101. package/lib/commands/awareness.js +88 -0
  102. package/lib/commands/backup.js +377 -0
  103. package/lib/commands/brain.js +1085 -0
  104. package/lib/commands/budget.js +241 -0
  105. package/lib/commands/build.js +170 -0
  106. package/lib/commands/calendar.js +216 -0
  107. package/lib/commands/capabilities.js +34 -0
  108. package/lib/commands/chat.js +295 -0
  109. package/lib/commands/claude.js +380 -0
  110. package/lib/commands/config-cmd.js +106 -0
  111. package/lib/commands/consent.js +84 -0
  112. package/lib/commands/contacts.js +1016 -0
  113. package/lib/commands/contactsSelftest.js +132 -0
  114. package/lib/commands/conversation.js +105 -0
  115. package/lib/commands/dashboard.js +43 -0
  116. package/lib/commands/department.js +96 -0
  117. package/lib/commands/dev.js +620 -0
  118. package/lib/commands/devResident.js +326 -0
  119. package/lib/commands/devSupervisor.js +1062 -0
  120. package/lib/commands/discord.js +132 -0
  121. package/lib/commands/doctor.js +181 -0
  122. package/lib/commands/domain.js +114 -0
  123. package/lib/commands/done.js +347 -0
  124. package/lib/commands/engagement.js +597 -0
  125. package/lib/commands/entity.js +119 -0
  126. package/lib/commands/facebook.js +212 -0
  127. package/lib/commands/fetchAllowlist.js +71 -0
  128. package/lib/commands/file.js +165 -0
  129. package/lib/commands/fleet.js +1189 -0
  130. package/lib/commands/governance.js +647 -0
  131. package/lib/commands/gripe.js +355 -0
  132. package/lib/commands/hat.js +374 -0
  133. package/lib/commands/helpers.js +96 -0
  134. package/lib/commands/hyperion.js +58 -0
  135. package/lib/commands/inbox.js +173 -0
  136. package/lib/commands/instagram.js +264 -0
  137. package/lib/commands/integration.js +100 -0
  138. package/lib/commands/inventory.js +115 -0
  139. package/lib/commands/invites.js +45 -0
  140. package/lib/commands/licence.js +139 -0
  141. package/lib/commands/linkedin.js +178 -0
  142. package/lib/commands/llm-policy.js +117 -0
  143. package/lib/commands/llm.js +45 -0
  144. package/lib/commands/lucid.js +597 -0
  145. package/lib/commands/mail.js +531 -0
  146. package/lib/commands/memory.js +361 -0
  147. package/lib/commands/mind.js +71 -0
  148. package/lib/commands/mon.js +581 -0
  149. package/lib/commands/monitoring.js +86 -0
  150. package/lib/commands/motion.js +22 -0
  151. package/lib/commands/notes.js +1246 -0
  152. package/lib/commands/notesBatch.js +160 -0
  153. package/lib/commands/notesBridges.js +56 -0
  154. package/lib/commands/notesLinks.js +60 -0
  155. package/lib/commands/notification.js +57 -0
  156. package/lib/commands/nucleus.js +123 -0
  157. package/lib/commands/objective.js +240 -0
  158. package/lib/commands/offload.js +89 -0
  159. package/lib/commands/onboard.js +329 -0
  160. package/lib/commands/open.js +56 -0
  161. package/lib/commands/org.js +276 -0
  162. package/lib/commands/peek.js +28 -0
  163. package/lib/commands/plan.js +944 -0
  164. package/lib/commands/plugin-doctor.js +1091 -0
  165. package/lib/commands/plugin.js +649 -0
  166. package/lib/commands/policy.js +78 -0
  167. package/lib/commands/powers.js +296 -0
  168. package/lib/commands/presence.js +89 -0
  169. package/lib/commands/prompt.js +350 -0
  170. package/lib/commands/provider.js +159 -0
  171. package/lib/commands/qlarity.js +706 -0
  172. package/lib/commands/quoxbox.js +270 -0
  173. package/lib/commands/quoxchat.js +275 -0
  174. package/lib/commands/quoxseo.js +378 -0
  175. package/lib/commands/reach.js +159 -0
  176. package/lib/commands/role.js +286 -0
  177. package/lib/commands/router.js +77 -0
  178. package/lib/commands/rows.js +358 -0
  179. package/lib/commands/run.js +187 -0
  180. package/lib/commands/safety.js +107 -0
  181. package/lib/commands/scim.js +88 -0
  182. package/lib/commands/scope.js +58 -0
  183. package/lib/commands/security.js +157 -0
  184. package/lib/commands/server.js +292 -0
  185. package/lib/commands/service.js +89 -0
  186. package/lib/commands/settings.js +99 -0
  187. package/lib/commands/setup.js +569 -0
  188. package/lib/commands/skillManifest.js +113 -0
  189. package/lib/commands/skillRightsFormat.js +38 -0
  190. package/lib/commands/skills.js +687 -0
  191. package/lib/commands/slot.js +1451 -0
  192. package/lib/commands/sso.js +229 -0
  193. package/lib/commands/status.js +137 -0
  194. package/lib/commands/tag.js +91 -0
  195. package/lib/commands/team.js +142 -0
  196. package/lib/commands/tg.js +240 -0
  197. package/lib/commands/tiktok.js +218 -0
  198. package/lib/commands/tips.js +23 -0
  199. package/lib/commands/tool.js +304 -0
  200. package/lib/commands/trace.js +530 -0
  201. package/lib/commands/trigger.js +223 -0
  202. package/lib/commands/update.js +46 -0
  203. package/lib/commands/vault.js +1447 -0
  204. package/lib/commands/vm.js +237 -0
  205. package/lib/commands/voice.js +213 -0
  206. package/lib/commands/volt.js +570 -0
  207. package/lib/commands/walkthrough.js +32 -0
  208. package/lib/commands/watch.js +167 -0
  209. package/lib/commands/webhook.js +137 -0
  210. package/lib/commands/welcome.js +14 -0
  211. package/lib/commands/workflow.js +660 -0
  212. package/lib/commands/x.js +448 -0
  213. package/lib/core/actingAs.js +136 -0
  214. package/lib/core/activeSummary.js +186 -0
  215. package/lib/core/aee.js +53 -0
  216. package/lib/core/agentAlias.js +163 -0
  217. package/lib/core/approvalContext.js +61 -0
  218. package/lib/core/aside.js +54 -0
  219. package/lib/core/askDecision.js +60 -0
  220. package/lib/core/auth.js +501 -0
  221. package/lib/core/banner.js +143 -0
  222. package/lib/core/brainPrime.js +90 -0
  223. package/lib/core/callerSource.js +129 -0
  224. package/lib/core/claudeLs.js +94 -0
  225. package/lib/core/cliBuild.js +62 -0
  226. package/lib/core/client.js +693 -0
  227. package/lib/core/commandRegistrars.js +121 -0
  228. package/lib/core/completions.js +163 -0
  229. package/lib/core/config.js +669 -0
  230. package/lib/core/confirm.js +37 -0
  231. package/lib/core/customHats.js +168 -0
  232. package/lib/core/deeplinks.js +76 -0
  233. package/lib/core/doneEngineFetch.js +227 -0
  234. package/lib/core/errors.js +441 -0
  235. package/lib/core/global-flags.js +190 -0
  236. package/lib/core/governedSession.js +402 -0
  237. package/lib/core/hyperion.js +102 -0
  238. package/lib/core/inboxResolution.js +65 -0
  239. package/lib/core/lazyCommands.js +122 -0
  240. package/lib/core/liveSessionsReport.js +112 -0
  241. package/lib/core/offload.js +504 -0
  242. package/lib/core/org-override.js +52 -0
  243. package/lib/core/orgResolve.js +70 -0
  244. package/lib/core/output.js +239 -0
  245. package/lib/core/peek.js +126 -0
  246. package/lib/core/prodEnv.js +7 -0
  247. package/lib/core/profileUsers.js +51 -0
  248. package/lib/core/promptCancel.js +18 -0
  249. package/lib/core/quoxglyph.js +158 -0
  250. package/lib/core/repoPath.js +11 -0
  251. package/lib/core/residentAlarm.js +282 -0
  252. package/lib/core/residentAuth.js +243 -0
  253. package/lib/core/residentPump.js +229 -0
  254. package/lib/core/residentSeed.js +106 -0
  255. package/lib/core/rootOptions.js +39 -0
  256. package/lib/core/router.js +168 -0
  257. package/lib/core/selfUpdate.js +188 -0
  258. package/lib/core/sessionHeartbeat.js +192 -0
  259. package/lib/core/sessionsOverview.js +224 -0
  260. package/lib/core/slotKeeper.js +527 -0
  261. package/lib/core/slotWake.js +120 -0
  262. package/lib/core/supervisorEngine.js +933 -0
  263. package/lib/core/systemdInstaller.js +256 -0
  264. package/lib/core/version.js +87 -0
  265. package/lib/core/vm.js +361 -0
  266. package/lib/core/vmTui.js +86 -0
  267. package/lib/core/walkthrough.js +35 -0
  268. package/lib/hyperion/deck.js +29 -0
  269. package/lib/lucid/LucidCard.jsx +68 -0
  270. package/lib/lucid/LucidIntro.jsx +92 -0
  271. package/lib/lucid/blind.js +71 -0
  272. package/lib/lucid/cards.js +86 -0
  273. package/lib/lucid/deck.js +32 -0
  274. package/lib/lucid/fmt.js +139 -0
  275. package/lib/lucid/markdown.js +81 -0
  276. package/lib/lucid/motion.js +56 -0
  277. package/lib/lucid/sitrep.js +173 -0
  278. package/lib/plugins/loader.js +93 -0
  279. package/lib/quoxon/activity.js +116 -0
  280. package/lib/quoxon/aocl.js +117 -0
  281. package/lib/quoxon/api.js +952 -0
  282. package/lib/quoxon/app.js +4032 -0
  283. package/lib/quoxon/approvalFacts.js +94 -0
  284. package/lib/quoxon/approvalsView.js +325 -0
  285. package/lib/quoxon/asideView.js +40 -0
  286. package/lib/quoxon/ask.js +121 -0
  287. package/lib/quoxon/away.js +52 -0
  288. package/lib/quoxon/bang.js +224 -0
  289. package/lib/quoxon/bulkRisk.js +17 -0
  290. package/lib/quoxon/capabilities.js +82 -0
  291. package/lib/quoxon/cells.js +53 -0
  292. package/lib/quoxon/commandShort.js +112 -0
  293. package/lib/quoxon/commands.js +479 -0
  294. package/lib/quoxon/connect.js +654 -0
  295. package/lib/quoxon/connectCard.js +45 -0
  296. package/lib/quoxon/consent.js +86 -0
  297. package/lib/quoxon/context.js +68 -0
  298. package/lib/quoxon/copy.js +34 -0
  299. package/lib/quoxon/countdownLine.js +11 -0
  300. package/lib/quoxon/demo.autoplay.js +29 -0
  301. package/lib/quoxon/demo.fixtures.js +24 -0
  302. package/lib/quoxon/demo.js +76 -0
  303. package/lib/quoxon/devObserver.js +20 -0
  304. package/lib/quoxon/dividerAocl.js +191 -0
  305. package/lib/quoxon/dividerRule.js +57 -0
  306. package/lib/quoxon/dragonModes.js +150 -0
  307. package/lib/quoxon/dragonView.js +41 -0
  308. package/lib/quoxon/earlyInput.js +40 -0
  309. package/lib/quoxon/echo.js +15 -0
  310. package/lib/quoxon/egg.js +36 -0
  311. package/lib/quoxon/events.js +677 -0
  312. package/lib/quoxon/feedback.js +50 -0
  313. package/lib/quoxon/gallery.js +237 -0
  314. package/lib/quoxon/handoffOffer.js +78 -0
  315. package/lib/quoxon/hatSwitch.js +37 -0
  316. package/lib/quoxon/headless.js +161 -0
  317. package/lib/quoxon/hostUrls.js +41 -0
  318. package/lib/quoxon/indicator.js +197 -0
  319. package/lib/quoxon/intent.js +52 -0
  320. package/lib/quoxon/keys.js +164 -0
  321. package/lib/quoxon/launcher.js +103 -0
  322. package/lib/quoxon/main.js +176 -0
  323. package/lib/quoxon/markdown.js +341 -0
  324. package/lib/quoxon/markdownSettle.js +19 -0
  325. package/lib/quoxon/matrixDomains.json +46 -0
  326. package/lib/quoxon/mentions.js +90 -0
  327. package/lib/quoxon/mind.js +103 -0
  328. package/lib/quoxon/mode.js +46 -0
  329. package/lib/quoxon/model.js +311 -0
  330. package/lib/quoxon/modelPrefs.js +345 -0
  331. package/lib/quoxon/motion/clock.js +70 -0
  332. package/lib/quoxon/motion/color.js +35 -0
  333. package/lib/quoxon/motion/frame.js +14 -0
  334. package/lib/quoxon/motion/level.js +91 -0
  335. package/lib/quoxon/motion/reveal.js +54 -0
  336. package/lib/quoxon/motion/ring.js +79 -0
  337. package/lib/quoxon/mouse.js +211 -0
  338. package/lib/quoxon/noai.js +57 -0
  339. package/lib/quoxon/objects/agent.js +61 -0
  340. package/lib/quoxon/objects/away.js +72 -0
  341. package/lib/quoxon/objects/crystal.js +100 -0
  342. package/lib/quoxon/objects/fetch.js +182 -0
  343. package/lib/quoxon/objects/fleet.js +149 -0
  344. package/lib/quoxon/objects/health.js +186 -0
  345. package/lib/quoxon/objects/index.js +106 -0
  346. package/lib/quoxon/objects/ladder.js +71 -0
  347. package/lib/quoxon/objects/memory.js +44 -0
  348. package/lib/quoxon/objects/mirror.js +137 -0
  349. package/lib/quoxon/objects/model.js +118 -0
  350. package/lib/quoxon/objects/peek.js +17 -0
  351. package/lib/quoxon/objects/proof.js +110 -0
  352. package/lib/quoxon/objects/prove.js +130 -0
  353. package/lib/quoxon/objects/replay.js +125 -0
  354. package/lib/quoxon/objects/sitrep.js +58 -0
  355. package/lib/quoxon/objects/skill.js +105 -0
  356. package/lib/quoxon/objects/view.js +87 -0
  357. package/lib/quoxon/objects/workflow.js +119 -0
  358. package/lib/quoxon/observers.js +42 -0
  359. package/lib/quoxon/onboarding/copy.js +263 -0
  360. package/lib/quoxon/onboarding/credential.js +108 -0
  361. package/lib/quoxon/onboarding/detect.js +22 -0
  362. package/lib/quoxon/onboarding/dockerOffer.js +45 -0
  363. package/lib/quoxon/onboarding/failureCause.js +33 -0
  364. package/lib/quoxon/onboarding/finish.js +134 -0
  365. package/lib/quoxon/onboarding/index.js +94 -0
  366. package/lib/quoxon/onboarding/installRunner.js +284 -0
  367. package/lib/quoxon/onboarding/intent.js +53 -0
  368. package/lib/quoxon/onboarding/journey.js +73 -0
  369. package/lib/quoxon/onboarding/preflight.js +156 -0
  370. package/lib/quoxon/onboarding/probe.js +65 -0
  371. package/lib/quoxon/onboarding/runner.js +58 -0
  372. package/lib/quoxon/onboarding/view.js +682 -0
  373. package/lib/quoxon/orgLabel.js +10 -0
  374. package/lib/quoxon/orgSwitch.js +33 -0
  375. package/lib/quoxon/ownBroadcast.js +22 -0
  376. package/lib/quoxon/palette.js +43 -0
  377. package/lib/quoxon/print.js +98 -0
  378. package/lib/quoxon/profileSwitch.js +53 -0
  379. package/lib/quoxon/promptHistory.js +41 -0
  380. package/lib/quoxon/providers.js +48 -0
  381. package/lib/quoxon/qart.js +348 -0
  382. package/lib/quoxon/qdragon.js +410 -0
  383. package/lib/quoxon/qdragonFly.js +61 -0
  384. package/lib/quoxon/qdragonScenes.js +282 -0
  385. package/lib/quoxon/qeyes.js +213 -0
  386. package/lib/quoxon/qglyph.js +143 -0
  387. package/lib/quoxon/qhello.js +58 -0
  388. package/lib/quoxon/qmotion.js +132 -0
  389. package/lib/quoxon/render.js +1167 -0
  390. package/lib/quoxon/resend.js +72 -0
  391. package/lib/quoxon/roster.js +307 -0
  392. package/lib/quoxon/route.js +39 -0
  393. package/lib/quoxon/rows.js +711 -0
  394. package/lib/quoxon/rowsStore.js +80 -0
  395. package/lib/quoxon/rules.js +130 -0
  396. package/lib/quoxon/screenContext.js +150 -0
  397. package/lib/quoxon/screenFrames.js +254 -0
  398. package/lib/quoxon/session.js +238 -0
  399. package/lib/quoxon/sessionDead.js +17 -0
  400. package/lib/quoxon/signin.js +125 -0
  401. package/lib/quoxon/skills.js +30 -0
  402. package/lib/quoxon/slash/agents.js +112 -0
  403. package/lib/quoxon/slash/argSources.js +65 -0
  404. package/lib/quoxon/slash/args.js +65 -0
  405. package/lib/quoxon/slash/automate.js +89 -0
  406. package/lib/quoxon/slash/broadcast.js +140 -0
  407. package/lib/quoxon/slash/broadcastRun.js +108 -0
  408. package/lib/quoxon/slash/card.js +30 -0
  409. package/lib/quoxon/slash/challenge.js +114 -0
  410. package/lib/quoxon/slash/cliCommand.js +53 -0
  411. package/lib/quoxon/slash/cliLeaves.json +948 -0
  412. package/lib/quoxon/slash/compact.js +90 -0
  413. package/lib/quoxon/slash/confirm.js +30 -0
  414. package/lib/quoxon/slash/crystallize.js +69 -0
  415. package/lib/quoxon/slash/dashboard.js +136 -0
  416. package/lib/quoxon/slash/draft.js +54 -0
  417. package/lib/quoxon/slash/hatWalk.js +206 -0
  418. package/lib/quoxon/slash/inverses.js +77 -0
  419. package/lib/quoxon/slash/killer.js +24 -0
  420. package/lib/quoxon/slash/killerApi.js +16 -0
  421. package/lib/quoxon/slash/ledger.js +88 -0
  422. package/lib/quoxon/slash/listView.js +30 -0
  423. package/lib/quoxon/slash/modelCmd.js +261 -0
  424. package/lib/quoxon/slash/palette.js +118 -0
  425. package/lib/quoxon/slash/paletteController.js +169 -0
  426. package/lib/quoxon/slash/panels.js +116 -0
  427. package/lib/quoxon/slash/picker.js +56 -0
  428. package/lib/quoxon/slash/restart.js +202 -0
  429. package/lib/quoxon/slash/resume.js +59 -0
  430. package/lib/quoxon/slash/rowCmd.js +157 -0
  431. package/lib/quoxon/slash/rowWalk.js +175 -0
  432. package/lib/quoxon/slash/settings.js +60 -0
  433. package/lib/quoxon/slash/spawn.js +177 -0
  434. package/lib/quoxon/slash/stepUp.js +274 -0
  435. package/lib/quoxon/slash/stepUpCard.js +60 -0
  436. package/lib/quoxon/slash/stepUpCmds.js +78 -0
  437. package/lib/quoxon/slash/undoApi.js +38 -0
  438. package/lib/quoxon/slash/undoCmd.js +49 -0
  439. package/lib/quoxon/slash/undoWish.js +15 -0
  440. package/lib/quoxon/slash/watch.js +164 -0
  441. package/lib/quoxon/slash/wish.js +23 -0
  442. package/lib/quoxon/slash/wishCmd.js +32 -0
  443. package/lib/quoxon/slotChat.js +300 -0
  444. package/lib/quoxon/slotFormat.js +195 -0
  445. package/lib/quoxon/slotRun.js +131 -0
  446. package/lib/quoxon/sound/index.js +186 -0
  447. package/lib/quoxon/sound/mapping.js +120 -0
  448. package/lib/quoxon/sound/output.js +52 -0
  449. package/lib/quoxon/sound/synth.js +122 -0
  450. package/lib/quoxon/stray.js +22 -0
  451. package/lib/quoxon/suggestCommand.js +59 -0
  452. package/lib/quoxon/term.js +141 -0
  453. package/lib/quoxon/textBuffer.js +416 -0
  454. package/lib/quoxon/theme.js +286 -0
  455. package/lib/quoxon/tips.js +433 -0
  456. package/lib/quoxon/toolError.js +41 -0
  457. package/lib/quoxon/transcript.js +188 -0
  458. package/lib/quoxon/web/qface.js +89 -0
  459. package/lib/quoxon/welcome.js +52 -0
  460. package/lib/quoxon/whatsnew.js +136 -0
  461. package/lib/quoxon/whatsnew.jsonl +89 -0
  462. package/lib/quoxon/windowOrg.js +113 -0
  463. package/lib/server/diag.js +129 -0
  464. package/lib/server/doctor.js +71 -0
  465. package/lib/server/install.js +149 -0
  466. package/lib/server/pluginEnable.js +161 -0
  467. package/lib/server/skew.js +56 -0
  468. package/lib/server/snapshot.js +131 -0
  469. package/lib/server/status.js +128 -0
  470. package/lib/server/sys.js +65 -0
  471. package/lib/server/uninstall.js +63 -0
  472. package/lib/server/update.js +234 -0
  473. package/lib/toolOutputShape.js +315 -0
  474. package/lib/tui/app.jsx +289 -0
  475. package/lib/tui/components/Breadcrumb.jsx +42 -0
  476. package/lib/tui/components/ChatInput.jsx +68 -0
  477. package/lib/tui/components/Confirm.jsx +32 -0
  478. package/lib/tui/components/DataTable.jsx +270 -0
  479. package/lib/tui/components/DetailPanel.jsx +241 -0
  480. package/lib/tui/components/HelpOverlay.jsx +67 -0
  481. package/lib/tui/components/Layout.jsx +129 -0
  482. package/lib/tui/components/Palette.jsx +141 -0
  483. package/lib/tui/components/SearchInput.jsx +125 -0
  484. package/lib/tui/components/Sparkline.jsx +55 -0
  485. package/lib/tui/components/StatusBar.jsx +133 -0
  486. package/lib/tui/components/Toast.jsx +52 -0
  487. package/lib/tui/hooks/useApi.js +44 -0
  488. package/lib/tui/hooks/useHealth.js +90 -0
  489. package/lib/tui/hooks/usePolledApi.js +86 -0
  490. package/lib/tui/hooks/useTerminalSize.js +46 -0
  491. package/lib/tui/index.js +56 -0
  492. package/lib/tui/intro/Intro.jsx +332 -0
  493. package/lib/tui/jsx-loader.js +32 -0
  494. package/lib/tui/keys.js +87 -0
  495. package/lib/tui/registry.js +49 -0
  496. package/lib/tui/theme.js +103 -0
  497. package/lib/tui/views/AdminView.jsx +398 -0
  498. package/lib/tui/views/AgentView.jsx +204 -0
  499. package/lib/tui/views/BackupView.jsx +225 -0
  500. package/lib/tui/views/BrainView.jsx +223 -0
  501. package/lib/tui/views/ChatView.jsx +468 -0
  502. package/lib/tui/views/FilesView.jsx +218 -0
  503. package/lib/tui/views/FleetView.jsx +234 -0
  504. package/lib/tui/views/GovernanceView.jsx +453 -0
  505. package/lib/tui/views/HealthView.jsx +216 -0
  506. package/lib/tui/views/HyperionDeck.jsx +79 -0
  507. package/lib/tui/views/InboxView.jsx +228 -0
  508. package/lib/tui/views/LucidDeck.jsx +719 -0
  509. package/lib/tui/views/MainMenu.jsx +123 -0
  510. package/lib/tui/views/MemoryView.jsx +377 -0
  511. package/lib/tui/views/ObjectivesView.jsx +230 -0
  512. package/lib/tui/views/OrgView.jsx +229 -0
  513. package/lib/tui/views/ToolView.jsx +221 -0
  514. package/lib/tui/views/VaultView.jsx +422 -0
  515. package/lib/tui/views/WorkflowView.jsx +329 -0
  516. package/package.json +75 -4
@@ -0,0 +1,570 @@
1
+ /**
2
+ * VOLT commands: verify evidence bundles, inspect chains, export reports
3
+ *
4
+ * quox volt <subcommand> [options]
5
+ *
6
+ * Works with VOLT evidence bundle files (JSON) and raw NDJSON chain exports.
7
+ */
8
+
9
+ import chalk from 'chalk';
10
+ import { readFile, writeFile } from 'fs/promises';
11
+ import { printSuccess, printWarning, printInfo, formatDetail } from '../core/output.js';
12
+ import { resolveEndpoint } from '../api/endpoints.js';
13
+
14
+ /**
15
+ * Peel a fetched VOLT payload down to the verifiable bundle shape
16
+ * ({ manifest, events_ndjson?, signature? }), not the storage row around it.
17
+ * `/volt/runs/:runId/bundle` returns { bundle: <db row> } with the actual
18
+ * bundle nested in `row.data`; `/volt/bundles/:bundleId/download` returns the
19
+ * bundle directly. Shared by `volt fetch` for both the initial fetch and the
20
+ * follow-up download after `volt.bundle.create` (fleet #447).
21
+ */
22
+ function unwrapVoltBundle(data) {
23
+ let bundle = (data && data.bundle) ? data.bundle : data;
24
+ if (bundle && bundle.data && typeof bundle.data === 'object' && bundle.data.manifest) {
25
+ bundle = bundle.data;
26
+ }
27
+ return bundle;
28
+ }
29
+
30
+ /**
31
+ * quox#935: a bundle is ONE JSON object carrying `manifest` and/or
32
+ * `events_ndjson`. An events NDJSON file also starts with '{' on every line,
33
+ * so a first-character check took every NDJSON file for a bundle and the
34
+ * whole-file JSON.parse failed. Decide by parsing instead.
35
+ */
36
+ export function looksLikeBundle(raw) {
37
+ try {
38
+ const p = JSON.parse(raw);
39
+ return !!p && typeof p === 'object' && !Array.isArray(p) && ('manifest' in p || 'events_ndjson' in p);
40
+ } catch {
41
+ return false;
42
+ }
43
+ }
44
+
45
+ const ndjsonEvents = (raw) => raw.trim().split('\n').filter((l) => l.trim()).map((l) => JSON.parse(l));
46
+
47
+ export function registerVoltCommands(program, ctx = {}) {
48
+ const { client, auth } = ctx;
49
+
50
+ const volt = program
51
+ .command('volt')
52
+ .description('VOLT evidence bundle verification and inspection');
53
+
54
+ // ── volt verify ─────────────────────────────────────────────────────────────
55
+
56
+ volt
57
+ .command('verify')
58
+ .description('Verify an evidence bundle or NDJSON chain file')
59
+ .argument('<file>', 'path to bundle JSON or events NDJSON file')
60
+ .option('--strict', 'fail on warnings too; unsigned or unpinned signatures fail')
61
+ .option('--key <pubkey|file>', 'trusted Ed25519 public key (base64 raw, or file containing it); repeatable', (v, acc) => (acc || []).concat(v))
62
+ .option('--trusted-keys <file>', 'JSON file: array of base64 public keys or {publicKey, keyId?} objects')
63
+ .action(async (file, options) => {
64
+ const raw = await readFile(file, 'utf8');
65
+
66
+ // Detect if this is a bundle (JSON with manifest) or raw NDJSON
67
+ const isBundle = looksLikeBundle(raw);
68
+
69
+ if (isBundle) {
70
+ // fleet #447: a persisted per-run bundle can be manifest_only (no
71
+ // events_ndjson, see voltContentStore.js). Handing that straight to
72
+ // verifyEvidenceBundle produced a bare MISSING_EVENTS error even
73
+ // though the engine is working correctly, there is simply nothing to
74
+ // chain-verify. Catch it here and name the remedy instead.
75
+ let manifestOnly = null;
76
+ try {
77
+ const parsed = JSON.parse(raw);
78
+ const hasEvents = typeof parsed.events_ndjson === 'string' && parsed.events_ndjson.trim().length > 0;
79
+ if (parsed && parsed.manifest && !hasEvents) {
80
+ manifestOnly = parsed.manifest;
81
+ }
82
+ } catch {
83
+ // Not valid JSON, let verifyEvidenceBundle report its own PARSE_ERROR below.
84
+ }
85
+
86
+ if (manifestOnly) {
87
+ console.log('');
88
+ console.log(chalk.bold('VOLT Evidence Bundle Verification'));
89
+ console.log(chalk.gray('─'.repeat(40)));
90
+ console.log('');
91
+ const mode = manifestOnly.bundle_mode ? ` (bundle_mode: ${manifestOnly.bundle_mode})` : '';
92
+ printWarning(`Manifest-only bundle${mode}: no events_ndjson embedded, so there is no chain to verify.`);
93
+ const remedy = manifestOnly.run_id
94
+ ? `quox volt fetch ${manifestOnly.run_id}`
95
+ : 'quox volt fetch <run_id>';
96
+ printInfo(`Remedy: ${remedy} to build a verifiable bundle.`);
97
+ console.log('');
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+
102
+ const { verifyEvidenceBundle } = await import('../../../src/lib/volt/volt-verify.js');
103
+ const trustedKeys = [];
104
+ const addKey = (k) => {
105
+ if (typeof k === 'string') trustedKeys.push({ publicKey: k.trim() });
106
+ else if (k && k.publicKey) trustedKeys.push({ publicKey: k.publicKey, ...(k.keyId ? { keyId: k.keyId } : {}) });
107
+ };
108
+ try {
109
+ for (const k of options.key || []) {
110
+ let v = k;
111
+ try { v = (await readFile(k, 'utf8')).trim(); } catch { /* literal key */ }
112
+ addKey(v);
113
+ }
114
+ if (options.trustedKeys) {
115
+ const list = JSON.parse(await readFile(options.trustedKeys, 'utf8'));
116
+ (Array.isArray(list) ? list : list.keys || []).forEach(addKey);
117
+ }
118
+ } catch (err) {
119
+ console.log(chalk.red(`Could not load trusted keys: ${err.message}`));
120
+ process.exitCode = 1;
121
+ return;
122
+ }
123
+ const result = await verifyEvidenceBundle(raw, {
124
+ strict: !!options.strict,
125
+ ...(trustedKeys.length ? { keys: trustedKeys } : {})
126
+ });
127
+
128
+ console.log('');
129
+ console.log(chalk.bold('VOLT Evidence Bundle Verification'));
130
+ console.log(chalk.gray('─'.repeat(40)));
131
+
132
+ if (result.summary.bundle_id) {
133
+ console.log(` Bundle: ${chalk.cyan(result.summary.bundle_id)}`);
134
+ }
135
+ if (result.summary.run_id) {
136
+ console.log(` Run: ${chalk.cyan(result.summary.run_id)}`);
137
+ }
138
+ console.log(` Version: ${result.summary.volt_version || 'unknown'}`);
139
+ console.log(` Events: ${result.summary.event_count}`);
140
+ console.log(` Chain: ${result.summary.chain_valid ? chalk.green('PASS') : chalk.red('FAIL')}`);
141
+ {
142
+ const sigs = result.summary.signatures || [];
143
+ if (sigs.length === 0) {
144
+ console.log(` Signature: ${chalk.yellow('NONE')} (bundle is unsigned)`);
145
+ }
146
+ for (const sg of sigs) {
147
+ const key = `${String(sg.key_id || 'unknown').slice(0, 4)}...`;
148
+ if (sg.valid) {
149
+ const how = sg.trust === 'trusted' ? 'trusted' : 'embedded, not pinned';
150
+ console.log(` Signature: ${chalk.green('VALID')} (key ${key}, ${how})`);
151
+ } else {
152
+ console.log(` Signature: ${chalk.red('INVALID')} (key ${key}, see errors)`);
153
+ }
154
+ }
155
+ }
156
+ console.log(` Timestamps: ${result.summary.timestamps_checked || 0}`);
157
+
158
+ if (result.errors.length > 0) {
159
+ console.log('');
160
+ console.log(chalk.red(` ${result.errors.length} error(s):`));
161
+ for (const err of result.errors) {
162
+ console.log(chalk.red(` ✗ [${err.code}] ${err.message}`));
163
+ if (err.detail) console.log(chalk.gray(` ${err.detail}`));
164
+ }
165
+ }
166
+ if (result.warnings.length > 0) {
167
+ console.log('');
168
+ console.log(chalk.yellow(` ${result.warnings.length} warning(s):`));
169
+ for (const w of result.warnings) {
170
+ console.log(chalk.yellow(` ⚠ [${w.code}] ${w.message}`));
171
+ }
172
+ }
173
+
174
+ console.log('');
175
+ const pass = result.valid && (!options.strict || result.warnings.length === 0);
176
+ if (pass) {
177
+ printSuccess(`RESULT: PASS — bundle is valid (${result.summary.event_count} events verified)`);
178
+ } else {
179
+ console.log(chalk.red.bold(` RESULT: FAIL`));
180
+ process.exitCode = 1;
181
+ }
182
+ } else {
183
+ // Raw NDJSON chain
184
+ const { verifyNDJSON, formatReport } = await import('../../../src/lib/volt/volt-verifier.js');
185
+ const result = await verifyNDJSON(raw);
186
+ console.log('');
187
+ console.log(formatReport(result));
188
+ console.log('');
189
+
190
+ if (result.result === 'PASS') {
191
+ printSuccess('Chain verified successfully');
192
+ } else {
193
+ console.log(chalk.red.bold('Chain verification FAILED'));
194
+ process.exitCode = 1;
195
+ }
196
+ }
197
+ });
198
+
199
+ // ── volt inspect ────────────────────────────────────────────────────────────
200
+
201
+ volt
202
+ .command('inspect')
203
+ .description('Inspect events inside a bundle or NDJSON file')
204
+ .argument('<file>', 'path to bundle JSON or events NDJSON file')
205
+ .option('--events', 'list all events')
206
+ .option('--event <seq>', 'show a single event by sequence number', parseInt)
207
+ .option('--manifest', 'show bundle manifest only')
208
+ .action(async (file, options) => {
209
+ const raw = await readFile(file, 'utf8');
210
+ const isBundle = looksLikeBundle(raw);
211
+
212
+ let events;
213
+ let manifest = null;
214
+
215
+ if (isBundle) {
216
+ const parsed = JSON.parse(raw);
217
+ manifest = parsed.manifest;
218
+ events = parsed.events_ndjson
219
+ .trim()
220
+ .split('\n')
221
+ .filter(l => l.trim())
222
+ .map(l => JSON.parse(l));
223
+ } else {
224
+ events = raw.trim().split('\n').filter(l => l.trim()).map(l => JSON.parse(l));
225
+ }
226
+
227
+ // --manifest: show just the bundle manifest
228
+ if (options.manifest) {
229
+ if (!manifest) {
230
+ printWarning('Not a bundle file — no manifest available');
231
+ return;
232
+ }
233
+ formatDetail(manifest, {
234
+ format: program.opts().output,
235
+ title: `Bundle Manifest: ${manifest.bundle_id || 'unknown'}`,
236
+ fields: [
237
+ 'bundle_id', 'run_id', 'volt_version', 'event_count', 'hash_alg',
238
+ 'first_event_hash', 'last_event_hash', 'merkle_root',
239
+ 'agents_involved', 'run_status', 'started_at', 'completed_at',
240
+ 'signed', 'redactions_present', 'created_ts'
241
+ ],
242
+ });
243
+ return;
244
+ }
245
+
246
+ // --event <seq>: show a single event
247
+ if (options.event != null) {
248
+ const ev = events.find(e => e.seq === options.event);
249
+ if (!ev) {
250
+ printWarning(`No event with seq=${options.event} (range: 1-${events.length})`);
251
+ process.exitCode = 1;
252
+ return;
253
+ }
254
+ console.log(JSON.stringify(ev, null, 2));
255
+ return;
256
+ }
257
+
258
+ // --events or default: list events summary
259
+ console.log('');
260
+ if (manifest) {
261
+ console.log(chalk.bold(`Bundle: ${manifest.bundle_id || 'N/A'}`));
262
+ console.log(chalk.gray(`Run: ${manifest.run_id || 'N/A'} — ${events.length} events`));
263
+ } else {
264
+ console.log(chalk.bold(`NDJSON Chain — ${events.length} events`));
265
+ if (events.length > 0) {
266
+ console.log(chalk.gray(`Run: ${events[0].run_id || 'N/A'}`));
267
+ }
268
+ }
269
+ console.log('');
270
+
271
+ // Table header
272
+ console.log(
273
+ chalk.gray(' SEQ ') +
274
+ chalk.gray('EVENT TYPE'.padEnd(28)) +
275
+ chalk.gray('ACTOR'.padEnd(20)) +
276
+ chalk.gray('HASH (first 12)')
277
+ );
278
+ console.log(chalk.gray(' ' + '─'.repeat(75)));
279
+
280
+ for (const ev of events) {
281
+ const seqStr = String(ev.seq).padStart(4);
282
+ const typeStr = (ev.event_type || 'unknown').padEnd(28);
283
+ const actor = (ev.actor?.actor_id || '—').padEnd(20);
284
+ const hashShort = ev.hash ? ev.hash.slice(0, 12) + '…' : '—';
285
+
286
+ console.log(` ${seqStr} ${typeStr}${actor}${chalk.gray(hashShort)}`);
287
+ }
288
+ console.log('');
289
+ printInfo(`${events.length} events total`);
290
+ });
291
+
292
+ // ── volt export ─────────────────────────────────────────────────────────────
293
+
294
+ volt
295
+ .command('export')
296
+ .description('Re-export a bundle in a different format')
297
+ .argument('<file>', 'path to bundle JSON file')
298
+ .option('--ndjson <outfile>', 'export events as NDJSON')
299
+ .option('--manifest <outfile>', 'export manifest as JSON')
300
+ .option('--pretty', 'pretty-print JSON output')
301
+ .action(async (file, options) => {
302
+ const raw = await readFile(file, 'utf8');
303
+ const parsed = JSON.parse(raw);
304
+
305
+ if (!parsed.manifest || !parsed.events_ndjson) {
306
+ printWarning('File does not appear to be a VOLT evidence bundle');
307
+ process.exitCode = 1;
308
+ return;
309
+ }
310
+
311
+ if (options.ndjson) {
312
+ await writeFile(options.ndjson, parsed.events_ndjson);
313
+ printSuccess(`Events exported to ${options.ndjson} (${parsed.manifest.event_count} events)`);
314
+ }
315
+
316
+ if (options.manifest) {
317
+ const content = options.pretty
318
+ ? JSON.stringify(parsed.manifest, null, 2)
319
+ : JSON.stringify(parsed.manifest);
320
+ await writeFile(options.manifest, content + '\n');
321
+ printSuccess(`Manifest exported to ${options.manifest}`);
322
+ }
323
+
324
+ if (!options.ndjson && !options.manifest) {
325
+ printInfo('Specify --ndjson <outfile> and/or --manifest <outfile> to export');
326
+ console.log('');
327
+ console.log('Examples:');
328
+ console.log(' quox volt export bundle.json --ndjson events.ndjson');
329
+ console.log(' quox volt export bundle.json --manifest manifest.json --pretty');
330
+ console.log(' quox volt export bundle.json --ndjson events.ndjson --manifest manifest.json');
331
+ }
332
+ });
333
+
334
+ // ── volt fetch ──────────────────────────────────────────────────────────────
335
+ //
336
+ // 2026-08-19 (proof-loop). `quox volt verify` only accepts a LOCAL FILE, and
337
+ // no verb existed to obtain one from the running instance. The collector has
338
+ // served /volt/runs/:runId/bundle and /volt/bundles/:bundleId/download all
339
+ // along with nothing wired to them, so the chain a customer needs —
340
+ // run -> bundle -> verify — was broken at exactly the step where they check
341
+ // a receipt for themselves. That is the "keep the receipt" promise, and it
342
+ // could not be kept from the canonical CLI.
343
+
344
+ volt
345
+ .command('fetch')
346
+ .description('Download a run\'s evidence bundle so `quox volt verify` can check it')
347
+ .argument('<runId>', 'VOLT run id (see `quox governance cert list`)')
348
+ .option('--out <file>', 'write the bundle here (default: <runId>-bundle.json)')
349
+ .option('--bundle-id <id>', 'fetch a specific bundle id instead of the run\'s current one')
350
+ .option('--manifest-only', 'write the persisted manifest-only bundle as-is, skip building a verifiable one')
351
+ .action(async (runId, options) => {
352
+ auth.requireAuth();
353
+
354
+ const ep = options.bundleId
355
+ ? resolveEndpoint('volt.bundle.download', { bundleId: options.bundleId })
356
+ : resolveEndpoint('volt.run.bundle.get', { runId });
357
+
358
+ const data = await client.get(ep.path, { service: ep.service });
359
+
360
+ // Unwrap to the VERIFIABLE bundle, not the storage row around it.
361
+ //
362
+ // /volt/runs/:runId/bundle returns { bundle: <db row> } where the row is
363
+ // { bundle_id, run_id, created_ts, data, stored_at } and the thing
364
+ // `quox volt verify` actually needs (manifest + events_ndjson +
365
+ // signatures) is nested in `data`. Writing the row produced a file that
366
+ // failed verification with MISSING_MANIFEST — the verifier was right and
367
+ // the fetch was wrong. Peel both layers, and only accept the result if it
368
+ // carries a manifest, so this can never hand someone a file that looks
369
+ // like evidence and is not.
370
+ let bundle = unwrapVoltBundle(data);
371
+ if (!bundle) {
372
+ printWarning(`No bundle found for ${options.bundleId || runId}`);
373
+ process.exitCode = 1;
374
+ return;
375
+ }
376
+ if (!bundle.manifest) {
377
+ printWarning(`Fetched payload for ${options.bundleId || runId} has no manifest — refusing to write a file that would fail verification.`);
378
+ printInfo(`Payload keys: ${Object.keys(bundle).join(', ')}`);
379
+ process.exitCode = 1;
380
+ return;
381
+ }
382
+
383
+ const hasEvents = typeof bundle.events_ndjson === 'string' && bundle.events_ndjson.trim().length > 0;
384
+
385
+ // fleet #447: the bundle persisted at run completion is bundle_mode:
386
+ // 'manifest_only' (see voltContentStore.js), so a plain fetch handed
387
+ // `quox volt verify` a file it could never chain-verify. Build the full
388
+ // bundle on demand instead, unless the caller asked for a specific
389
+ // bundle id (that bundle is what it is) or opted out with
390
+ // --manifest-only.
391
+ if (!hasEvents) {
392
+ if (options.bundleId) {
393
+ const out = options.out || `${options.bundleId}-bundle.json`;
394
+ await writeFile(out, JSON.stringify(bundle, null, 2) + '\n');
395
+ const mode = bundle.manifest.bundle_mode ? ` (bundle_mode: ${bundle.manifest.bundle_mode})` : '';
396
+ printSuccess(`Bundle written to ${out}`);
397
+ printWarning(`Bundle ${options.bundleId} is manifest-only${mode}, no events_ndjson to verify.`);
398
+ const runHint = bundle.manifest.run_id;
399
+ printInfo(runHint ? `For a verifiable bundle: quox volt fetch ${runHint}` : 'Fetch by run id for a verifiable bundle.');
400
+ return;
401
+ }
402
+
403
+ if (options.manifestOnly) {
404
+ const out = options.out || `${runId}-bundle.json`;
405
+ await writeFile(out, JSON.stringify(bundle, null, 2) + '\n');
406
+ printSuccess(`Bundle written to ${out}`);
407
+ printWarning('This is a manifest-only bundle: `quox volt verify` cannot chain-verify it (no events_ndjson).');
408
+ return;
409
+ }
410
+
411
+ printInfo(`Persisted bundle for ${runId} is manifest-only, building a verifiable bundle from stored events.`);
412
+
413
+ const createEp = resolveEndpoint('volt.bundle.create');
414
+ const created = await client.post(createEp.path, { service: createEp.service, body: { run_id: runId } });
415
+ const bundleId = created && created.bundle_id;
416
+ if (!bundleId) {
417
+ printWarning(`Could not build a verifiable bundle for ${runId}.`);
418
+ process.exitCode = 1;
419
+ return;
420
+ }
421
+
422
+ const downloadEp = resolveEndpoint('volt.bundle.download', { bundleId });
423
+ const fullData = await client.get(downloadEp.path, { service: downloadEp.service });
424
+ const fullBundle = unwrapVoltBundle(fullData);
425
+ if (!fullBundle || !fullBundle.manifest) {
426
+ printWarning(`Built bundle ${bundleId} but could not download it, no manifest in the response.`);
427
+ process.exitCode = 1;
428
+ return;
429
+ }
430
+
431
+ const out = options.out || `${runId}-bundle.json`;
432
+ await writeFile(out, JSON.stringify(fullBundle, null, 2) + '\n');
433
+ const eventCount = fullBundle.manifest.event_count;
434
+ printSuccess(`Bundle ${bundleId} written to ${out}${eventCount != null ? ` (${eventCount} events)` : ''}`);
435
+ printInfo(`Verify it: quox volt verify ${out}`);
436
+ return;
437
+ }
438
+
439
+ const out = options.out || `${options.bundleId || runId}-bundle.json`;
440
+ await writeFile(out, JSON.stringify(bundle, null, 2) + '\n');
441
+
442
+ const events = bundle.manifest && bundle.manifest.event_count;
443
+ printSuccess(`Bundle written to ${out}${events != null ? ` (${events} events)` : ''}`);
444
+ printInfo(`Verify it: quox volt verify ${out}`);
445
+ });
446
+
447
+ // ── volt summary ────────────────────────────────────────────────────────────
448
+
449
+ volt
450
+ .command('summary')
451
+ .description('Quick summary of a bundle (no verification)')
452
+ .argument('<file>', 'path to bundle JSON or events NDJSON file')
453
+ .action(async (file) => {
454
+ const raw = await readFile(file, 'utf8');
455
+ // quox#935: an events NDJSON file gets a chain summary instead of a crash.
456
+ if (!looksLikeBundle(raw)) {
457
+ let evs;
458
+ try { evs = ndjsonEvents(raw); } catch {
459
+ printWarning('File is neither a VOLT evidence bundle nor an events NDJSON file');
460
+ process.exitCode = 1;
461
+ return;
462
+ }
463
+ const counts = {};
464
+ for (const ev of evs) counts[ev.event_type] = (counts[ev.event_type] || 0) + 1;
465
+ console.log('');
466
+ console.log(chalk.bold(`VOLT NDJSON Chain Summary (${evs.length} events)`));
467
+ console.log(chalk.gray('─'.repeat(40)));
468
+ console.log(` Run ID: ${chalk.cyan(evs[0]?.run_id || 'N/A')}`);
469
+ console.log(` Events: ${evs.length} events`);
470
+ if (Object.keys(counts).length > 0) {
471
+ console.log('');
472
+ console.log(chalk.bold(' Event Types:'));
473
+ for (const [type, count] of Object.entries(counts).sort((a, b) => b[1] - a[1])) {
474
+ console.log(` ${String(count).padStart(4)} ${type}`);
475
+ }
476
+ }
477
+ console.log('');
478
+ return;
479
+ }
480
+ const parsed = JSON.parse(raw);
481
+
482
+ if (!parsed.manifest) {
483
+ printWarning('File does not appear to be a VOLT evidence bundle');
484
+ process.exitCode = 1;
485
+ return;
486
+ }
487
+
488
+ const m = parsed.manifest;
489
+ const events = parsed.events_ndjson
490
+ ?.trim()
491
+ .split('\n')
492
+ .filter(l => l.trim()) || [];
493
+
494
+ // Event type breakdown
495
+ const typeCounts = {};
496
+ for (const line of events) {
497
+ try {
498
+ const ev = JSON.parse(line);
499
+ typeCounts[ev.event_type] = (typeCounts[ev.event_type] || 0) + 1;
500
+ } catch { /* skip */ }
501
+ }
502
+
503
+ console.log('');
504
+ console.log(chalk.bold('VOLT Bundle Summary'));
505
+ console.log(chalk.gray('─'.repeat(40)));
506
+ console.log(` Bundle ID: ${chalk.cyan(m.bundle_id || 'N/A')}`);
507
+ console.log(` Run ID: ${chalk.cyan(m.run_id || 'N/A')}`);
508
+ console.log(` Version: ${m.volt_version || 'N/A'}`);
509
+ console.log(` Status: ${m.run_status || 'N/A'}`);
510
+ console.log(` Events: ${m.event_count || events.length}`);
511
+ console.log(` Agents: ${(m.agents_involved || []).join(', ') || 'none'}`);
512
+ console.log(` Policies: ${(m.policy_ids_evaluated || []).length} evaluated`);
513
+ console.log(` HITL: ${m.hitl_decisions || 0} decisions`);
514
+ console.log(` Signed: ${m.signed ? 'yes' : 'no'}`);
515
+ console.log(` Redacted: ${m.redactions_present ? 'yes' : 'no'}`);
516
+ console.log(` Created: ${m.created_ts || 'N/A'}`);
517
+ console.log(` Started: ${m.started_at || 'N/A'}`);
518
+ console.log(` Completed: ${m.completed_at || 'N/A'}`);
519
+
520
+ if (Object.keys(typeCounts).length > 0) {
521
+ console.log('');
522
+ console.log(chalk.bold(' Event Types:'));
523
+ const sorted = Object.entries(typeCounts).sort((a, b) => b[1] - a[1]);
524
+ for (const [type, count] of sorted) {
525
+ console.log(` ${String(count).padStart(4)} ${type}`);
526
+ }
527
+ }
528
+ console.log('');
529
+ });
530
+
531
+ // ── volt accept / acceptance ────────────────────────────────────────────────
532
+ // SEO-MOAT (owner ruling 2026-09-03): the "did it work" layer. The chain
533
+ // proves what happened; this records whether it achieved its intent — an
534
+ // attestation, not automated evaluation. The server derives WHO attested
535
+ // from the credential class (human/agent/service) and witnesses the
536
+ // verdict as its own VOLT run pinning the target run's head_hash, so an
537
+ // agent marking its own work "pass" is visible as exactly that.
538
+
539
+ volt
540
+ .command('accept')
541
+ .description('Attest a terminal run\'s outcome: did it achieve its intent?')
542
+ .argument('<runId>', 'VOLT run id (VR_...) — see `quox volt fetch`')
543
+ .requiredOption('--verdict <verdict>', "'pass' or 'fail'")
544
+ .option('--reason <text>', 'what you checked and what you saw')
545
+ .action(async (runId, options) => {
546
+ auth.requireAuth();
547
+ const ep = resolveEndpoint('volt.run.acceptance.post', { runId });
548
+ const data = await client.post(ep.path, {
549
+ service: ep.service,
550
+ body: { verdict: options.verdict, reason: options.reason || null },
551
+ });
552
+ const v = data.verdict || {};
553
+ printSuccess(`Acceptance recorded: ${v.verdict} on ${runId} (attested by ${v.actor_type}.${v.actor_id})`);
554
+ if (v.evidence_run_id) printInfo(`Witnessed as VOLT run ${v.evidence_run_id} (pins target head_hash ${String(v.target_head_hash || '').slice(0, 12)}...)`);
555
+ });
556
+
557
+ volt
558
+ .command('acceptance')
559
+ .description('Show a run\'s acceptance verdict history (latest is the standing verdict)')
560
+ .argument('<runId>', 'VOLT run id (VR_...)')
561
+ .action(async (runId) => {
562
+ auth.requireAuth();
563
+ const ep = resolveEndpoint('volt.run.acceptance.get', { runId });
564
+ const data = await client.get(ep.path, { service: ep.service });
565
+ formatDetail(data.latest, { format: program.opts().output });
566
+ if ((data.history || []).length > 1) {
567
+ printInfo(`${data.history.length} verdicts total — latest supersedes; history is append-only.`);
568
+ }
569
+ });
570
+ }
@@ -0,0 +1,32 @@
1
+ /** `quox approvals walkthrough` and `quox inbox walkthrough`: the waiting questions, one card at a time. */
2
+ import { createInterface } from 'node:readline';
3
+ import { resolveEndpoint } from '../api/endpoints.js';
4
+ import { resolveOrgId } from './helpers.js';
5
+ import { runWalkthrough } from '../core/walkthrough.js';
6
+
7
+ export function attachWalkthrough(parent, { client, auth }, program) {
8
+ parent
9
+ .command('walkthrough')
10
+ .description('Walk through the questions waiting for you one at a time: what it does, why, my advice, then your choice')
11
+ .action(async () => {
12
+ auth.requireAuth();
13
+ const orgId = resolveOrgId(auth, program);
14
+ const lp = resolveEndpoint('inbox.list', { orgId });
15
+ const data = await client.get(lp.path, { service: lp.service, query: { status: 'open', limit: 200 } });
16
+ const items = (data && (data.items || data)) || [];
17
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
18
+ const lines = []; let waiting = null; let closed = false;
19
+ rl.on('line', (l) => { if (waiting) { const w = waiting; waiting = null; w(l); } else lines.push(l); });
20
+ rl.on('close', () => { closed = true; if (waiting) { const w = waiting; waiting = null; w(null); } });
21
+ const readLine = (prompt) => new Promise((res) => { if (lines.length) return res(lines.shift()); if (closed) return res(null); process.stdout.write(prompt); waiting = res; });
22
+ try {
23
+ await runWalkthrough(Array.isArray(items) ? items : [], {
24
+ readLine, write: (l) => console.log(l),
25
+ answer: async (it, key, note) => {
26
+ const ep = resolveEndpoint('inbox.respond', { orgId, itemId: it.id });
27
+ await client.post(ep.path, { service: ep.service, body: { action: 'answer', option: key, ...(note ? { comment: String(note).slice(0, 4000) } : {}) } });
28
+ },
29
+ });
30
+ } finally { rl.close(); }
31
+ });
32
+ }