quoxcli 0.2.0 → 0.4.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 (442) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -0
  3. package/bin/quox.js +99 -126
  4. package/lib/api/endpoints/actions.js +15 -0
  5. package/lib/api/endpoints/admin.js +46 -0
  6. package/lib/api/endpoints/agent-schedules.js +26 -0
  7. package/lib/api/endpoints/agents.js +7 -0
  8. package/lib/api/endpoints/assistants.js +12 -0
  9. package/lib/api/endpoints/away.js +15 -0
  10. package/lib/api/endpoints/blog.js +16 -0
  11. package/lib/api/endpoints/chat.js +14 -0
  12. package/lib/api/endpoints/contactsq.js +6 -0
  13. package/lib/api/endpoints/conversations.js +14 -0
  14. package/lib/api/endpoints/devServerRegistry.js +25 -0
  15. package/lib/api/endpoints/engagement.js +26 -0
  16. package/lib/api/endpoints/evidence.js +20 -0
  17. package/lib/api/endpoints/executions.js +13 -0
  18. package/lib/api/endpoints/fetchAllowlist.js +27 -0
  19. package/lib/api/endpoints/files.js +14 -0
  20. package/lib/api/endpoints/hat.js +44 -0
  21. package/lib/api/endpoints/inbox.js +20 -0
  22. package/lib/api/endpoints/index.js +26 -0
  23. package/lib/api/endpoints/loops.js +26 -0
  24. package/lib/api/endpoints/memory.js +19 -0
  25. package/lib/api/endpoints/mind.js +13 -0
  26. package/lib/api/endpoints/mon.js +179 -0
  27. package/lib/api/endpoints/objectives.js +12 -0
  28. package/lib/api/endpoints/plugins.js +18 -0
  29. package/lib/api/endpoints/presence.js +33 -0
  30. package/lib/api/endpoints/quoxplan.js +7 -0
  31. package/lib/api/endpoints/quoxseo.js +12 -0
  32. package/lib/api/endpoints/router.js +17 -0
  33. package/lib/api/endpoints/safety.js +7 -0
  34. package/lib/api/endpoints/server.js +21 -0
  35. package/lib/api/endpoints/setup.js +6 -0
  36. package/lib/api/endpoints/skills.js +20 -0
  37. package/lib/api/endpoints/stepup.js +20 -0
  38. package/lib/api/endpoints/teams.js +2 -2
  39. package/lib/api/endpoints/triggers.js +26 -0
  40. package/lib/api/endpoints/v1.js +120 -0
  41. package/lib/api/endpoints/ward.js +7 -0
  42. package/lib/api/endpoints/workflows.js +7 -0
  43. package/lib/api/endpoints/x.js +8 -0
  44. package/lib/commands/actions.js +131 -0
  45. package/lib/commands/admin.js +16 -0
  46. package/lib/commands/agent.js +170 -27
  47. package/lib/commands/agentAttach.js +140 -13
  48. package/lib/commands/approvals.js +78 -1
  49. package/lib/commands/aside.js +24 -0
  50. package/lib/commands/ask.js +146 -0
  51. package/lib/commands/assistant.js +59 -4
  52. package/lib/commands/auth.js +8 -2
  53. package/lib/commands/backup.js +8 -4
  54. package/lib/commands/blog.js +110 -0
  55. package/lib/commands/brain.js +105 -14
  56. package/lib/commands/build.js +19 -5
  57. package/lib/commands/chat.js +180 -26
  58. package/lib/commands/chatCompanion.js +27 -0
  59. package/lib/commands/chatState.js +45 -0
  60. package/lib/commands/claude.js +35 -38
  61. package/lib/commands/contacts.js +134 -4
  62. package/lib/commands/contactsSendAt.js +21 -0
  63. package/lib/commands/conversation.js +35 -4
  64. package/lib/commands/dashboard.js +43 -0
  65. package/lib/commands/department.js +28 -7
  66. package/lib/commands/devResident.js +15 -3
  67. package/lib/commands/devSupervisor.js +13 -1
  68. package/lib/commands/discord.js +75 -39
  69. package/lib/commands/done.js +98 -28
  70. package/lib/commands/engagement.js +107 -6
  71. package/lib/commands/evidence.js +154 -0
  72. package/lib/commands/ext.js +23 -0
  73. package/lib/commands/fetchAllowlist.js +71 -0
  74. package/lib/commands/file.js +38 -1
  75. package/lib/commands/fleet.js +336 -4
  76. package/lib/commands/governance.js +12 -3
  77. package/lib/commands/gripe.js +44 -13
  78. package/lib/commands/hat.js +254 -9
  79. package/lib/commands/helpers.js +18 -1
  80. package/lib/commands/hyperion.js +58 -0
  81. package/lib/commands/image.js +68 -0
  82. package/lib/commands/inbox.js +74 -23
  83. package/lib/commands/kuma.js +1050 -0
  84. package/lib/commands/kumaSla.js +174 -0
  85. package/lib/commands/licence.js +52 -155
  86. package/lib/commands/loop.js +291 -0
  87. package/lib/commands/lucid.js +10 -4
  88. package/lib/commands/memory.js +85 -8
  89. package/lib/commands/mind.js +71 -0
  90. package/lib/commands/mon.js +69 -2
  91. package/lib/commands/monitoring.js +1 -1
  92. package/lib/commands/motion.js +2 -2
  93. package/lib/commands/nucleus.js +48 -17
  94. package/lib/commands/objective.js +59 -1
  95. package/lib/commands/offload.js +89 -0
  96. package/lib/commands/onboard.js +2 -1
  97. package/lib/commands/org.js +30 -3
  98. package/lib/commands/peek.js +28 -0
  99. package/lib/commands/plan.js +38 -0
  100. package/lib/commands/plugin.js +110 -0
  101. package/lib/commands/presence.js +89 -0
  102. package/lib/commands/provider.js +217 -0
  103. package/lib/commands/qlarity.js +19 -3
  104. package/lib/commands/quoxchat.js +13 -4
  105. package/lib/commands/quoxseo.js +69 -0
  106. package/lib/commands/reach.js +2 -1
  107. package/lib/commands/research.js +79 -0
  108. package/lib/commands/router.js +77 -0
  109. package/lib/commands/rows.js +367 -0
  110. package/lib/commands/run.js +82 -10
  111. package/lib/commands/scope.js +2 -2
  112. package/lib/commands/server.js +405 -0
  113. package/lib/commands/setup.js +33 -7
  114. package/lib/commands/shortcut.js +41 -0
  115. package/lib/commands/skills.js +68 -9
  116. package/lib/commands/slot.js +260 -7
  117. package/lib/commands/status.js +1 -1
  118. package/lib/commands/team.js +3 -1
  119. package/lib/commands/tips.js +23 -0
  120. package/lib/commands/tool.js +133 -45
  121. package/lib/commands/trace.js +12 -7
  122. package/lib/commands/trigger.js +95 -0
  123. package/lib/commands/update.js +46 -0
  124. package/lib/commands/vault.js +31 -8
  125. package/lib/commands/vm.js +237 -0
  126. package/lib/commands/voice.js +34 -3
  127. package/lib/commands/volt.js +45 -3
  128. package/lib/commands/walkthrough.js +32 -0
  129. package/lib/commands/watch.js +73 -21
  130. package/lib/commands/welcome.js +14 -0
  131. package/lib/commands/workflow.js +189 -32
  132. package/lib/commands/x.js +13 -4
  133. package/lib/commands/youtube.js +172 -0
  134. package/lib/core/actingAs.js +2 -2
  135. package/lib/core/actionItems.js +115 -0
  136. package/lib/core/activeSummary.js +186 -0
  137. package/lib/core/agentAlias.js +2 -0
  138. package/lib/core/agentFamilies.js +7 -0
  139. package/lib/core/aside.js +54 -0
  140. package/lib/core/askDecision.js +60 -0
  141. package/lib/core/auth.js +164 -13
  142. package/lib/core/callerSource.js +1 -1
  143. package/lib/core/cliBuild.js +62 -0
  144. package/lib/core/client.js +152 -35
  145. package/lib/core/commandRegistrars.js +130 -0
  146. package/lib/core/config.js +143 -25
  147. package/lib/core/customHats.js +168 -0
  148. package/lib/core/doneEngineFetch.js +8 -0
  149. package/lib/core/errors.js +329 -20
  150. package/lib/core/findingReconcile.js +90 -0
  151. package/lib/core/global-flags.js +105 -5
  152. package/lib/core/governedSession.js +1 -3
  153. package/lib/core/hyperion.js +102 -0
  154. package/lib/core/inboxResolution.js +65 -0
  155. package/lib/core/lazyCommands.js +4 -1
  156. package/lib/core/liveSessionsReport.js +1 -1
  157. package/lib/core/loopGlyph.js +97 -0
  158. package/lib/core/offload.js +533 -0
  159. package/lib/core/org-override.js +1 -1
  160. package/lib/core/orgResolve.js +70 -0
  161. package/lib/core/output.js +11 -11
  162. package/lib/core/peek.js +126 -0
  163. package/lib/core/profileUsers.js +51 -0
  164. package/lib/core/promptCancel.js +18 -0
  165. package/lib/core/repoPath.js +11 -0
  166. package/lib/core/residentSeed.js +3 -1
  167. package/lib/core/rootOptions.js +39 -0
  168. package/lib/core/router.js +168 -0
  169. package/lib/core/selfUpdate.js +188 -0
  170. package/lib/core/sessionHeartbeat.js +12 -8
  171. package/lib/core/sessionsOverview.js +64 -0
  172. package/lib/core/shortcut.js +83 -0
  173. package/lib/core/slotKeeper.js +248 -3
  174. package/lib/core/slotWake.js +120 -0
  175. package/lib/core/supervisorEngine.js +71 -2
  176. package/lib/core/version.js +1 -1
  177. package/lib/core/vm.js +366 -0
  178. package/lib/core/vmTui.js +86 -0
  179. package/lib/core/walkthrough.js +35 -0
  180. package/lib/dragon/companionView.js +34 -0
  181. package/lib/dragon/frames.js +118 -0
  182. package/lib/dragon/jobs.js +123 -0
  183. package/lib/dragon/renderWorker.js +15 -0
  184. package/lib/dragon/select.js +72 -0
  185. package/lib/evidence/bundleExport.js +47 -0
  186. package/lib/evidence/bundleVerify.js +77 -0
  187. package/lib/hyperion/deck.js +29 -0
  188. package/lib/lucid/LucidCard.jsx +68 -0
  189. package/lib/lucid/LucidIntro.jsx +45 -58
  190. package/lib/lucid/cards.js +86 -0
  191. package/lib/lucid/markdown.js +81 -0
  192. package/lib/lucid/motion.js +56 -0
  193. package/lib/quoxon/EXTENSIONS.md +23 -0
  194. package/lib/quoxon/activity.js +14 -2
  195. package/lib/quoxon/aocl.js +117 -0
  196. package/lib/quoxon/api.js +690 -25
  197. package/lib/quoxon/app.js +3586 -250
  198. package/lib/quoxon/approvalFacts.js +96 -0
  199. package/lib/quoxon/approvalSentence.js +44 -0
  200. package/lib/quoxon/approvalsView.js +384 -0
  201. package/lib/quoxon/asideView.js +40 -0
  202. package/lib/quoxon/ask.js +121 -0
  203. package/lib/quoxon/away.js +52 -0
  204. package/lib/quoxon/bang.js +224 -0
  205. package/lib/quoxon/bulkRisk.js +17 -0
  206. package/lib/quoxon/capabilities.js +13 -6
  207. package/lib/quoxon/cells.js +53 -0
  208. package/lib/quoxon/commandShort.js +124 -0
  209. package/lib/quoxon/commands.js +429 -39
  210. package/lib/quoxon/connect.js +210 -23
  211. package/lib/quoxon/connectCard.js +19 -2
  212. package/lib/quoxon/consent.js +86 -0
  213. package/lib/quoxon/copy.js +4 -3
  214. package/lib/quoxon/countdownLine.js +20 -0
  215. package/lib/quoxon/deck.js +30 -0
  216. package/lib/quoxon/demo.autoplay.js +29 -0
  217. package/lib/quoxon/demo.fixtures.js +1 -1
  218. package/lib/quoxon/demo.js +46 -3
  219. package/lib/quoxon/devObserver.js +20 -0
  220. package/lib/quoxon/dividerAocl.js +192 -0
  221. package/lib/quoxon/dividerRule.js +57 -0
  222. package/lib/quoxon/dragonCompanion.js +255 -0
  223. package/lib/quoxon/dragonModes.js +151 -0
  224. package/lib/quoxon/dragonMoments.js +82 -0
  225. package/lib/quoxon/dragonReads.js +68 -0
  226. package/lib/quoxon/dragonView.js +41 -0
  227. package/lib/quoxon/earlyInput.js +40 -0
  228. package/lib/quoxon/echo.js +15 -0
  229. package/lib/quoxon/egg.js +2 -2
  230. package/lib/quoxon/events.js +266 -26
  231. package/lib/quoxon/extensions.js +276 -0
  232. package/lib/quoxon/feedback.js +50 -0
  233. package/lib/quoxon/gallery.js +21 -7
  234. package/lib/quoxon/handoffOffer.js +78 -0
  235. package/lib/quoxon/hatSwitch.js +37 -0
  236. package/lib/quoxon/headless.js +161 -0
  237. package/lib/quoxon/hostUrls.js +41 -0
  238. package/lib/quoxon/inboxView.js +79 -0
  239. package/lib/quoxon/indicator.js +6 -2
  240. package/lib/quoxon/installCli.js +79 -0
  241. package/lib/quoxon/intent.js +12 -1
  242. package/lib/quoxon/keys.js +51 -8
  243. package/lib/quoxon/launcher.js +103 -0
  244. package/lib/quoxon/loopCard.js +456 -0
  245. package/lib/quoxon/loopCards.js +180 -0
  246. package/lib/quoxon/loopStream.js +87 -0
  247. package/lib/quoxon/main.js +101 -160
  248. package/lib/quoxon/markdown.js +45 -21
  249. package/lib/quoxon/markdownSettle.js +19 -0
  250. package/lib/quoxon/matrixDomains.json +46 -0
  251. package/lib/quoxon/mentions.js +90 -0
  252. package/lib/quoxon/mind.js +103 -0
  253. package/lib/quoxon/mode.js +46 -0
  254. package/lib/quoxon/model.js +132 -26
  255. package/lib/quoxon/modelPrefs.js +345 -0
  256. package/lib/quoxon/motion/clock.js +3 -2
  257. package/lib/quoxon/motion/level.js +91 -0
  258. package/lib/quoxon/mouse.js +222 -0
  259. package/lib/quoxon/noai.js +57 -0
  260. package/lib/quoxon/objectiveOffer.js +82 -0
  261. package/lib/quoxon/objects/away.js +72 -0
  262. package/lib/quoxon/objects/fetch.js +17 -5
  263. package/lib/quoxon/objects/fleet.js +149 -0
  264. package/lib/quoxon/objects/health.js +186 -0
  265. package/lib/quoxon/objects/index.js +46 -7
  266. package/lib/quoxon/objects/mirror.js +137 -0
  267. package/lib/quoxon/objects/model.js +33 -0
  268. package/lib/quoxon/objects/peek.js +17 -0
  269. package/lib/quoxon/objects/proof.js +12 -4
  270. package/lib/quoxon/objects/prove.js +130 -0
  271. package/lib/quoxon/objects/replay.js +125 -0
  272. package/lib/quoxon/objects/sitrep.js +58 -0
  273. package/lib/quoxon/objects/view.js +11 -0
  274. package/lib/quoxon/onboarding/copy.js +32 -4
  275. package/lib/quoxon/onboarding/credential.js +17 -4
  276. package/lib/quoxon/onboarding/dockerOffer.js +45 -0
  277. package/lib/quoxon/onboarding/failureCause.js +33 -0
  278. package/lib/quoxon/onboarding/finish.js +15 -0
  279. package/lib/quoxon/onboarding/index.js +34 -7
  280. package/lib/quoxon/onboarding/installRunner.js +64 -5
  281. package/lib/quoxon/onboarding/preflight.js +17 -3
  282. package/lib/quoxon/onboarding/probe.js +65 -0
  283. package/lib/quoxon/onboarding/shortcutOffer.js +28 -0
  284. package/lib/quoxon/onboarding/view.js +76 -19
  285. package/lib/quoxon/orgLabel.js +10 -0
  286. package/lib/quoxon/orgSwitch.js +59 -0
  287. package/lib/quoxon/ownBroadcast.js +22 -0
  288. package/lib/quoxon/palette.js +43 -0
  289. package/lib/quoxon/planSteps.js +51 -0
  290. package/lib/quoxon/print.js +12 -5
  291. package/lib/quoxon/profileSwitch.js +53 -0
  292. package/lib/quoxon/promptHistory.js +41 -0
  293. package/lib/quoxon/providers.js +48 -0
  294. package/lib/quoxon/qart.js +20 -51
  295. package/lib/quoxon/qdragon.js +410 -0
  296. package/lib/quoxon/qdragonFly.js +62 -0
  297. package/lib/quoxon/qdragonScenes.js +282 -0
  298. package/lib/quoxon/qeyes.js +213 -0
  299. package/lib/quoxon/qmotion.js +75 -37
  300. package/lib/quoxon/render.js +740 -124
  301. package/lib/quoxon/resend.js +72 -0
  302. package/lib/quoxon/roster.js +117 -17
  303. package/lib/quoxon/route.js +6 -5
  304. package/lib/quoxon/rows.js +954 -0
  305. package/lib/quoxon/rowsStore.js +80 -0
  306. package/lib/quoxon/screenContext.js +150 -0
  307. package/lib/quoxon/screenFrames.js +254 -0
  308. package/lib/quoxon/serverChip.js +42 -0
  309. package/lib/quoxon/session.js +182 -2
  310. package/lib/quoxon/sessionDead.js +17 -0
  311. package/lib/quoxon/signin.js +125 -0
  312. package/lib/quoxon/slash/agents.js +112 -0
  313. package/lib/quoxon/slash/argSources.js +65 -0
  314. package/lib/quoxon/slash/args.js +65 -0
  315. package/lib/quoxon/slash/automate.js +89 -0
  316. package/lib/quoxon/slash/broadcast.js +140 -0
  317. package/lib/quoxon/slash/broadcastRun.js +108 -0
  318. package/lib/quoxon/slash/card.js +30 -0
  319. package/lib/quoxon/slash/challenge.js +114 -0
  320. package/lib/quoxon/slash/cliCommand.js +94 -0
  321. package/lib/quoxon/slash/cliLeaves.json +1023 -0
  322. package/lib/quoxon/slash/compact.js +1 -1
  323. package/lib/quoxon/slash/confirm.js +30 -0
  324. package/lib/quoxon/slash/crystallize.js +69 -0
  325. package/lib/quoxon/slash/dashboard.js +136 -0
  326. package/lib/quoxon/slash/draft.js +54 -0
  327. package/lib/quoxon/slash/evidenceCmd.js +34 -0
  328. package/lib/quoxon/slash/hatWalk.js +206 -0
  329. package/lib/quoxon/slash/inverses.js +77 -0
  330. package/lib/quoxon/slash/killer.js +24 -0
  331. package/lib/quoxon/slash/killerApi.js +16 -0
  332. package/lib/quoxon/slash/ledger.js +13 -8
  333. package/lib/quoxon/slash/listView.js +3 -1
  334. package/lib/quoxon/slash/modelCmd.js +261 -0
  335. package/lib/quoxon/slash/palette.js +22 -8
  336. package/lib/quoxon/slash/paletteController.js +117 -7
  337. package/lib/quoxon/slash/panels.js +21 -6
  338. package/lib/quoxon/slash/picker.js +20 -2
  339. package/lib/quoxon/slash/qpeCmd.js +35 -0
  340. package/lib/quoxon/slash/restart.js +95 -13
  341. package/lib/quoxon/slash/resume.js +18 -1
  342. package/lib/quoxon/slash/rowCmd.js +157 -0
  343. package/lib/quoxon/slash/rowWalk.js +175 -0
  344. package/lib/quoxon/slash/settings.js +16 -6
  345. package/lib/quoxon/slash/spawn.js +177 -0
  346. package/lib/quoxon/slash/stepUp.js +274 -0
  347. package/lib/quoxon/slash/stepUpCard.js +60 -0
  348. package/lib/quoxon/slash/stepUpCmds.js +78 -0
  349. package/lib/quoxon/slash/todoCmd.js +122 -0
  350. package/lib/quoxon/slash/undoApi.js +38 -0
  351. package/lib/quoxon/slash/undoCmd.js +49 -0
  352. package/lib/quoxon/slash/undoWish.js +15 -0
  353. package/lib/quoxon/slash/watch.js +164 -0
  354. package/lib/quoxon/slash/wish.js +23 -0
  355. package/lib/quoxon/slash/wishCmd.js +32 -0
  356. package/lib/quoxon/slotChat.js +300 -0
  357. package/lib/quoxon/slotFormat.js +195 -0
  358. package/lib/quoxon/slotRun.js +131 -0
  359. package/lib/quoxon/sound/mapping.js +2 -1
  360. package/lib/quoxon/stray.js +22 -0
  361. package/lib/quoxon/suggestCommand.js +90 -0
  362. package/lib/quoxon/term.js +46 -11
  363. package/lib/quoxon/textBuffer.js +176 -2
  364. package/lib/quoxon/theme.js +58 -25
  365. package/lib/quoxon/tips.js +433 -0
  366. package/lib/quoxon/toolCards.js +30 -0
  367. package/lib/quoxon/toolError.js +41 -0
  368. package/lib/quoxon/transcript.js +42 -4
  369. package/lib/quoxon/web/qface.js +18 -10
  370. package/lib/quoxon/welcome.js +1 -1
  371. package/lib/quoxon/whatsnew.js +136 -0
  372. package/lib/quoxon/whatsnew.jsonl +134 -0
  373. package/lib/quoxon/windowOrg.js +123 -0
  374. package/lib/server/devServers.js +137 -0
  375. package/lib/server/diag.js +129 -0
  376. package/lib/server/doctor.js +71 -0
  377. package/lib/server/install.js +149 -0
  378. package/lib/server/pluginEnable.js +161 -0
  379. package/lib/server/skew.js +56 -0
  380. package/lib/server/snapshot.js +131 -0
  381. package/lib/server/status.js +128 -0
  382. package/lib/server/sys.js +65 -0
  383. package/lib/server/uninstall.js +63 -0
  384. package/lib/server/update.js +234 -0
  385. package/lib/toolOutputShape.js +315 -0
  386. package/lib/tui/views/HyperionDeck.jsx +79 -0
  387. package/lib/tui/views/LucidDeck.jsx +209 -217
  388. package/package.json +5 -1
  389. package/vendor/dragonlab/SOURCE +4 -0
  390. package/vendor/dragonlab/design/cipher/v1/cipher-master.svg +46 -0
  391. package/vendor/dragonlab/design/cipher/v2/character.mjs +49 -0
  392. package/vendor/dragonlab/design/cipher/v2/review.mjs +33 -0
  393. package/vendor/dragonlab/design/cipher/v2/watch.mjs +56 -0
  394. package/vendor/dragonlab/design/drago/v1/character.mjs +19 -0
  395. package/vendor/dragonlab/design/drago/v1/drago-master.svg +56 -0
  396. package/vendor/dragonlab/design/drago/v2/character.mjs +87 -0
  397. package/vendor/dragonlab/design/drago/v4/character.mjs +67 -0
  398. package/vendor/dragonlab/design/drago/v4/profile.mjs +35 -0
  399. package/vendor/dragonlab/design/drago/v4/review.mjs +33 -0
  400. package/vendor/dragonlab/design/drago/v4/watch.mjs +56 -0
  401. package/vendor/dragonlab/design/hyperion/v1/hyperion-master.svg +56 -0
  402. package/vendor/dragonlab/design/hyperion/v2/character.mjs +79 -0
  403. package/vendor/dragonlab/design/hyperion/v2/review.mjs +33 -0
  404. package/vendor/dragonlab/design/hyperion/v2/watch.mjs +56 -0
  405. package/vendor/dragonlab/design/lucid/recovery/arrival.mjs +22 -0
  406. package/vendor/dragonlab/design/lucid/recovery/character.mjs +106 -0
  407. package/vendor/dragonlab/design/lucid/recovery/layout.mjs +50 -0
  408. package/vendor/dragonlab/design/lucid/recovery/lucid-master.svg +78 -0
  409. package/vendor/dragonlab/design/lucid/recovery/motion.mjs +42 -0
  410. package/vendor/dragonlab/design/lucid/recovery/render.mjs +121 -0
  411. package/vendor/dragonlab/design/lucid/recovery/review.mjs +68 -0
  412. package/vendor/dragonlab/design/lucid/recovery/verify.mjs +84 -0
  413. package/vendor/dragonlab/design/lucid/recovery/watch.mjs +56 -0
  414. package/vendor/dragonlab/design/seer/v1/seer-master.svg +53 -0
  415. package/vendor/dragonlab/design/seer/v2/character.mjs +88 -0
  416. package/vendor/dragonlab/design/seer/v3/character.mjs +33 -0
  417. package/vendor/dragonlab/design/seer/v4/character.mjs +66 -0
  418. package/vendor/dragonlab/design/seer/v4/review.mjs +33 -0
  419. package/vendor/dragonlab/design/seer/v4/watch.mjs +56 -0
  420. package/vendor/dragonlab/design/stage3/companion-review.mjs +28 -0
  421. package/vendor/dragonlab/design/stage3/sentinel-art.js +39 -0
  422. package/vendor/dragonlab/design/stage3/sentinel-braille.js +216 -0
  423. package/vendor/dragonlab/design/stage3/sentinel-character.js +257 -0
  424. package/vendor/dragonlab/design/stage3/sentinel-icon.js +103 -0
  425. package/vendor/dragonlab/design/stage3/sentinel-warden-eyes.js +95 -0
  426. package/vendor/dragonlab/design/stage3/svg-coverage.js +148 -0
  427. package/vendor/dragonlab/factory/svg-rig.mjs +63 -0
  428. package/vendor/dragonlab/integration/companions-v1/characters.mjs +88 -0
  429. package/vendor/dragonlab/integration/companions-v1/cipher.mjs +2 -0
  430. package/vendor/dragonlab/integration/companions-v1/companion.mjs +63 -0
  431. package/vendor/dragonlab/integration/companions-v1/drago.mjs +2 -0
  432. package/vendor/dragonlab/integration/companions-v1/hyperion.mjs +2 -0
  433. package/vendor/dragonlab/integration/companions-v1/lucid.mjs +2 -0
  434. package/vendor/dragonlab/integration/companions-v1/seer.mjs +2 -0
  435. package/vendor/dragonlab/integration/companions-v1/sentinel.mjs +2 -0
  436. package/vendor/dragonlab/integration/companions-v1/view.mjs +28 -0
  437. package/vendor/dragonlab/integration/hyperion-v3/activity.mjs +76 -0
  438. package/vendor/dragonlab/lib/power-effects.js +294 -0
  439. package/vendor/dragonlab/lib/power-registry.js +74 -0
  440. package/vendor/dragonlab/vendor/quox-dragon/qart.js +348 -0
  441. package/vendor/dragonlab/vendor/quox-dragon/qeyes.js +213 -0
  442. package/lib/core/websiteSession.js +0 -148
