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,229 @@
1
+ /**
2
+ * SSO commands: org SSO provider registry (OIDC + SAML admin CRUD)
3
+ *
4
+ * quox sso providers list|get|create|update|delete|saml-metadata
5
+ *
6
+ * Backend: services/auth/routes/sso.js, mounted at plain `/api`
7
+ * (org-scoped IN the URL for admin routes: /api/orgs/:orgId/sso/providers...).
8
+ * Enterprise-tier + ORG_MANAGE_SSO gated — expect 402/403 on non-enterprise
9
+ * orgs.
10
+ *
11
+ * `saml-metadata` is the one exception: its backend route has NO orgId
12
+ * segment (`/api/sso/providers/:providerId/saml-metadata`) and is public
13
+ * (no auth chain) — see endpoints/sso.js for the full finding. It only
14
+ * works for providers whose protocol is 'saml'.
15
+ *
16
+ * The browser-flow login/callback/discover routes are intentionally not
17
+ * exposed here — they're 302-redirect handshakes, not CLI-shaped.
18
+ */
19
+
20
+ import { readFileSync } from 'node:fs';
21
+ import { formatOutput, formatDetail, printSuccess, printWarning, printInfo } from '../core/output.js';
22
+ import { resolveOrgId, parseJSON } from './helpers.js';
23
+ import { resolveEndpoint } from '../api/endpoints.js';
24
+
25
+ /** Build a create/update body from the shared provider flags. */
26
+ function buildProviderBody(options) {
27
+ const body = {};
28
+ if (options.protocol) body.protocol = options.protocol;
29
+ if (options.key) body.provider_key = options.key;
30
+ if (options.displayName) body.display_name = options.displayName;
31
+ if (options.enabled) body.enabled = true;
32
+ if (options.disabled) body.enabled = false;
33
+ if (options.ssoOnly) body.sso_only = true;
34
+ if (options.emailDomains) {
35
+ body.email_domains = options.emailDomains.split(',').map(d => d.trim()).filter(Boolean);
36
+ }
37
+ // OIDC
38
+ if (options.issuer) body.issuer = options.issuer;
39
+ if (options.clientId) body.client_id = options.clientId;
40
+ if (options.clientSecret) body.client_secret = options.clientSecret;
41
+ if (options.authzUrl) body.authz_url = options.authzUrl;
42
+ if (options.tokenUrl) body.token_url = options.tokenUrl;
43
+ if (options.userinfoUrl) body.userinfo_url = options.userinfoUrl;
44
+ if (options.jwksUri) body.jwks_uri = options.jwksUri;
45
+ if (options.scopes) body.scopes = options.scopes.split(',').map(s => s.trim()).filter(Boolean);
46
+ // SAML
47
+ if (options.entityId) body.entity_id = options.entityId;
48
+ if (options.ssoUrl) body.sso_url = options.ssoUrl;
49
+ if (options.sloUrl) body.slo_url = options.sloUrl;
50
+ if (options.x509CertFile) body.x509_cert = readFileSync(options.x509CertFile, 'utf-8');
51
+ if (options.nameidFormat) body.nameid_format = options.nameidFormat;
52
+ if (options.attributeMap) body.attribute_map = parseJSON(options.attributeMap, '--attribute-map');
53
+ if (options.groupRoleMap) body.group_role_map = parseJSON(options.groupRoleMap, '--group-role-map');
54
+ return body;
55
+ }
56
+
57
+ function addProviderFlags(cmd) {
58
+ return cmd
59
+ .option('--protocol <protocol>', 'oidc|saml (create defaults to oidc)')
60
+ .option('--display-name <name>', 'human-readable name')
61
+ .option('--enabled', 'enable the provider')
62
+ .option('--disabled', 'disable the provider')
63
+ .option('--sso-only', 'require SSO for matching email domains (disable password login)')
64
+ .option('--email-domains <domains>', 'comma-separated email domains routed to this provider')
65
+ .option('--issuer <url>', '[oidc] issuer URL')
66
+ .option('--client-id <id>', '[oidc] client ID')
67
+ .option('--client-secret <secret>', '[oidc] client secret')
68
+ .option('--authz-url <url>', '[oidc] authorization endpoint (optional, discovered if omitted)')
69
+ .option('--token-url <url>', '[oidc] token endpoint')
70
+ .option('--userinfo-url <url>', '[oidc] userinfo endpoint')
71
+ .option('--jwks-uri <url>', '[oidc] JWKS URI')
72
+ .option('--scopes <scopes>', '[oidc] comma-separated scopes (default: openid,email,profile)')
73
+ .option('--entity-id <id>', '[saml] IdP entity ID')
74
+ .option('--sso-url <url>', '[saml] IdP SSO URL')
75
+ .option('--slo-url <url>', '[saml] IdP SLO URL')
76
+ .option('--x509-cert-file <path>', '[saml] path to the IdP\'s PEM-encoded x509 certificate')
77
+ .option('--nameid-format <format>', '[saml] NameID format')
78
+ .option('--attribute-map <json>', '[saml] attribute mapping as a JSON object')
79
+ .option('--group-role-map <json>', '[saml] group-to-role mapping as a JSON object');
80
+ }
81
+
82
+ export function registerSsoCommands(program, ctx) {
83
+ const { client, auth } = ctx;
84
+
85
+ const sso = program
86
+ .command('sso')
87
+ .description('Manage org SSO providers (enterprise — OIDC/SAML admin)');
88
+
89
+ const providers = sso
90
+ .command('providers')
91
+ .description('Manage SSO provider configurations');
92
+
93
+ // ── sso providers list ──────────────────────────────────────────────────────
94
+
95
+ providers
96
+ .command('list')
97
+ .description('List SSO providers for the active org')
98
+ .action(async () => {
99
+ auth.requireAuth();
100
+ const orgId = resolveOrgId(auth, program);
101
+ const ep = resolveEndpoint('sso.providers.list', { orgId });
102
+ const data = await client.get(ep.path, { service: ep.service });
103
+ const rows = data.providers || data || [];
104
+
105
+ formatOutput({
106
+ columns: ['id', 'protocol', 'provider_key', 'display_name', 'enabled', 'sso_only', 'created_at'],
107
+ headers: ['ID', 'Protocol', 'Key', 'Display Name', 'Enabled', 'SSO Only', 'Created'],
108
+ rows,
109
+ }, { format: program.opts().output, emptyMessage: 'No SSO providers configured.' });
110
+ });
111
+
112
+ // ── sso providers get ───────────────────────────────────────────────────────
113
+
114
+ providers
115
+ .command('get')
116
+ .description('Show SSO provider details')
117
+ .argument('<providerId>', 'provider ID')
118
+ .action(async (providerId) => {
119
+ auth.requireAuth();
120
+ const orgId = resolveOrgId(auth, program);
121
+ const ep = resolveEndpoint('sso.providers.get', { orgId, providerId });
122
+ const data = await client.get(ep.path, { service: ep.service });
123
+ const provider = data.provider || data;
124
+
125
+ formatDetail(provider, {
126
+ format: program.opts().output,
127
+ title: `SSO Provider: ${provider.display_name || provider.provider_key || providerId}`,
128
+ fields: [
129
+ 'id', 'protocol', 'provider_key', 'display_name', 'enabled', 'sso_only',
130
+ 'issuer', 'client_id', 'authz_url', 'token_url', 'userinfo_url', 'jwks_uri', 'scopes',
131
+ 'entity_id', 'sso_url', 'slo_url', 'nameid_format', 'attribute_map', 'group_role_map',
132
+ 'email_domains', 'created_at', 'updated_at',
133
+ ],
134
+ });
135
+ });
136
+
137
+ // ── sso providers create ────────────────────────────────────────────────────
138
+
139
+ addProviderFlags(
140
+ providers
141
+ .command('create')
142
+ .description('Create an SSO provider')
143
+ .requiredOption('--key <providerKey>', 'unique provider key (e.g. "okta", "google-workspace")'),
144
+ ).action(async (options) => {
145
+ auth.requireAuth();
146
+ const orgId = resolveOrgId(auth, program);
147
+ const body = buildProviderBody(options);
148
+
149
+ const ep = resolveEndpoint('sso.providers.create', { orgId });
150
+ const data = await client.post(ep.path, { service: ep.service, body });
151
+ printSuccess(`SSO provider "${options.key}" created.`);
152
+ formatDetail(data.provider || data, { format: program.opts().output });
153
+ });
154
+
155
+ // ── sso providers update ────────────────────────────────────────────────────
156
+
157
+ addProviderFlags(
158
+ providers
159
+ .command('update')
160
+ .description('Update an SSO provider')
161
+ .argument('<providerId>', 'provider ID'),
162
+ ).action(async (providerId, options) => {
163
+ auth.requireAuth();
164
+ const orgId = resolveOrgId(auth, program);
165
+ const body = buildProviderBody(options);
166
+
167
+ if (Object.keys(body).length === 0) {
168
+ throw new Error('Specify at least one field to update.');
169
+ }
170
+
171
+ const ep = resolveEndpoint('sso.providers.update', { orgId, providerId });
172
+ const data = await client.patch(ep.path, { service: ep.service, body });
173
+ printSuccess('SSO provider updated.');
174
+ formatDetail(data.provider || data, { format: program.opts().output });
175
+ });
176
+
177
+ // ── sso providers delete ────────────────────────────────────────────────────
178
+
179
+ providers
180
+ .command('delete')
181
+ .description('Delete an SSO provider')
182
+ .argument('<providerId>', 'provider ID')
183
+ .option('--force', 'skip confirmation')
184
+ .action(async (providerId, options) => {
185
+ auth.requireAuth();
186
+ const orgId = resolveOrgId(auth, program);
187
+
188
+ if (!options.force && !program.opts().yes) {
189
+ const { default: inquirer } = await import('inquirer');
190
+ const ans = await inquirer.prompt([{
191
+ type: 'confirm',
192
+ name: 'confirm',
193
+ message: `Delete SSO provider ${providerId}? Users routed to it will fall back to password login.`,
194
+ default: false,
195
+ }]);
196
+ if (!ans.confirm) {
197
+ printInfo('Cancelled.');
198
+ return;
199
+ }
200
+ }
201
+
202
+ const ep = resolveEndpoint('sso.providers.delete', { orgId, providerId });
203
+ await client.delete(ep.path, { service: ep.service });
204
+ printSuccess('SSO provider deleted.');
205
+ });
206
+
207
+ // ── sso providers saml-metadata ─────────────────────────────────────────────
208
+
209
+ providers
210
+ .command('saml-metadata')
211
+ .description('Fetch the SP metadata XML for a SAML provider (paste into your IdP)')
212
+ .argument('<providerId>', 'provider ID (must be a SAML provider)')
213
+ .action(async (providerId) => {
214
+ auth.requireAuth();
215
+ // This backend route is public and NOT org-scoped in the URL — see
216
+ // endpoints/sso.js's header note. No orgId is sent.
217
+ const ep = resolveEndpoint('sso.providers.saml-metadata', { providerId });
218
+ const data = await client.get(ep.path, { service: ep.service });
219
+ // The route returns `application/xml`, so client.get() hands back
220
+ // `{ success: true, text: '<...xml...>' }` (its non-JSON-content-type
221
+ // fallback) rather than a parsed body.
222
+ const xml = data?.text ?? data;
223
+ if (program.opts().output === 'json') {
224
+ console.log(JSON.stringify({ metadata: xml }, null, 2));
225
+ } else {
226
+ console.log(typeof xml === 'string' ? xml : JSON.stringify(xml, null, 2));
227
+ }
228
+ });
229
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * quox status — Platform Pulse
3
+ *
4
+ * Displays a one-screen overview of the entire Quox platform:
5
+ * services, fleet, sessions, vault, memory, AEE, workflows.
6
+ *
7
+ * CLI-3a (Stream CLI Phase 3)
8
+ */
9
+
10
+ import chalk from 'chalk';
11
+ import { emitCliEvent } from '../core/aee.js';
12
+ import { resolveEndpoint } from '../api/endpoints.js';
13
+
14
+ const STATUS_ICON = {
15
+ ok: chalk.green('●'),
16
+ degraded: chalk.yellow('●'),
17
+ down: chalk.red('●'),
18
+ };
19
+
20
+ function statusDot(status) {
21
+ return STATUS_ICON[status] || chalk.dim('○');
22
+ }
23
+
24
+ function renderPulse(data) {
25
+ const lines = [];
26
+
27
+ // Header
28
+ const scoreColor = data.score >= 90 ? chalk.green : data.score >= 70 ? chalk.yellow : chalk.red;
29
+ lines.push('');
30
+ lines.push(chalk.bold(` QUOX PLATFORM STATUS`) + chalk.dim(` ${scoreColor(`Health: ${data.score}%`)} ${data.timestamp || ''}`));
31
+ lines.push(chalk.dim(' ' + '─'.repeat(60)));
32
+
33
+ // Services
34
+ const svcLine = Object.entries(data.services || {})
35
+ .map(([name, s]) => `${statusDot(s.status)} ${name}`)
36
+ .join(' ');
37
+ lines.push(` Services ${svcLine}`);
38
+
39
+ // Fleet
40
+ const f = data.fleet || {};
41
+ lines.push(` Fleet ${f.total || 0} agents (${chalk.green(f.healthy || 0)} healthy, ${chalk.yellow(f.degraded || 0)} degraded, ${chalk.red(f.down || 0)} down)`);
42
+
43
+ // Sessions
44
+ const s = data.sessions || {};
45
+ const providers = Object.entries(s.providers || {}).map(([k, v]) => `${v} ${k}`).join(', ');
46
+ lines.push(` Sessions ${s.active || 0} active ${providers ? `(${providers})` : ''} ${chalk.dim(`$${(s.cost_today_usd || 0).toFixed(2)} today`)}`);
47
+
48
+ // Workflows
49
+ const w = data.workflows || {};
50
+ const wfParts = [];
51
+ if (w.running) wfParts.push(`${w.running} running`);
52
+ if (w.pending_approval) wfParts.push(`${w.pending_approval} pending approval`);
53
+ if (wfParts.length) lines.push(` Workflows ${wfParts.join(', ')}`);
54
+
55
+ // Vault
56
+ const v = data.vault || {};
57
+ if (v.total) {
58
+ const vaultWarn = v.expiring_soon > 0 ? chalk.yellow(` (${v.expiring_soon} expiring soon)`) : '';
59
+ lines.push(` Vault ${v.total} creds (${chalk.green(v.healthy)} healthy)${vaultWarn}`);
60
+ }
61
+
62
+ // Memory
63
+ const m = data.memory || {};
64
+ if (m.entries) {
65
+ const size = m.vector_size_gb ? ` ${m.vector_size_gb}GB vectors` : '';
66
+ lines.push(` Memory ${m.entries.toLocaleString()} entries${size}`);
67
+ }
68
+
69
+ // AEE
70
+ const a = data.aee || {};
71
+ if (a.envelopes_today) {
72
+ const integrity = a.chain_ok ? chalk.green('✓') : chalk.red('✗');
73
+ lines.push(` AEE ${a.envelopes_today.toLocaleString()} envelopes today chain integrity ${integrity}`);
74
+ }
75
+
76
+ lines.push('');
77
+ return lines.join('\n');
78
+ }
79
+
80
+ export function registerStatusCommand(program, ctx) {
81
+ const { client } = ctx;
82
+
83
+ program
84
+ .command('status')
85
+ .description('Show platform health and status overview')
86
+ .action(async (opts, cmd) => {
87
+ const outputFormat = cmd.parent?.opts()?.output || 'table';
88
+ const isJson = outputFormat === 'json' || cmd.parent?.opts()?.json;
89
+
90
+ try {
91
+ // fleet #602: this used to pass noAuth: true, which suppressed the
92
+ // Authorization header the client would otherwise attach. The TUI's
93
+ // useHealth/HealthView poll this same endpoint WITH the normal client
94
+ // auth, as does a comparable authenticated route (backup.js).
95
+ // (monitoring.js's `health` verb had the identical noAuth bug — fixed
96
+ // in the same change.) Dropping noAuth here matches that pattern: the
97
+ // request still works
98
+ // for a logged-out session (client.js sends no Authorization header
99
+ // when there's nothing stored), but a logged-in session's token now
100
+ // actually reaches the collector instead of being withheld.
101
+ const data = await client.get(resolveEndpoint('v1.health.aggregate.list').path, {
102
+ service: resolveEndpoint('v1.health.aggregate.list').service,
103
+ timeout: 15000, // #930: the aggregate fans out to several services; 5s was too tight under load
104
+ });
105
+
106
+ if (isJson) {
107
+ console.log(JSON.stringify(data, null, 2));
108
+ } else {
109
+ console.log(renderPulse(data));
110
+ }
111
+
112
+ emitCliEvent(client, {
113
+ command: 'status',
114
+ intent: 'quox.cli.status',
115
+ payload: { score: data.score, services: Object.keys(data.services || {}).length },
116
+ });
117
+ } catch (err) {
118
+ if (isJson) {
119
+ console.log(JSON.stringify({ error: 'collector_unavailable', message: err.message }));
120
+ } else {
121
+ console.log('');
122
+ console.log(chalk.red(' Platform status unavailable'));
123
+ console.log(chalk.dim(` Collector not reachable: ${err.message}`));
124
+ console.log('');
125
+ }
126
+ // fleet #602: a real request failure (network error, non-2xx from
127
+ // the collector) was printing the message above and still exiting
128
+ // 0, hiding the failure from scripts/CI that check the exit code.
129
+ // client.get only reaches this catch on an actual error (thrown
130
+ // QuoxApiError / QuoxNetworkError / QuoxAuthError, see
131
+ // lib/core/client.js) — never on a successful 2xx — so it's safe to
132
+ // fail the process here without risking a false failure on a
133
+ // legitimately-empty-but-200 status payload.
134
+ process.exitCode = 1;
135
+ }
136
+ });
137
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Tag commands
3
+ *
4
+ * quox tag list|create|update|delete
5
+ */
6
+
7
+ import { formatOutput, formatDetail, printSuccess, printInfo } from '../core/output.js';
8
+ import { resolveOrgId } from './helpers.js';
9
+ import { resolveEndpoint } from '../api/endpoints.js';
10
+ import { confirmDestructive } from '../core/confirm.js';
11
+
12
+ export function registerTagCommands(program, ctx) {
13
+ const { client, auth } = ctx;
14
+
15
+ const tag = program
16
+ .command('tag')
17
+ .description('Manage tags');
18
+
19
+ tag
20
+ .command('list')
21
+ .description('List tags')
22
+ .action(async () => {
23
+ auth.requireAuth();
24
+ const orgId = resolveOrgId(auth, program);
25
+ // fleet #392: the route only computes usage when include_counts=true,
26
+ // which was never sent — so Count was hardcoded 0 for every tag.
27
+ const data = await client.get(resolveEndpoint('tags.list', { orgId }).path, { service: resolveEndpoint('tags.list', { orgId }).service, query: { include_counts: 'true' } });
28
+ const tags = data.tags || data || [];
29
+ formatOutput({
30
+ columns: ['id', 'name', 'color', 'count'],
31
+ headers: ['ID', 'Name', 'Color', 'Count'],
32
+ rows: tags.map(t => ({ id: t.id, name: t.name, color: t.color || '-', count: t.total_usage ?? 0 })),
33
+ }, { format: program.opts().output });
34
+ });
35
+
36
+ tag
37
+ .command('create')
38
+ .description('Create a tag')
39
+ .requiredOption('--name <name>', 'Tag name')
40
+ .option('--color <color>', 'Tag color (hex)')
41
+ .action(async (opts) => {
42
+ auth.requireAuth();
43
+ const orgId = resolveOrgId(auth, program);
44
+ const body = { name: opts.name };
45
+ if (opts.color) body.color = opts.color;
46
+ // fleet #399: the id wasn't surfaced, so a script had to call
47
+ // `tag list` to recover it after create.
48
+ const data = await client.post(resolveEndpoint('tags.create', { orgId }).path, { service: resolveEndpoint('tags.create', { orgId }).service, body });
49
+ const t = data.tag || data;
50
+ printSuccess(`Tag "${opts.name}" created (id: ${t.id}).`);
51
+ formatDetail(t, { format: program.opts().output });
52
+ });
53
+
54
+ tag
55
+ .command('update')
56
+ .argument('<tagId>', 'tag ID')
57
+ .description('Update a tag')
58
+ .option('--name <name>', 'New name')
59
+ .option('--color <color>', 'New color')
60
+ .action(async (tagId, opts) => {
61
+ auth.requireAuth();
62
+ const orgId = resolveOrgId(auth, program);
63
+ const body = {};
64
+ if (opts.name) body.name = opts.name;
65
+ if (opts.color) body.color = opts.color;
66
+ await client.patch(resolveEndpoint('tags.update', { orgId, tagId }).path, { service: resolveEndpoint('tags.update', { orgId, tagId }).service, body });
67
+ printSuccess('Tag updated.');
68
+ });
69
+
70
+ tag
71
+ .command('delete')
72
+ .argument('<tagId>', 'tag ID')
73
+ .description('Delete a tag')
74
+ .option('--force', 'skip confirmation')
75
+ .action(async (tagId, options) => {
76
+ auth.requireAuth();
77
+ const orgId = resolveOrgId(auth, program);
78
+
79
+ // fleet #399: this deleted immediately with no confirmation and no
80
+ // --force option, inconsistent with `prompt delete` which is equally
81
+ // destructive.
82
+ const confirmed = await confirmDestructive(program, options, `Delete tag ${tagId}? This cannot be undone.`);
83
+ if (!confirmed) {
84
+ printInfo('Cancelled.');
85
+ return;
86
+ }
87
+
88
+ await client.delete(resolveEndpoint('tags.delete', { orgId, tagId }).path, { service: resolveEndpoint('tags.delete', { orgId, tagId }).service });
89
+ printSuccess('Tag deleted.');
90
+ });
91
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Team commands: CRUD + members
3
+ */
4
+
5
+ import { formatOutput, formatDetail, printSuccess } from '../core/output.js';
6
+ import { resolveOrgId } from './helpers.js';
7
+ import { resolveEndpoint } from '../api/endpoints.js';
8
+
9
+ export function registerTeamCommands(program, ctx) {
10
+ const { client, auth } = ctx;
11
+
12
+ const team = program
13
+ .command('team')
14
+ .description('Manage teams');
15
+
16
+ team
17
+ .command('list')
18
+ .description('List teams')
19
+ .option('--division <divId>', 'filter by division')
20
+ .action(async (options) => {
21
+ auth.requireAuth();
22
+ const orgId = resolveOrgId(auth, program);
23
+ const query = {};
24
+ if (options.division) query.division_id = options.division;
25
+ // fleet #392: division_name and member_count only exist when
26
+ // includeStats=true, which was never sent — both columns were dashes.
27
+ query.includeStats = 'true';
28
+ const data = await client.get(resolveEndpoint('teams.list', { orgId }).path, { service: resolveEndpoint('teams.list', { orgId }).service, query });
29
+ formatOutput({
30
+ columns: ['id', 'name', 'division_name', 'member_count', 'created_at'],
31
+ headers: ['ID', 'Name', 'Division', 'Members', 'Created'],
32
+ rows: data.teams || data,
33
+ }, { format: program.opts().output });
34
+ });
35
+
36
+ team
37
+ .command('get')
38
+ .description('Get team details')
39
+ .argument('<teamId>', 'team ID')
40
+ .action(async (teamId) => {
41
+ auth.requireAuth();
42
+ const orgId = resolveOrgId(auth, program);
43
+ const data = await client.get(resolveEndpoint('teams.get', { orgId, teamId }).path, { service: resolveEndpoint('teams.get', { orgId, teamId }).service });
44
+ formatDetail(data.team || data, { format: program.opts().output, title: data.team?.name || data.name });
45
+ });
46
+
47
+ team
48
+ .command('create')
49
+ .description('Create a team')
50
+ .requiredOption('--name <name>', 'team name')
51
+ .option('--division <divId>', 'division ID')
52
+ .option('--department <deptId>', 'department ID')
53
+ .option('--description <desc>', 'description')
54
+ .action(async (options) => {
55
+ auth.requireAuth();
56
+ const orgId = resolveOrgId(auth, program);
57
+ await client.post(resolveEndpoint('teams.create', { orgId }).path, {
58
+ service: resolveEndpoint('teams.create', { orgId }).service,
59
+ body: {
60
+ name: options.name,
61
+ division_id: options.division,
62
+ department_id: options.department,
63
+ description: options.description,
64
+ },
65
+ });
66
+ printSuccess(`Team "${options.name}" created.`);
67
+ });
68
+
69
+ team
70
+ .command('update')
71
+ .description('Update a team')
72
+ .argument('<teamId>', 'team ID')
73
+ .option('--name <name>', 'new name')
74
+ .option('--description <desc>', 'new description')
75
+ .action(async (teamId, options) => {
76
+ auth.requireAuth();
77
+ const orgId = resolveOrgId(auth, program);
78
+ const body = {};
79
+ if (options.name) body.name = options.name;
80
+ if (options.description) body.description = options.description;
81
+ await client.patch(resolveEndpoint('teams.update', { orgId, teamId }).path, { service: resolveEndpoint('teams.update', { orgId, teamId }).service, body });
82
+ printSuccess('Team updated.');
83
+ });
84
+
85
+ team
86
+ .command('delete')
87
+ .description('Delete a team')
88
+ .argument('<teamId>', 'team ID')
89
+ .action(async (teamId) => {
90
+ auth.requireAuth();
91
+ const orgId = resolveOrgId(auth, program);
92
+ await client.delete(resolveEndpoint('teams.delete', { orgId, teamId }).path, { service: resolveEndpoint('teams.delete', { orgId, teamId }).service });
93
+ printSuccess('Team deleted.');
94
+ });
95
+
96
+ team
97
+ .command('provision-room')
98
+ .description('Provision (or adopt) the governed Matrix room for a team')
99
+ .argument('<teamId>', 'team ID')
100
+ .action(async (teamId) => {
101
+ auth.requireAuth();
102
+ const orgId = resolveOrgId(auth, program);
103
+ const ep = resolveEndpoint('teams.provisionRoom', { orgId, teamId });
104
+ const data = await client.post(ep.path, { service: ep.service, body: {} });
105
+ printSuccess('Team Matrix room provisioned.');
106
+ const room = data.room || data;
107
+ formatDetail(room, { format: program.opts().output, title: 'Matrix Room' });
108
+ });
109
+
110
+ // Team members
111
+ const members = team
112
+ .command('members')
113
+ .description('Manage team members');
114
+
115
+ members
116
+ .command('add')
117
+ .description('Add a member to a team')
118
+ .argument('<teamId>', 'team ID')
119
+ .requiredOption('--user <userId>', 'user ID')
120
+ .option('--role <role>', 'team role', 'member')
121
+ .action(async (teamId, options) => {
122
+ auth.requireAuth();
123
+ const orgId = resolveOrgId(auth, program);
124
+ await client.post(resolveEndpoint('teams.members.create', { orgId, teamId }).path, {
125
+ service: resolveEndpoint('teams.members.create', { orgId, teamId }).service,
126
+ body: { user_id: options.user, role: options.role },
127
+ });
128
+ printSuccess('Member added to team.');
129
+ });
130
+
131
+ members
132
+ .command('remove')
133
+ .description('Remove a member from a team')
134
+ .argument('<teamId>', 'team ID')
135
+ .requiredOption('--user <userId>', 'user ID')
136
+ .action(async (teamId, options) => {
137
+ auth.requireAuth();
138
+ const orgId = resolveOrgId(auth, program);
139
+ await client.delete(resolveEndpoint('teams.members.delete', { orgId, teamId, user: options.user }).path, { service: resolveEndpoint('teams.members.delete', { orgId, teamId, user: options.user }).service });
140
+ printSuccess('Member removed from team.');
141
+ });
142
+ }