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,239 @@
1
+ /**
2
+ * Output formatter for QuoxCLI
3
+ *
4
+ * All commands pass results through this module.
5
+ * Supports: table, json, csv, quiet output modes.
6
+ */
7
+
8
+ import chalk from 'chalk';
9
+ import Table from 'cli-table3';
10
+
11
+ /**
12
+ * Format and print tabular data
13
+ *
14
+ * @param {Object} result - { columns, headers, rows } or array of objects
15
+ * @param {Object} options - { format, title, emptyMessage, full } (full: no 60-char cell truncation in table mode)
16
+ */
17
+ export function formatOutput(result, options = {}) {
18
+ const format = options.format || getOutputFormat();
19
+ const rows = result.rows || result;
20
+ const columns = result.columns || (rows.length > 0 ? Object.keys(rows[0]) : []);
21
+ const headers = result.headers || columns;
22
+
23
+ // options.raw: the untransformed API records behind the display rows.
24
+ // --json exists for scripting, and scripts want DATA keys (name, state,
25
+ // holder_session), not the humanised table cells (NAME, HOLDER, "2d") the
26
+ // display rows carry -- `quox --json slot list` emitting NAME/STATE bit a
27
+ // live harness on 2026-08-20. Table/csv/quiet still render the display
28
+ // rows; json prefers raw when the caller provides it.
29
+ if (!Array.isArray(rows) || rows.length === 0) {
30
+ if (format === 'json') {
31
+ console.log(JSON.stringify(Array.isArray(options.raw) ? options.raw : []));
32
+ } else if (format === 'csv') {
33
+ console.log(headers.join(','));
34
+ } else if (format !== 'quiet') {
35
+ console.log(chalk.dim(options.emptyMessage || 'No results.'));
36
+ }
37
+ return;
38
+ }
39
+
40
+ switch (format) {
41
+ case 'json':
42
+ console.log(JSON.stringify(Array.isArray(options.raw) ? options.raw : rows, null, 2));
43
+ break;
44
+ case 'csv':
45
+ formatCsv(rows, columns, headers);
46
+ break;
47
+ case 'quiet':
48
+ formatQuiet(rows, columns);
49
+ break;
50
+ default:
51
+ formatTable(rows, columns, headers, options);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Format and print a single object (detail view)
57
+ */
58
+ export function formatDetail(obj, options = {}) {
59
+ const format = options.format || getOutputFormat();
60
+
61
+ if (format === 'json') {
62
+ console.log(JSON.stringify(obj, null, 2));
63
+ return;
64
+ }
65
+
66
+ if (format === 'quiet') {
67
+ console.log(obj.id || obj.name || '');
68
+ return;
69
+ }
70
+
71
+ // Key-value display
72
+ const fields = options.fields || Object.keys(obj);
73
+ const labels = options.labels || {};
74
+
75
+ if (options.title) {
76
+ console.log(chalk.bold(options.title));
77
+ console.log(chalk.dim('โ”€'.repeat(Math.min(options.title.length + 10, 60))));
78
+ }
79
+
80
+ const maxLabel = Math.max(...fields.map(f => (labels[f] || f).length));
81
+
82
+ for (const field of fields) {
83
+ const label = (labels[field] || field).padEnd(maxLabel + 2);
84
+ const raw = obj[field];
85
+ if (raw !== null && typeof raw === 'object') {
86
+ console.log(` ${chalk.dim(label)}${formatNestedValue(raw)}`);
87
+ } else {
88
+ const value = formatValue(raw);
89
+ console.log(` ${chalk.dim(label)} ${value}`);
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Recursively render a nested object/array value for formatDetail, instead
96
+ * of falling through to formatValue's String(value) -> "[object Object]".
97
+ * Kept local to formatDetail (not folded into formatValue) so formatTable /
98
+ * formatCsv output is unchanged.
99
+ */
100
+ function formatNestedValue(value, indent = 4) {
101
+ if (value == null) return ` ${chalk.dim('-')}`;
102
+
103
+ if (Array.isArray(value)) {
104
+ if (value.length === 0) return ` ${chalk.dim('[]')}`;
105
+ const allPrimitive = value.every(v => v === null || typeof v !== 'object');
106
+ if (allPrimitive) return ` ${value.map(v => formatValue(v)).join(', ')}`;
107
+ return '\n' + value
108
+ .map(v => `${' '.repeat(indent)}- ${typeof v === 'object' && v !== null ? formatNestedValue(v, indent + 2).trimStart() : formatValue(v)}`)
109
+ .join('\n');
110
+ }
111
+
112
+ const keys = Object.keys(value);
113
+ if (keys.length === 0) return ` ${chalk.dim('{}')}`;
114
+ return '\n' + keys
115
+ .map(k => {
116
+ const v = value[k];
117
+ if (v !== null && typeof v === 'object') {
118
+ return `${' '.repeat(indent)}${chalk.dim(k + ':')}${formatNestedValue(v, indent + 2)}`;
119
+ }
120
+ return `${' '.repeat(indent)}${chalk.dim(k + ':')} ${formatValue(v)}`;
121
+ })
122
+ .join('\n');
123
+ }
124
+
125
+ /**
126
+ * Print a success message
127
+ */
128
+ export function printSuccess(message) {
129
+ const format = getOutputFormat();
130
+ if (format === 'json') {
131
+ console.log(JSON.stringify({ success: true, message }));
132
+ } else if (format !== 'quiet') {
133
+ console.log(chalk.green(message));
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Print a warning message
139
+ */
140
+ export function printWarning(message) {
141
+ if (getOutputFormat() !== 'quiet') {
142
+ console.error(chalk.yellow(message));
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Print info message (suppressed in quiet/json mode)
148
+ */
149
+ export function printInfo(message) {
150
+ const format = getOutputFormat();
151
+ if (format !== 'quiet' && format !== 'json') {
152
+ console.log(chalk.dim(message));
153
+ }
154
+ }
155
+
156
+ // -- Internal helpers --
157
+
158
+ function formatTable(rows, columns, headers, options) {
159
+ const table = new Table({
160
+ head: headers.map(h => chalk.bold(h)),
161
+ style: { head: [], border: [] },
162
+ chars: {
163
+ 'top': '', 'top-mid': '', 'top-left': '', 'top-right': '',
164
+ 'bottom': '', 'bottom-mid': '', 'bottom-left': '', 'bottom-right': '',
165
+ 'left': '', 'left-mid': '', 'mid': '', 'mid-mid': '',
166
+ 'right': '', 'right-mid': '', 'middle': ' ',
167
+ },
168
+ });
169
+
170
+ for (const row of rows) {
171
+ table.push(columns.map(col => formatValue(row[col], options.full === true)));
172
+ }
173
+
174
+ console.log(table.toString());
175
+
176
+ // Show count
177
+ if (rows.length > 10) {
178
+ console.log(chalk.dim(`\n${rows.length} items`));
179
+ }
180
+ }
181
+
182
+ function formatCsv(rows, columns, headers) {
183
+ console.log(headers.map(csvEscape).join(','));
184
+ for (const row of rows) {
185
+ console.log(columns.map(col => csvEscape(row[col])).join(','));
186
+ }
187
+ }
188
+
189
+ function formatQuiet(rows, columns) {
190
+ // Print first column (usually ID) of each row
191
+ const idCol = columns[0];
192
+ for (const row of rows) {
193
+ console.log(row[idCol] ?? '');
194
+ }
195
+ }
196
+
197
+ function csvEscape(value) {
198
+ const str = String(value ?? '');
199
+ if (str.includes(',') || str.includes('"') || str.includes('\n')) {
200
+ return `"${str.replace(/"/g, '""')}"`;
201
+ }
202
+ return str;
203
+ }
204
+
205
+ function formatValue(value, full = false) {
206
+ if (value == null) return chalk.dim('-');
207
+ if (typeof value === 'boolean') return value ? chalk.green('yes') : chalk.dim('no');
208
+
209
+ const str = String(value);
210
+
211
+ // Color status values
212
+ const lower = str.toLowerCase();
213
+ if (['active', 'healthy', 'operational', 'approved', 'online', 'success'].includes(lower)) {
214
+ return chalk.green(str);
215
+ }
216
+ if (['degraded', 'warning', 'pending', 'in_progress', 'draft', 'stale'].includes(lower)) {
217
+ return chalk.yellow(str);
218
+ }
219
+ if (['error', 'down', 'failed', 'rejected', 'retired', 'offline', 'suspended', 'dead'].includes(lower)) {
220
+ return chalk.red(str);
221
+ }
222
+
223
+ // Truncate long values in table mode
224
+ if (!full && str.length > 60) return str.slice(0, 57) + '...';
225
+
226
+ return str;
227
+ }
228
+
229
+ export function getOutputFormat() {
230
+ if (process.argv.includes('--json')) return 'json';
231
+ if (process.argv.includes('-q') || process.argv.includes('--quiet')) return 'quiet';
232
+
233
+ const idx = process.argv.indexOf('-o');
234
+ if (idx !== -1 && process.argv[idx + 1]) return process.argv[idx + 1];
235
+ const idx2 = process.argv.indexOf('--output');
236
+ if (idx2 !== -1 && process.argv[idx2 + 1]) return process.argv[idx2 + 1];
237
+
238
+ return 'table';
239
+ }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * PEEK: look up one id without knowing what it is. `quox peek <id>` and the TUI /peek share this.
3
+ *
4
+ * The id's shape picks the kinds worth asking for (an envelope, inbox item, objective and workflow run
5
+ * are all ULIDs, so a ULID asks all four at once; a WARD receipt is a UUID; an agent is a slug). Every
6
+ * lookup reuses an existing read endpoint. A 404 means "not this kind"; any other failure is kept and
7
+ * said, so an unknown id always names exactly what was tried and what each answered.
8
+ */
9
+ import { resolveEndpoint } from '../api/endpoints.js';
10
+
11
+ const ULID = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
12
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
13
+ const SLUG = /^[a-z][a-z0-9_-]{0,63}$/i;
14
+
15
+ export const KIND_LABEL = { envelope: 'envelope', inbox: 'inbox item', objective: 'objective', run: 'workflow run', receipt: 'WARD receipt', agent: 'agent' };
16
+
17
+ /** -> { id (normalised), kinds: ordered kinds to try, shape: a plain word for the id's shape }. */
18
+ export function idShapes(raw) {
19
+ const id = String(raw ?? '').trim();
20
+ if (!id) return { id, kinds: [], shape: 'empty' };
21
+ if (/^ENV_/i.test(id)) return { id, kinds: ['envelope'], shape: 'envelope id' };
22
+ const obj = id.match(/^OBJ_([0-9A-HJKMNP-TV-Z]{26})$/i); // an objective's corr id
23
+ if (obj) return { id: obj[1], kinds: ['objective'], shape: 'objective correlation id' };
24
+ if (UUID.test(id)) return { id, kinds: ['receipt', 'inbox'], shape: 'UUID' };
25
+ if (ULID.test(id)) return { id: id.toUpperCase(), kinds: ['envelope', 'inbox', 'objective', 'run'], shape: 'ULID' };
26
+ if (SLUG.test(id)) return { id, kinds: ['agent', 'inbox'], shape: 'name' };
27
+ return { id, kinds: [], shape: 'unrecognised' };
28
+ }
29
+
30
+ const unwrap = (d, ...keys) => { for (const k of keys) if (d && d[k] && typeof d[k] === 'object') return d[k]; return d; };
31
+
32
+ /**
33
+ * One fetcher per kind on a CLI client. Each resolves to the object or throws the client's error
34
+ * (with .status). orgId: a function returning the org the caller is acting in (the window org in the TUI).
35
+ */
36
+ export function createPeekFetchers({ client, orgId }) {
37
+ const org = () => { const o = typeof orgId === 'function' ? orgId() : orgId; return typeof o === 'string' && o ? o : null; };
38
+ const get = (name, params, opts = {}) => { const ep = resolveEndpoint(name, params); return client.get(ep.path, { service: ep.service, retries: 0, timeout: 25000, ...opts }); };
39
+ const needOrg = () => { const o = org(); if (!o) { const e = new Error('no org on this login'); e.status = 0; throw e; } return o; };
40
+ return {
41
+ envelope: async (id) => unwrap(await get('aee.get', { id: encodeURIComponent(id) }), 'envelope'),
42
+ inbox: async (id) => unwrap(await get('inbox.get', { orgId: needOrg(), itemId: encodeURIComponent(id) }), 'item'),
43
+ objective: async (id) => unwrap(await get('objectives.get', { id: encodeURIComponent(id) }), 'objective', 'data'),
44
+ run: async (id) => {
45
+ try { return unwrap(await get('executions.get', { executionId: encodeURIComponent(id) }), 'data', 'execution'); }
46
+ catch (e) { if (e?.status !== 404) throw e; }
47
+ return unwrap(await get('runs.get', { orgId: needOrg(), pollRunId: encodeURIComponent(id) }), 'run', 'data');
48
+ },
49
+ receipt: async (id) => unwrap(await get('ward.entries.get', { id: encodeURIComponent(id) }), 'entry'),
50
+ agent: async (id) => {
51
+ try { return unwrap(await get('agents.get', { orgId: needOrg(), agentId: encodeURIComponent(id) }), 'agent'); }
52
+ catch (e) { if (e?.status !== 404) throw e; }
53
+ const reg = await get('v1.agents.registry', {});
54
+ const hit = (reg?.agents || []).find(r => r.agent_id === id || String(r.name || '').toLowerCase() === id.toLowerCase());
55
+ if (!hit) { const e = new Error('Agent not found'); e.status = 404; throw e; }
56
+ return { ...hit, source: 'registry' };
57
+ },
58
+ };
59
+ }
60
+
61
+ const failText = (e) => {
62
+ if (e?.status === 404) return 'not found';
63
+ if (e?.status === 401 || e?.status === 403) return `HTTP ${e.status} (not allowed for this login)`;
64
+ if (e?.status) return `HTTP ${e.status}${e.message ? `: ${String(e.message).slice(0, 80)}` : ''}`;
65
+ return String(e?.message || 'failed').slice(0, 80);
66
+ };
67
+
68
+ /**
69
+ * Ask every candidate kind at once; the first hit in shape order wins, other hits are named.
70
+ * -> { id, shape, hit: { kind, data } | null, also: [kind], tried: [{ kind, result }] }
71
+ */
72
+ export async function peekId(raw, fetchers) {
73
+ const { id, kinds, shape } = idShapes(raw);
74
+ const settled = await Promise.all(kinds.map(async (kind) => {
75
+ try {
76
+ const data = await fetchers[kind](id);
77
+ if (data == null || (typeof data === 'object' && !Object.keys(data).length)) return { kind, result: 'empty answer' };
78
+ return { kind, data };
79
+ } catch (e) { return { kind, result: failText(e) }; }
80
+ }));
81
+ const hits = settled.filter(s => 'data' in s);
82
+ return {
83
+ id, shape,
84
+ hit: hits[0] ? { kind: hits[0].kind, data: hits[0].data } : null,
85
+ also: hits.slice(1).map(s => s.kind),
86
+ tried: settled.map(s => ({ kind: s.kind, result: 'data' in s ? 'found' : s.result })),
87
+ };
88
+ }
89
+
90
+ const s = (v) => (v == null || v === '' ? null : String(v));
91
+ const short = (v, n = 16) => { const t = s(v); return t && t.length > n ? `${t.slice(0, n)}โ€ฆ` : t; };
92
+ const when = (v) => { const t = s(v); return t ? t.replace('T', ' ').replace(/\.\d+Z$/, 'Z') : null; };
93
+ const parse = (v) => { if (v && typeof v === 'object') return v; try { return JSON.parse(v); } catch { return null; } };
94
+
95
+ export const MORE = { envelope: (id) => `quox aee get ${id}`, inbox: (id) => `quox inbox get ${id}`, objective: (id) => `quox objective get ${id}`, run: (id) => `quox run get ${id}`, receipt: () => 'quox governance ward entries', agent: (id) => `quox agent get ${id}` };
96
+
97
+ /** kind -> data -> [[label, value|null]]: the card fields, shared by peekLines and the TUI card. */
98
+ export const ROWS = {
99
+ envelope: (d) => [['intent', s(d.intent)], ['from', s(d.from) && `${d.from} โ†’ ${d.to || '?'}`], ['type', s(d.type)], ['corr', s(d.corr)], ['at', when(d.ts || d.timestamp)]],
100
+ inbox: (d) => { const p = parse(d.payload_json) || {}; return [['title', s(d.title)], ['kind', s(d.kind)], ['status', [d.status, d.priority && `${d.priority} priority`].filter(Boolean).join(', ') || null], ['from', s(p.agent || p.session || p.source || d.created_by)], ['created', when(d.created_at)]]; },
101
+ objective: (d) => [['title', s(d.title)], ['status', s(d.status)], ['tasks', d.task_count != null ? `${d.tasks_completed ?? 0} of ${d.task_count} done${d.tasks_failed ? `, ${d.tasks_failed} failed` : ''}` : null], ['team', s(d.team_id)], ['created', when(d.created_at)]],
102
+ run: (d) => [['workflow', s(d.workflowName || d.workflow_name || d.workflowId || d.workflow_id)], ['status', s(d.status)], ['trigger', s(d.triggerData?.trigger || d.trigger)], ['started', when(d.startedAt || d.started_at || d.createdAt || d.created_at)], ['finished', when(d.finishedAt || d.completedAt || d.completed_at)]],
103
+ receipt: (d) => [['chain', d.chain_id ? `${d.chain_id} #${d.seq ?? '?'}` : null], ['witnessed', s(d.source_kind) && `${d.source_kind} ${d.source_id || ''}`.trim()], ['at', when(d.witnessed_at)], ['hash', short(d.chain_hash)]],
104
+ agent: (d) => [['name', s(d.name)], ['role', [d.role, d.level != null && `level ${d.level}`].filter(Boolean).join(', ') || null], ['about', s(d.description)], ['tools', d.tool_count != null ? String(d.tool_count) : null], ['source', s(d.source)]],
105
+ };
106
+
107
+ /**
108
+ * Plain lines for a peek result: [{ text, tone }] (tone ok | warn | dim | null). Width-agnostic; the caller clips.
109
+ */
110
+ export function peekLines(r) {
111
+ if (!r) return [];
112
+ if (!r.hit) {
113
+ if (r.shape === 'empty') return [{ text: 'Usage: peek <id>. An envelope, inbox item, objective, workflow run, WARD receipt or agent id.', tone: 'warn' }];
114
+ if (!r.tried.length) return [{ text: `"${r.id}" does not look like any id Quox issues (envelope, inbox item, objective, run or agent ULID, WARD receipt UUID, agent name). Nothing was looked up.`, tone: 'warn' }];
115
+ return [
116
+ { text: `Nothing found for ${r.id}.`, tone: 'warn' },
117
+ { text: `Tried (${r.shape}): ${r.tried.map(t => `${KIND_LABEL[t.kind]} ${t.result}`).join(' ยท ')}`, tone: 'dim' },
118
+ ];
119
+ }
120
+ const { kind, data } = r.hit;
121
+ const out = [{ text: `โ—‡ ${KIND_LABEL[kind]} ${r.id}`, tone: 'ok' }];
122
+ for (const [k, v] of ROWS[kind](data || {})) if (v) out.push({ text: ` ${k.padEnd(9)} ${v}`, tone: null });
123
+ if (r.also.length) out.push({ text: ` ${'also'.padEnd(9)} an id of the same value: ${r.also.map(k => KIND_LABEL[k]).join(', ')}`, tone: 'dim' });
124
+ out.push({ text: ` ${'more'.padEnd(9)} ${MORE[kind](r.id)}`, tone: 'dim' });
125
+ return out;
126
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Imported FIRST by the shipped bins (bin/quox.js, bin/quoxon.js), before anything that loads React: ES modules
3
+ * evaluate in import order, and React picks its build from NODE_ENV when it is first loaded. The development
4
+ * build roughly doubles CPU per animation frame (measured: ~51% vs 12-30% at 12 fps, 100x40). An explicit
5
+ * NODE_ENV (a developer's, or a test runner's) is always kept.
6
+ */
7
+ if (!process.env.NODE_ENV) process.env.NODE_ENV = 'production';
@@ -0,0 +1,51 @@
1
+ /**
2
+ * #1034: which OTHER quox processes on this machine use a given CLI profile. `quox org switch` changes the shared
3
+ * profile's default org, so it names the sessions that will follow it (a TUI `/org switch` only moves its own window).
4
+ * Linux /proc only; elsewhere the answer is an empty list. Reads argv and the single QUOX_PROFILE env field, nothing else.
5
+ */
6
+ import { readdirSync, readFileSync } from 'node:fs';
7
+
8
+ const isQuox = (a) => /(^|\/)quox(\.js|\.mjs)?$/.test(String(a || ''));
9
+
10
+ /** The profile a process selected: a name, '' for "the config default", or null when it is not quox. */
11
+ export function profileOf({ argv = [], env = {} }) {
12
+ const at = argv.slice(0, 2).findIndex(isQuox);
13
+ if (at < 0) return null;
14
+ const rest = argv.slice(at + 1);
15
+ for (let i = 0; i < rest.length; i++) {
16
+ const a = rest[i];
17
+ if (a === '-p' || a === '--profile') return rest[i + 1] || '';
18
+ if (a.startsWith('--profile=')) return a.slice('--profile='.length);
19
+ }
20
+ return env.QUOX_PROFILE || '';
21
+ }
22
+
23
+ export function otherProfileUsers({ profile, defaultProfile, procs, selfPids = [] }) {
24
+ const self = new Set(selfPids);
25
+ return procs.filter(p => {
26
+ if (self.has(p.pid)) return false;
27
+ const sel = profileOf(p);
28
+ if (sel === null) return false;
29
+ return sel === profile || (sel === '' && profile === defaultProfile);
30
+ });
31
+ }
32
+
33
+ /** Live processes of this user: [{ pid, argv, env: { QUOX_PROFILE? } }]. */
34
+ export function listProcs(root = '/proc') {
35
+ let dirs;
36
+ try { dirs = readdirSync(root).filter(d => /^\d+$/.test(d)); } catch { return []; }
37
+ const out = [];
38
+ for (const d of dirs) {
39
+ try {
40
+ const argv = readFileSync(`${root}/${d}/cmdline`, 'utf8').split('\0').filter(Boolean);
41
+ if (!argv.slice(0, 2).some(isQuox)) continue;
42
+ let env = {};
43
+ try {
44
+ const line = readFileSync(`${root}/${d}/environ`, 'utf8').split('\0').find(l => l.startsWith('QUOX_PROFILE='));
45
+ if (line) env = { QUOX_PROFILE: line.slice('QUOX_PROFILE='.length) };
46
+ } catch { /* not ours to read */ }
47
+ out.push({ pid: Number(d), argv, env });
48
+ } catch { /* exited */ }
49
+ }
50
+ return out;
51
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * #1101: Ctrl-C (or a closed stdin) at an inquirer prompt rejects with ExitPromptError
3
+ * ("User force closed the prompt with SIGINT"). That is the user leaving, not a crash: say so in one word,
4
+ * put the cursor back, and exit 130 instead of printing a raw Error line.
5
+ */
6
+ export const PROMPT_CANCELLED = 'Cancelled.';
7
+
8
+ export function isPromptCancel(err) {
9
+ if (!err) return false;
10
+ return err.name === 'ExitPromptError' || /User force closed the prompt/.test(String(err.message || ''));
11
+ }
12
+
13
+ export function exitOnPromptCancel(err, { stderr = process.stderr, exit = process.exit } = {}) {
14
+ if (!isPromptCancel(err)) return false;
15
+ try { stderr.write(`\x1b[?25h\n${PROMPT_CANCELLED}\n`); } catch { /* the exit still happens */ }
16
+ exit(130);
17
+ return true;
18
+ }
@@ -0,0 +1,158 @@
1
+ /**
2
+ * @quox/glyph โ€” the canonical JS implementation of the QuoxGlyph terminal
3
+ * output language (DEVSUITE-GLYPH). Spec: quox-skills
4
+ * quoxify/references/quoxglyph-spec.md. This package IS the spec's constants:
5
+ * ports must consume it (or test against it), never re-type the values.
6
+ *
7
+ * Grammar: <icon> NAME โ”‚ <verb object> โ”‚ <result> ยท <duration> [status]
8
+ * Colour: truecolor, degrades to plain when !isTTY or NO_COLOR.
9
+ * Brand gradient #38bdf8 -> #a855f7; rainbow RESERVED for completed.
10
+ */
11
+
12
+ export const GRAD = [[56, 189, 248], [168, 85, 247]];
13
+ export const RAINBOW = [
14
+ [255, 59, 48], [255, 149, 0], [255, 204, 0], [52, 199, 89],
15
+ [0, 199, 190], [10, 132, 255], [94, 92, 230], [191, 90, 242]
16
+ ];
17
+ export const STATUS = {
18
+ ok: { glyph: 'โœ”', rgb: [48, 209, 88] },
19
+ fail: { glyph: 'โœ–', rgb: [255, 69, 58] },
20
+ busy: { glyph: 'โ—', rgb: [56, 189, 248] },
21
+ warn: { glyph: 'โš ', rgb: [255, 214, 10] },
22
+ block: { glyph: 'โ›”', rgb: null }
23
+ };
24
+ export const ICONS = {
25
+ repobrain: '๐Ÿง  REPOBRAIN', clarify: '๐Ÿ” CLARIFY', qlarity: '๐Ÿ” QLARITY',
26
+ quoxplan: '๐Ÿงญ QUOXPLAN', doneengine: '๐Ÿ DONEENGINE', quoxbuild: '๐Ÿ”จ QUOXBUILD',
27
+ quoxsignal: '๐Ÿ“ก QUOXSIGNAL', bastion: '๐Ÿ›ฐ๏ธ BASTION', precompact: '๐Ÿงฟ PRECOMPACT',
28
+ brain2: '๐ŸŒŒ QORTEX',
29
+ watchtower: '๐Ÿ“จ WATCHTOWER', metron: 'โณ METRON',
30
+ quoxseo: '๐Ÿ“ˆ QUOXSEO', reach: '๐Ÿ’ฅ REACH', vulcan: '๐ŸŒ‹ VULCAN',
31
+ quoxvoice: '๐Ÿ“ž QUOXVOICE', quoxsecurity: '๐Ÿ›ก๏ธ QUOXSECURITY', quoxpert: '๐ŸŽ“ QUOXPERT',
32
+ quoxslots: '๐Ÿ“ QUOXSLOTS',
33
+ quox: 'โ“† QUOX'
34
+ };
35
+ export const BUDGETS = { VERB_MAX: 48, RESULT_MAX: 40, LINE_MAX: 120, TREE_MAX: 6, TABLE_MAX: 6 };
36
+ export const PUA_Q = '๎ง€'; // real horned Q, served by QuoxSymbols font
37
+
38
+ const R = '\x1b[0m', DIM = '\x1b[2m', BOLD = '\x1b[1m';
39
+ const fg = ([r, g, b]) => `\x1b[38;2;${r};${g};${b}m`;
40
+
41
+ let forced = null;
42
+ /** Force colour on/off (null = auto: isTTY && !NO_COLOR). */
43
+ export function setColor(v) { forced = v; }
44
+ function on() {
45
+ if (forced !== null) return forced;
46
+ const env = process.env.QUOX_COLOR;
47
+ if (env === '0') return false;
48
+ if (env === '1' || env === '2') return true;
49
+ return Boolean(process.stdout && process.stdout.isTTY) && !process.env.NO_COLOR;
50
+ }
51
+
52
+ function iconFor(surface) {
53
+ let name = ICONS[surface] || `โ“† ${String(surface).toUpperCase()}`;
54
+ if (process.env.QUOX_BRAND_FONT === '1') name = name.replace('โ“†', PUA_Q);
55
+ return name;
56
+ }
57
+
58
+ /** "<icon> NAME" with NAME painted in the brand gradient, bold, so a Quox
59
+ * line stands out in tool output (owner 2026-10-05). Plain when colour is off. */
60
+ export function brandName(label, col = on()) {
61
+ if (!col) return label;
62
+ const i = label.indexOf(' ');
63
+ const icon = i > 0 ? label.slice(0, i) : '';
64
+ const chars = [...(i > 0 ? label.slice(i + 1) : label)];
65
+ const last = Math.max(chars.length - 1, 1);
66
+ const painted = chars.map((c, k) => fg(GRAD[0].map((v, j) => Math.round(v + (GRAD[1][j] - v) * k / last))) + c).join('');
67
+ return `${icon ? icon + ' ' : ''}${BOLD}${painted}${R}`;
68
+ }
69
+
70
+ const trunc = (s, max) => ([...s].length > max ? [...s].slice(0, max - 1).join('') + 'โ€ฆ' : s);
71
+
72
+ /** The grammar event line. opts: {result, ms, status} */
73
+ export function line(surface, verb, opts = {}) {
74
+ const col = on();
75
+ const name = brandName(iconFor(surface), col);
76
+ const sep = col ? `${DIM}โ”‚${R}` : 'โ”‚';
77
+ let tail = opts.result ? trunc(opts.result, BUDGETS.RESULT_MAX) : '';
78
+ if (opts.ms !== undefined) {
79
+ const d = col ? `${DIM}${opts.ms}ms${R}` : `${opts.ms}ms`;
80
+ tail = tail ? `${tail} ${col ? DIM + 'ยท' + R : 'ยท'} ${d}` : d;
81
+ }
82
+ const s = opts.status && STATUS[opts.status];
83
+ if (s) tail += ' ' + (col && s.rgb ? `${fg(s.rgb)}${s.glyph}${R}` : s.glyph);
84
+ const v = trunc(verb, BUDGETS.VERB_MAX);
85
+ return tail ? `${name} ${sep} ${v} ${sep} ${tail}` : `${name} ${sep} ${v}`;
86
+ }
87
+
88
+ /** Gradient progress meter: โ–ฐโ–ฐโ–ฐโ–ฑ done/total (or pct when total omitted). */
89
+ export function meter(done, total, width = 8) {
90
+ const col = on();
91
+ const pct = total === undefined || total === null;
92
+ const ratio = pct ? Math.min(100, Math.max(0, done)) / 100 : (total > 0 ? done / total : 0);
93
+ const filled = Math.round(ratio * width);
94
+ const last = Math.max(1, width - 1);
95
+ let bar = '';
96
+ for (let i = 0; i < filled; i++) {
97
+ if (col) {
98
+ const t = i / last;
99
+ bar += fg(GRAD[0].map((v, k) => Math.round(v + (GRAD[1][k] - v) * t)));
100
+ }
101
+ bar += 'โ–ฐ';
102
+ }
103
+ if (col && filled) bar += R;
104
+ bar += (col ? DIM : '') + 'โ–ฑ'.repeat(Math.max(0, width - filled)) + (col ? R : '');
105
+ return pct ? `${bar} ${done}%` : `${bar} ${done}/${total}`;
106
+ }
107
+
108
+ /** Rainbow text. RESERVED for the `completed` lifecycle event. */
109
+ export function celebrate(text) {
110
+ if (!on()) return text;
111
+ const chars = [...text];
112
+ const last = Math.max(1, chars.length - 1);
113
+ return chars.map((ch, i) => {
114
+ const t = (i / last) * (RAINBOW.length - 1);
115
+ const seg = Math.min(RAINBOW.length - 2, Math.floor(t));
116
+ const local = t - seg;
117
+ return fg(RAINBOW[seg].map((v, k) => Math.round(v + (RAINBOW[seg + 1][k] - v) * local))) + ch;
118
+ }).join('') + R;
119
+ }
120
+
121
+ /** WARD receipt footer. */
122
+ export function receipt(hash, ts) {
123
+ const col = on();
124
+ const chain = col ? `${fg([168, 85, 247])}โ›“${R}` : 'โ›“';
125
+ const label = col ? `${DIM}ward:${R}` : 'ward:';
126
+ const t = ts ? (col ? ` ${DIM}ยท witnessed ${ts}${R}` : ` ยท witnessed ${ts}`) : '';
127
+ return `${chain} ${label}${String(hash).slice(0, 12)}${t}`;
128
+ }
129
+
130
+ /**
131
+ * Lifecycle events (spec section 4b): the contract every product emits.
132
+ * Each returns a rendered line; the caller prints it.
133
+ */
134
+ export const events = {
135
+ created: (surface, thing, id) => line(surface, `${thing} created`, { result: id, status: 'ok' }),
136
+ updated: (surface, thing, id, delta) =>
137
+ line(surface, `${thing} updated`, { result: delta ? `${id} ${delta}` : id, status: 'ok' }),
138
+ progressed: (surface, step, id, done, total) =>
139
+ line(surface, step, { result: `${id} ${meter(done, total)}` }),
140
+ completed: (surface, thing, text) => line(surface, thing, { result: celebrate(text) }),
141
+ assigned: (surface, thing, holder) => line(surface, `${thing} assigned`, { result: holder, status: 'busy' }),
142
+ released: (surface, thing, id) => line(surface, `${thing} released`, { result: id, status: 'ok' }),
143
+ failed: (surface, thing, why) => line(surface, `${thing} failed`, { result: why, status: 'fail' }),
144
+ warned: (surface, thing, risk) => line(surface, thing, { result: risk, status: 'warn' })
145
+ };
146
+
147
+ // ---- quoxcli integration (not part of the @quox/glyph copy above) ----
148
+ // VENDORED from quox-plugin-sdk packages/quox-glyph/index.js until the
149
+ // owner-gated npm publish lands; the lockstep test in quoxglyph.test.js
150
+ // fails if this copy drifts from the package.
151
+ import { getOutputFormat } from './output.js';
152
+
153
+ /** Print a rendered glyph line, respecting --output json/quiet. */
154
+ export function printEvent(rendered) {
155
+ const format = getOutputFormat();
156
+ if (format === 'json' || format === 'quiet') return;
157
+ console.log(` ${rendered}`);
158
+ }
@@ -0,0 +1,11 @@
1
+ // Repo-relative path normaliser for loosening asks. Keep in step with services/auth/lib/repoPath.js and
2
+ // scripts/guards/check-test-loosening.mjs (cli/test/core/repoPath.test.js asserts all three agree).
3
+ // "<anywhere>/quox-dashboard-wt-x/cli/a.test.js" -> "cli/a.test.js"; "./cli/a.test.js" -> "cli/a.test.js".
4
+ export function toRepoRelative(p) {
5
+ let s = String(p ?? '').trim().replace(/\\/g, '/');
6
+ s = s.replace(/^(?:.*?\/)?quox-dashboard(?:-wt-[^/]+)?\//, '');
7
+ s = s.replace(/^(?:\.\/)+/, '').replace(/^\/+/, '');
8
+ return s;
9
+ }
10
+
11
+ export const LOOSENING_HINT = 'quox ask loosening --paths <repo-relative test files...> --justify "<why it is safe, plain words>"';