@@ -43,4 +43,11 @@ export const safety = {
43
43
  path: () => `/api/v1/safety/history`,
44
44
  tags: ['live-safe'],
45
45
  },
46
+ // QUOXON-STEPUP: a human with a live step-up token overrides ONE blocked action (collector routes/overrides.js).
47
+ 'safety.override': {
48
+ method: 'POST',
49
+ service: 'collector',
50
+ path: () => `/api/v1/overrides`,
51
+ tags: ['live-write'],
52
+ },
46
53
  };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 'server.*' endpoints: moved out of admin.js so each key carries its fragment's own domain prefix.
3
+ * See cli/lib/api/endpoints/index.js for aggregation + the fragment convention.
4
+ */
5
+
6
+ export const server = {
7
+ // DEVFLEET CX-2: server roles registry (role -> url, read before env by resolveServiceUrl). Collector routes;
8
+ // list is instance-admin readable, set/unset/test are instance-OWNER only (see services/collector/server.js).
9
+ 'server.roles.list': {
10
+ method: 'GET', service: 'collector', path: () => '/api/v1/server/roles', tags: ['live-safe'],
11
+ },
12
+ 'server.roles.set': {
13
+ method: 'PUT', service: 'collector', path: ({ role }) => `/api/v1/server/roles/${encodeURIComponent(role)}`, tags: ['admin-write'],
14
+ },
15
+ 'server.roles.unset': {
16
+ method: 'DELETE', service: 'collector', path: ({ role }) => `/api/v1/server/roles/${encodeURIComponent(role)}`, tags: ['admin-write'],
17
+ },
18
+ 'server.roles.test': {
19
+ method: 'POST', service: 'collector', path: ({ role }) => `/api/v1/server/roles/${encodeURIComponent(role)}/test`, tags: ['admin-write'],
20
+ },
21
+ };
@@ -81,6 +81,12 @@ export const setup = {
81
81
  path: ({ pluginId }) => `/api/setup/licensing/seats/${encodeURIComponent(pluginId)}/release-dead`,
82
82
  tags: ['live-write'],
83
83
  },
84
+ 'setup.licensing.seats.release': {
85
+ method: 'POST',
86
+ service: 'auth',
87
+ path: ({ pluginId }) => `/api/setup/licensing/seats/${encodeURIComponent(pluginId)}/release`,
88
+ tags: ['live-write'],
89
+ },
84
90
  'setup.status.list': {
85
91
  method: 'GET',
86
92
  service: 'auth',
@@ -161,6 +161,19 @@ export const skills = {
161
161
  path: ({ qid }) => `/api/quox-skills/review-queue/${qid}/reject`,
162
162
  tags: ['live-write'],
163
163
  },
164
+ // #1006: the crystal store (quoxflow skills.ts), where `skills from-execution` writes; list/show merge it in
165
+ 'skills.crystals.list': {
166
+ method: 'GET',
167
+ service: 'quoxflow',
168
+ path: () => `/api/skills`,
169
+ tags: ['live-safe'],
170
+ },
171
+ 'skills.crystals.get': {
172
+ method: 'GET',
173
+ service: 'quoxflow',
174
+ path: ({ id }) => `/api/skills/${id}`,
175
+ tags: ['live-safe'],
176
+ },
164
177
  'skills.rollbackToVersion': {
165
178
  method: 'POST',
166
179
  service: 'quoxflow',
@@ -171,6 +184,13 @@ export const skills = {
171
184
  // It actually runs a workflow/crystal (side effects beyond a rejected
172
185
  // write); 'skip-live' keeps it out of the live-contract harness entirely
173
186
  // per the WP2.3 brief ("Do NOT seed execute as live").
187
+ // QSKL create (quoxflow quox-skills.ts POST /): firewall-scanned; ?dry_run=true returns the verdict without writing.
188
+ 'skills.create': {
189
+ method: 'POST',
190
+ service: 'quoxflow',
191
+ path: () => `/api/quox-skills`,
192
+ tags: ['live-write'],
193
+ },
174
194
  'skills.run': {
175
195
  method: 'POST',
176
196
  service: 'quoxflow',
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 'stepup.*' endpoints: QUOXON-STEPUP human step-up PIN (auth service routes/stepUp.js).
3
+ * There is deliberately NO endpoint here that sets or changes the PIN: that is a dashboard-only act
4
+ * (browser session plus fresh password). The CLI can read status and verify, nothing else.
5
+ */
6
+
7
+ export const stepup = {
8
+ 'stepup.status': {
9
+ method: 'GET',
10
+ service: 'auth',
11
+ path: () => `/api/auth/me/step-up-pin`,
12
+ tags: ['live-safe'],
13
+ },
14
+ 'stepup.verify': {
15
+ method: 'POST',
16
+ service: 'auth',
17
+ path: () => `/api/auth/me/step-up`,
18
+ tags: ['live-write'],
19
+ },
20
+ };
@@ -43,8 +43,8 @@ export const teams = {
43
43
  },
44
44
  'teams.provisionRoom': {
45
45
  method: 'POST',
46
- service: 'tasks',
47
- path: ({ teamId }) => `/api/teams/${teamId}/provision-room`,
46
+ service: 'auth',
47
+ path: ({ orgId, teamId }) => `/api/orgs/${orgId}/teams/${teamId}/provision-room`,
48
48
  tags: ['live-write'],
49
49
  },
50
50
  'teams.update': {
@@ -67,4 +67,30 @@ export const triggers = {
67
67
  path: () => `/api/triggers/webhooks`,
68
68
  tags: ['live-safe'],
69
69
  },
70
+ // SITE-CLI 2026-10-19: pause/resume a schedule without re-applying the workflow JSON. quoxflow's
71
+ // src/api/routes/schedules.ts (mounted at /api/schedules) is org-scoped (cross-org = 404), persists
72
+ // node.config.paused and emits SCHEDULE.PAUSED / SCHEDULE.RESUMED envelopes.
73
+ 'triggers.schedule-list': {
74
+ method: 'GET',
75
+ service: 'quoxflow',
76
+ path: () => `/api/schedules`,
77
+ tags: ['live-safe'],
78
+ },
79
+ 'triggers.schedule-pause': {
80
+ method: 'POST',
81
+ service: 'quoxflow',
82
+ path: ({ workflowId, nodeId }) => `/api/schedules/${encodeURIComponent(workflowId)}/${encodeURIComponent(nodeId)}/pause`,
83
+ },
84
+ 'triggers.schedule-resume': {
85
+ method: 'POST',
86
+ service: 'quoxflow',
87
+ path: ({ workflowId, nodeId }) => `/api/schedules/${encodeURIComponent(workflowId)}/${encodeURIComponent(nodeId)}/resume`,
88
+ },
89
+ // The public webhook ingress (quoxflow src/api/routes/webhook-triggers.ts, mounted at /webhooks). It copies every
90
+ // request header into the run's trigger data, so the CLI fires it with NO credentials (noAuth).
91
+ 'triggers.webhook-fire': {
92
+ method: 'POST',
93
+ service: 'quoxflow',
94
+ path: ({ path }) => `/webhooks/${path}`,
95
+ },
70
96
  };
@@ -59,6 +59,14 @@ export const v1 = {
59
59
  path: () => `/api/v1/fleet/hosts`,
60
60
  tags: ['live-safe'],
61
61
  },
62
+ // quoxbastion#34 — `quox fleet ping [host]`: governed Bastion host-state
63
+ // refresh (org admin; emits a quox.fleet.ping evidence envelope).
64
+ 'v1.fleet.ping': {
65
+ method: 'POST',
66
+ service: 'collector',
67
+ path: () => `/api/v1/fleet/ping`,
68
+ tags: ['admin-write'],
69
+ },
62
70
  // DEVSUITE-HUB Phase 2 — `quox dev enable` (see lib/commands/dev.js).
63
71
  // Constructs + signs + delivers a quoxagent dev.CapabilityProfile onto a
64
72
  // target host via Bastion. See services/collector/server.js's
@@ -290,12 +298,47 @@ export const v1 = {
290
298
  path: () => `/api/v1/policies/validate`,
291
299
  tags: ['live-write'],
292
300
  },
301
+ // LAZY-AI-CLI: vendor CLIs (Claude Code, Codex) the user's own server installs from npm. Status is any
302
+ // signed-in caller; plan + install need a human instance admin (the binary is instance-wide).
303
+ 'v1.providers.cli.status': {
304
+ method: 'GET',
305
+ service: 'collector',
306
+ path: () => `/api/v1/providers/cli`,
307
+ tags: ['live-safe'],
308
+ },
309
+ 'v1.providers.cli.plan': {
310
+ method: 'GET',
311
+ service: 'collector',
312
+ path: ({ tool }) => `/api/v1/providers/cli/${encodeURIComponent(tool)}/plan`,
313
+ tags: ['live-safe'],
314
+ },
315
+ 'v1.providers.cli.install': {
316
+ method: 'POST',
317
+ service: 'collector',
318
+ path: ({ tool }) => `/api/v1/providers/cli/${encodeURIComponent(tool)}/install`,
319
+ tags: ['live-write'],
320
+ },
321
+ 'v1.providers.cli.job': {
322
+ method: 'GET',
323
+ service: 'collector',
324
+ path: ({ id }) => `/api/v1/providers/cli/jobs/${encodeURIComponent(id)}`,
325
+ tags: ['live-safe'],
326
+ },
293
327
  'v1.tools.execute': {
294
328
  method: 'POST',
295
329
  service: 'collector',
296
330
  path: () => `/api/v1/tools/execute`,
297
331
  tags: ['live-write'],
298
332
  },
333
+ // DEVFLEET: HYPERION VM pool, human REST surface (a human acting directly is the
334
+ // authorization; agents use the proxmox_pool_* tools, which are approval-governed).
335
+ 'v1.proxmox.pool': { method: 'GET', service: 'collector', path: () => `/api/v1/proxmox/pool`, tags: ['live-safe'] },
336
+ 'v1.proxmox.pool.config.put': { method: 'PUT', service: 'collector', path: () => `/api/v1/proxmox/pool/config`, tags: ['live-write'] },
337
+ 'v1.proxmox.pool.lease': { method: 'POST', service: 'collector', path: () => `/api/v1/proxmox/pool/lease`, tags: ['live-write'] },
338
+ 'v1.proxmox.pool.release': { method: 'POST', service: 'collector', path: ({ vmid }) => `/api/v1/proxmox/pool/${encodeURIComponent(vmid)}/release`, tags: ['live-write'] },
339
+ // DEVFLEET-P15: HYPERION activity (VMs, who holds each, node load, recent ops), read only.
340
+ 'v1.proxmox.activity': { method: 'GET', service: 'collector', path: () => `/api/v1/proxmox/activity`, tags: ['live-safe'] },
341
+ 'v1.proxmox.rehearsal': { method: 'GET', service: 'collector', path: ({ id }) => `/api/v1/proxmox/rehearsals/${encodeURIComponent(id)}`, tags: ['live-safe'] },
299
342
  // quox#791: stored outcome of an approved gated tool call.
300
343
  'v1.approvals.result': {
301
344
  method: 'GET',
@@ -303,12 +346,38 @@ export const v1 = {
303
346
  path: ({ id }) => `/api/v1/approvals/${encodeURIComponent(id)}/result`,
304
347
  tags: ['live-safe'],
305
348
  },
349
+ // Fleet standing grants (2026-10-13): org-admin pre-approved ssh_exec lanes.
350
+ 'v1.approvals.grants.list': {
351
+ method: 'GET',
352
+ service: 'collector',
353
+ path: () => `/api/v1/approvals/grants`,
354
+ tags: ['live-safe'],
355
+ },
356
+ 'v1.approvals.grants.create': {
357
+ method: 'POST',
358
+ service: 'collector',
359
+ path: () => `/api/v1/approvals/grants`,
360
+ tags: ['live-write'],
361
+ },
362
+ 'v1.approvals.grants.revoke': {
363
+ method: 'POST',
364
+ service: 'collector',
365
+ path: ({ id }) => `/api/v1/approvals/grants/${encodeURIComponent(id)}/revoke`,
366
+ tags: ['live-write'],
367
+ },
306
368
  'v1.tools.list': {
307
369
  method: 'GET',
308
370
  service: 'collector',
309
371
  path: () => `/api/v1/tools/list`,
310
372
  tags: ['live-safe'],
311
373
  },
374
+ // QUOXON-REACH: registered specialist roster (entity JSONs), used by `quox agent list`.
375
+ 'v1.agents.registry': {
376
+ method: 'GET',
377
+ service: 'collector',
378
+ path: () => `/api/v1/agent-registry`,
379
+ tags: ['live-safe'],
380
+ },
312
381
  // DEVSUITE-GRIPE-P7 / quox#567 (CLI half): agent-to-tool permission
313
382
  // mapping, keyed by agent id (Object.keys(...).agentTools) — the
314
383
  // no-auth-gate source of truth for "which agent ids currently exist",
@@ -431,6 +500,25 @@ export const v1 = {
431
500
  path: ({ name }) => `/api/v1/slots/${encodeURIComponent(name)}/say`,
432
501
  tags: ['live-write'],
433
502
  },
503
+ // QUOXON-BROADCAST: fan one message out to the org's held slots; status and per-slot acks.
504
+ 'v1.slots.broadcast': {
505
+ method: 'POST',
506
+ service: 'collector',
507
+ path: () => `/api/v1/slots/broadcast`,
508
+ tags: ['live-write'],
509
+ },
510
+ 'v1.slots.broadcast.get': {
511
+ method: 'GET',
512
+ service: 'collector',
513
+ path: ({ id }) => `/api/v1/slots/broadcast/${encodeURIComponent(id)}`,
514
+ tags: ['live-safe'],
515
+ },
516
+ 'v1.slots.broadcast.ack': {
517
+ method: 'POST',
518
+ service: 'collector',
519
+ path: ({ id }) => `/api/v1/slots/broadcast/${encodeURIComponent(id)}/ack`,
520
+ tags: ['live-write'],
521
+ },
434
522
  'v1.slots.messages': {
435
523
  method: 'GET',
436
524
  service: 'collector',
@@ -445,6 +533,38 @@ export const v1 = {
445
533
  path: ({ name }) => `/api/v1/slots/${encodeURIComponent(name)}/wait`,
446
534
  tags: ['live-safe'],
447
535
  },
536
+ // QUOXON-MESH: SSE push of a slot's messages (the quox TUI's live inbound).
537
+ 'v1.slots.stream': {
538
+ method: 'GET',
539
+ service: 'collector',
540
+ path: ({ name }) => `/api/v1/slots/${encodeURIComponent(name)}/stream`,
541
+ tags: ['live-safe'],
542
+ },
543
+ // QUOXON-ROOMS: a slot as a group room. Join = subscribe + post without holding.
544
+ 'v1.slots.join': {
545
+ method: 'POST',
546
+ service: 'collector',
547
+ path: ({ name }) => `/api/v1/slots/${encodeURIComponent(name)}/join`,
548
+ tags: ['live-write'],
549
+ },
550
+ 'v1.slots.leave': {
551
+ method: 'POST',
552
+ service: 'collector',
553
+ path: ({ name }) => `/api/v1/slots/${encodeURIComponent(name)}/leave`,
554
+ tags: ['live-write'],
555
+ },
556
+ 'v1.slots.members': {
557
+ method: 'GET',
558
+ service: 'collector',
559
+ path: ({ name }) => `/api/v1/slots/${encodeURIComponent(name)}/members`,
560
+ tags: ['live-safe'],
561
+ },
562
+ 'v1.slots.rooms': {
563
+ method: 'GET',
564
+ service: 'collector',
565
+ path: () => '/api/v1/slot-rooms',
566
+ tags: ['live-safe'],
567
+ },
448
568
  // "Option B" assign model (plan v2 note #2831): assign an expected holder
449
569
  // ahead of time, claim checks out every slot assigned to a session name.
450
570
  'v1.slots.assign': {
@@ -17,6 +17,13 @@ export const ward = {
17
17
  path: () => `/ward/entries`,
18
18
  tags: ['live-safe'],
19
19
  },
20
+ // PEEK: one WARD entry (a receipt) by its ward_entry_id; org-scoped for a user login.
21
+ 'ward.entries.get': {
22
+ method: 'GET',
23
+ service: 'collector',
24
+ path: ({ id }) => `/ward/entries/${id}`,
25
+ tags: ['live-safe'],
26
+ },
20
27
  'ward.stats.list': {
21
28
  method: 'GET',
22
29
  service: 'collector',
@@ -81,6 +81,13 @@ export const workflows = {
81
81
  // quoxflow#7: execute an engine-store workflow directly (the auth-service
82
82
  // runs route only knows auth-store workflows). Org comes from the caller's
83
83
  // auth context server-side, like the other quoxflow-direct entries.
84
+ // #997: `workflow delete` reaches engine workflows (the ones `workflow list` labels "engine")
85
+ 'workflows.applyDelete': {
86
+ method: 'DELETE',
87
+ service: 'quoxflow',
88
+ path: ({ workflowId }) => `/api/workflows/${workflowId}`,
89
+ tags: ['live-write'],
90
+ },
84
91
  'workflows.applyExecute': {
85
92
  method: 'POST',
86
93
  service: 'quoxflow',
@@ -19,6 +19,14 @@ export const x = {
19
19
  path: () => `/x/media`,
20
20
  tags: ['live-write'],
21
21
  },
22
+ // GET /x/activity: recent claims + ledger + live budget (camelCase), org-scoped. `quox x status`
23
+ // reads the budget from here.
24
+ 'x.activity': {
25
+ method: 'GET',
26
+ service: 'collector',
27
+ path: () => `/x/activity`,
28
+ tags: ['live-safe'],
29
+ },
22
30
  };
23
31
 
24
32
  export default x;
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Action Tracker commands (read-only): `quox actions list | get`.
3
+ *
4
+ * #839 / #891: the agent has action_list but the CLI had no verb, so Action
5
+ * Tracker answers could not be checked against CLI truth. These verbs call the
6
+ * SAME governed tool the Action Tracker UI and the agent use (POST
7
+ * /api/v1/tools/execute, tool_name action_list), so chat, UI and CLI read one
8
+ * source. `add` and `done` write through the collector route the dashboard
9
+ * uses (POST/PATCH /api/v1/actions) as the logged-in user, via core/actionItems.js,
10
+ * the same core the Quox TUI /todo uses. Move/update/delete stay in chat and the UI.
11
+ */
12
+
13
+ import { formatOutput, formatDetail, printSuccess } from '../core/output.js';
14
+ import { QuoxError } from '../core/errors.js';
15
+ import { confirmDestructive } from '../core/confirm.js';
16
+ import { executeGovernedTool } from './tool.js';
17
+ import { addActionItem, completeActionItem, moveActionItem, deleteActionItem, STATUS_COLUMNS, PRIORITIES } from '../core/actionItems.js';
18
+
19
+ const STATUSES = ['todo', 'doing', 'done', 'all'];
20
+ const MAX_PAGES = 50;
21
+
22
+ async function listItems(ctx, { status = 'all', limit = 100, scope } = {}) {
23
+ if (!STATUSES.includes(status)) {
24
+ throw new QuoxError(`--status must be one of ${STATUSES.join(', ')}`);
25
+ }
26
+ const pageSize = Math.min(Math.max(Number(limit) || 20, 1), 100);
27
+ // Page through everything: a silent cap at one page hid 4 of 24 items (owner, 2026-10-20).
28
+ const all = [];
29
+ for (let page = 1; page <= MAX_PAGES; page++) {
30
+ const input = { status, limit: pageSize };
31
+ if (scope) input.scope_id = scope;
32
+ if (page > 1) input.page = page;
33
+ const data = await executeGovernedTool(ctx, 'action_list', input);
34
+ const result = data && data.result !== undefined ? data.result : data;
35
+ if (!result || result.success === false) {
36
+ throw new QuoxError(`action_list failed: ${(result && (result.error || result.message)) || 'no result'}`);
37
+ }
38
+ all.push(...(Array.isArray(result.items) ? result.items : []));
39
+ if (!result.hasMore) return all;
40
+ }
41
+ throw new QuoxError(`More than ${MAX_PAGES * pageSize} items; narrow with --status or --scope.`);
42
+ }
43
+
44
+ export function registerActionsCommands(program, ctx) {
45
+ const actions = program
46
+ .command('actions')
47
+ .description('Action Tracker items: list, get, add, done, move, delete (edit in chat or the dashboard)');
48
+
49
+ actions
50
+ .command('list')
51
+ .description('List action items')
52
+ .option('--status <status>', 'todo, doing, done or all', 'all')
53
+ .option('--limit <n>', 'page size (1-100); every page is listed', '100')
54
+ .option('--scope <scopeId>', 'only items in this team/department/division scope')
55
+ .action(async (options) => {
56
+ const items = await listItems({ ...ctx, program }, options);
57
+ formatOutput({
58
+ columns: ['id', 'status', 'priority', 'title', 'dueDate'],
59
+ headers: ['ID', 'Status', 'Priority', 'Title', 'Due'],
60
+ rows: items.map((i) => ({ ...i, dueDate: i.dueDate || '-' })),
61
+ }, { raw: items });
62
+ });
63
+
64
+ actions
65
+ .command('get')
66
+ .description('Show one action item by id')
67
+ .argument('<id>', 'action item id (from `quox actions list`)')
68
+ .action(async (id) => {
69
+ const items = await listItems({ ...ctx, program }, { status: 'all', limit: 100 });
70
+ const item = items.find((i) => i.id === id);
71
+ if (!item) throw new QuoxError(`No action item ${id} among the latest 100 items.`);
72
+ formatDetail(item);
73
+ });
74
+
75
+ actions
76
+ .command('add')
77
+ .description('Add an Action Tracker item (todo) as the logged-in user')
78
+ .argument('<text...>', 'what needs doing')
79
+ .option('--due <date>', 'YYYY-MM-DD, today or tomorrow')
80
+ .option('--priority <priority>', `one of ${PRIORITIES.join(', ')}`)
81
+ .option('--description <text>', 'longer notes')
82
+ .action(async (words, options) => {
83
+ ctx.auth.requireAuth();
84
+ const item = await addActionItem(ctx.client, { title: words, due: options.due, priority: options.priority, description: options.description });
85
+ if (program.opts().output === 'json') return formatDetail(item);
86
+ printSuccess(`Added action item ${item.id}: ${item.title}${item.due_date ? ` (due ${String(item.due_date).slice(0, 10)})` : ''}`);
87
+ return undefined;
88
+ });
89
+
90
+ actions
91
+ .command('done')
92
+ .description('Mark an Action Tracker item done')
93
+ .argument('<id>', 'action item id (from `quox actions list`)')
94
+ .action(async (id) => {
95
+ ctx.auth.requireAuth();
96
+ const item = await completeActionItem(ctx.client, id);
97
+ if (program.opts().output === 'json') return formatDetail(item);
98
+ printSuccess(`Marked done ${item.id}: ${item.title}`);
99
+ return undefined;
100
+ });
101
+
102
+ actions
103
+ .command('move')
104
+ .description('Move an Action Tracker item to todo, doing or done')
105
+ .argument('<id>', 'action item id (from `quox actions list`)')
106
+ .argument('<status>', STATUS_COLUMNS.join(', '))
107
+ .action(async (id, status) => {
108
+ ctx.auth.requireAuth();
109
+ const item = await moveActionItem(ctx.client, id, status);
110
+ if (program.opts().output === 'json') return formatDetail(item);
111
+ printSuccess(`Moved ${item.id} to ${item.status}: ${item.title}`);
112
+ return undefined;
113
+ });
114
+
115
+ actions
116
+ .command('delete')
117
+ .description('Delete one of your Action Tracker items (asks first; --yes skips, required without a terminal)')
118
+ .argument('<id>', 'action item id (from `quox actions list`)')
119
+ .option('-y, --yes', 'do not ask')
120
+ .action(async (id, options) => {
121
+ ctx.auth.requireAuth();
122
+ if (!(await confirmDestructive(program, { force: options.yes === true }, `Delete action item ${id}?`))) {
123
+ console.log('Not deleted.');
124
+ return undefined;
125
+ }
126
+ const r = await deleteActionItem(ctx.client, id);
127
+ if (program.opts().output === 'json') return formatDetail(r);
128
+ printSuccess(`Deleted ${r.id}${r.title ? `: ${r.title}` : ''}`);
129
+ return undefined;
130
+ });
131
+ }
@@ -27,6 +27,13 @@ export function registerAdminCommands(program, ctx) {
27
27
  const config = data.config || data;
28
28
  if (key) {
29
29
  // quox#533: `get <key>` used to be rejected outright.
30
+ // #1010: auth returns an ARRAY of { key, value, ... } rows; an object map is handled too.
31
+ if (Array.isArray(config)) {
32
+ const row = config.find((r) => r && r.key === key);
33
+ if (!row) throw new Error(`config key "${key}" not found. Run \`quox admin config get\` to list all keys.`);
34
+ formatDetail(row, { format: program.opts().output, title: 'Platform Config' });
35
+ return;
36
+ }
30
37
  if (!config || typeof config !== 'object' || !(key in config)) {
31
38
  throw new Error(`config key "${key}" not found. Run \`quox admin config get\` to list all keys.`);
32
39
  }
@@ -345,6 +352,15 @@ export function registerAdminCommands(program, ctx) {
345
352
  const body = {};
346
353
  if (options.dryRun) body.dry_run = true;
347
354
  const data = await client.post(resolveEndpoint('admin.retention.cleanup').path, { service: resolveEndpoint('admin.retention.cleanup').service, body });
355
+ if (options.dryRun) {
356
+ // quox#1084: servers before the fix ignored dry_run and deleted for real.
357
+ // Never present an unconfirmed result as a harmless preview.
358
+ if (!data || data.dry_run !== true) {
359
+ throw new Error('the server did not honour --dry-run (it predates quox#1084): the cleanup may have run for real. Check `quox admin retention stats`.');
360
+ }
361
+ formatDetail(data, { format: program.opts().output, title: 'Cleanup preview (dry run): nothing deleted' });
362
+ return;
363
+ }
348
364
  formatDetail(data, { format: program.opts().output, title: 'Cleanup Result' });
349
365
  });
350
366