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,410 @@
1
+ /**
2
+ * The Quox dragon: the horned Q brought alive (eyes, tail, fire). Ported from the lab (~/quoxon-work/intro/lab/dragon-core.mjs), tuned there with the owner (CLI-QUOX F3).
3
+ *
4
+ * PURE AND PORTABLE: no process, no timers, no Node or DOM APIs. Everything is a function of
5
+ * (layout, pose, time, seed). A scene maps t (ms) to a pose; renderDragon(pose, layout) maps a pose to rows
6
+ * of cells { ch, rgb, bg } (rgb/bg null = terminal default). The terminal (qart.cellsToAnsi, qmotion.cellNodes)
7
+ * and the web face (web/qface.js) draw these same cells; both understand the bg colour.
8
+ *
9
+ * ONE dragon (v8): a Braille field with the body (bowl ring + horns, from qart.js's vector silhouette), dim bat
10
+ * wings, a spade-tailed spine, the smile and pink cheeks, and the fire (with its embers and smoke) from the mouth.
11
+ * 2x4 dots per cell, one colour per cell. The eyes are NOT drawn here: the googly dot eyes (qeyes.js) are laid over
12
+ * the cells by qdragonScenes.js composeCells, so every scene, mood, greeting and the flight share one face.
13
+ */
14
+
15
+ export const PAL = {
16
+ SKY: [56, 189, 248], INDIGO: [99, 102, 241], VIOLET: [168, 85, 247], TEAL: [6, 182, 212],
17
+ AMBER: [245, 158, 11], ORANGE: [251, 146, 60], RED: [239, 68, 68], CORE: [255, 250, 235],
18
+ SMOKE: [120, 126, 138],
19
+ };
20
+ const { SKY, VIOLET, AMBER, ORANGE, RED, CORE, SMOKE } = PAL;
21
+
22
+ /**
23
+ * Themes. dark: the default (terminal background is dark). light: for light terminal backgrounds; the body
24
+ * gradient is deepened, smoke darkens, and the fire keeps its saturation (no white-hot core, which would vanish on a light background).
25
+ */
26
+ export const THEMES = {
27
+ dark: {
28
+ name: 'dark', bg: [12, 15, 21], light: false, body0: SKY, body1: VIOLET,
29
+ smoke0: [150, 156, 168], smoke1: [72, 78, 90], smoke: SMOKE, label: (c) => c,
30
+ },
31
+ light: {
32
+ name: 'light', bg: [248, 250, 252], light: true, body0: [3, 116, 178], body1: [109, 40, 217],
33
+ smoke0: [96, 104, 118], smoke1: [196, 201, 210], smoke: [110, 116, 128],
34
+ label: (c) => c.map((v) => Math.round(v * 0.62)),
35
+ },
36
+ };
37
+ let TH = THEMES.dark; // set per renderDragon call (synchronous, so this stays pure per frame)
38
+
39
+ const TAU = Math.PI * 2;
40
+ const ASPECT = 0.82;
41
+ export const clamp = (x, a = 0, b = 1) => Math.max(a, Math.min(b, x));
42
+ export const smooth = (e) => { e = clamp(e); return e * e * (3 - 2 * e); };
43
+ const mix = (A, B, t) => A.map((v, i) => v + (B[i] - v) * t);
44
+ export function rng(seed) { return () => { seed |= 0; seed = (seed + 0x6d2b79f5) | 0; let t = Math.imul(seed ^ (seed >>> 15), 1 | seed); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; }
45
+ export const hash = (n) => { let x = Math.imul((n | 0) ^ 0x9e3779b9, 0x85ebca6b); x ^= x >>> 13; x = Math.imul(x, 0xc2b2ae35); x ^= x >>> 16; return (x >>> 0) / 4294967296; };
46
+ /** Keyframes: [[ms, value], ...], eased (smoothstep) between neighbours, held outside. */
47
+ export function kf(t, keys) {
48
+ if (t <= keys[0][0]) return keys[0][1];
49
+ for (let i = 0; i < keys.length - 1; i++) {
50
+ const [t0, v0] = keys[i], [t1, v1] = keys[i + 1];
51
+ if (t < t1) return t1 === t0 ? v1 : v0 + (v1 - v0) * smooth((t - t0) / (t1 - t0));
52
+ }
53
+ return keys[keys.length - 1][1];
54
+ }
55
+ const win = (t, a, b) => t >= a && t < b;
56
+
57
+ /** Fire colour by heat 0..1: dark red, red, orange, amber, pale gold, hot white core. */
58
+ const FIRE_DARK = [[0, [70, 16, 16]], [0.22, RED], [0.45, ORANGE], [0.66, AMBER], [0.84, [253, 224, 140]], [1, CORE]];
59
+ const FIRE_LIGHT = [[0, [127, 29, 29]], [0.25, [220, 38, 38]], [0.5, [234, 88, 12]], [0.75, [245, 140, 11]], [1, [251, 191, 36]]];
60
+ export function fireRGB(h) {
61
+ const S = TH.light ? FIRE_LIGHT : FIRE_DARK;
62
+ h = clamp(h);
63
+ for (let i = 0; i < S.length - 1; i++) if (h <= S[i + 1][0]) return mix(S[i][1], S[i + 1][1], (h - S[i][0]) / (S[i + 1][0] - S[i][0]));
64
+ return S[S.length - 1][1];
65
+ }
66
+
67
+ // ---- geometry (unit space: y 0..1 down the Q, x 0..ASPECT; the same silhouette as qart.js) ----------------
68
+ const BOWL = { cx: ASPECT / 2, cy: 0.6, rx: 0.4, ry: 0.385, w: 0.118 };
69
+ const bez = (a, b, c, t) => [(1 - t) ** 2 * a[0] + 2 * (1 - t) * t * b[0] + t * t * c[0], (1 - t) ** 2 * a[1] + 2 * (1 - t) * t * b[1] + t * t * c[1]];
70
+ const HORNS = [
71
+ { a: [0.2, 0.29], b: [-0.02, 0.27], c: [0.02, 0.03], r0: 0.048 },
72
+ { a: [0.62, 0.29], b: [0.84, 0.27], c: [0.8, 0.0], r0: 0.048 },
73
+ ];
74
+ const HORN_PTS = HORNS.map((hn) => Array.from({ length: 24 }, (_, i) => ({ p: bez(hn.a, hn.b, hn.c, i / 23), t: i / 23, r0: hn.r0 })));
75
+ const TAIL0 = { a: [0.4, 0.69], b: [0.79, 0.985], r0: 0.07, r1: 0.04 };
76
+ const TAIL_LEN0 = Math.hypot(TAIL0.b[0] - TAIL0.a[0], TAIL0.b[1] - TAIL0.a[1]);
77
+ const TAIL_ANG0 = Math.atan2(TAIL0.b[1] - TAIL0.a[1], TAIL0.b[0] - TAIL0.a[0]);
78
+ const TAIL_FIXED = 0.5 * TAIL_LEN0; // the stroke inside the bowl and through the ring never bends
79
+ // The mouth is a jaw notch at the bowl's lower right, just above where the tail leaves the ring: the bowl is the
80
+ // upper jaw and the tail stroke the lower one, so the fire comes out of the Q's own stroke rather than a hole in
81
+ // the side of its head. A small notch is always there (the mouth corner); it opens wide to breathe.
82
+ const MOUTH_ANG = 0.52; // radians below the bowl's right-hand horizontal (normalised ellipse angle)
83
+ const NOTCH = 0.07; // the resting notch half-width (radians)
84
+
85
+ function bodyAt(x, y) {
86
+ const dx = (x - BOWL.cx) / BOWL.rx, dy = (y - BOWL.cy) / BOWL.ry, e = Math.hypot(dx, dy);
87
+ const inner = 1 - BOWL.w / ((BOWL.rx + BOWL.ry) / 2);
88
+ if (e <= 1 && e >= inner) return { part: 'bowl', t: 0, ang: Math.atan2(dy, dx) };
89
+ if (y > 0.34) return null;
90
+ for (const pts of HORN_PTS) for (const q of pts) if (Math.hypot(x - q.p[0], y - q.p[1]) <= q.r0 * (1 - q.t * 0.93) + 0.004) return { part: 'horn', t: q.t, ang: 0 };
91
+ return null;
92
+ }
93
+
94
+ export const DSIZES = { large: 72, mid: 44, small: 24 }; // small = qart's compact Q (under 60 cols), for the intro hand-over
95
+ /**
96
+ * Layout for a frame `cols` wide. large (18-row Q) from 64 cols, mid (11 rows) below. The Q sits at the left;
97
+ * everything to its right is room for fire and labels; rows below hold the tail.
98
+ */
99
+ export function dragonLayout(cols, { size, lm, ty = 0, rows: fixedRows } = {}) {
100
+ size ??= cols >= 64 ? 'large' : 'mid';
101
+ const H = DSIZES[size], qw = Math.round(H * ASPECT);
102
+ lm ??= cols >= 64 ? 2 : 1; // left margin in cells (0 lines the dragon up with qart's Q, for the intro hand-over)
103
+ const rows = fixedRows ?? Math.ceil((ty + H * 1.34) / 4); // ty: dots of room above the Q (the flight's raised wings and its bob)
104
+ const L = { size, H, cols, rows, Wd: cols * 2, Hd: rows * 4, qx0: lm * 2, qy0: ty, qw, qCols: Math.ceil((lm * 2 + qw) / 2) };
105
+ L.X = (x) => L.qx0 + x * H;
106
+ L.Y = (y) => L.qy0 + y * H;
107
+ L.grad = (xd) => mix(TH.body0, TH.body1, clamp((xd - L.qx0) / qw));
108
+ L.mouth = [L.X(BOWL.cx + BOWL.rx * Math.cos(MOUTH_ANG) * 0.97), L.Y(BOWL.cy + BOWL.ry * Math.sin(MOUTH_ANG) * 0.97)];
109
+ L.mouthL = [L.X(BOWL.cx - BOWL.rx * Math.cos(MOUTH_ANG) * 0.97), L.mouth[1]]; // the mirrored mouth (pose.mouthSide 'left')
110
+ // large eyes are a tall oval (8 quadrant rows) so the iris can move up and down with a row of white to spare
111
+ return L;
112
+ }
113
+
114
+ const bodyCache = new Map();
115
+ function bodyDots(L) {
116
+ const key = `${L.size}:${L.qx0}:${L.qy0}`;
117
+ if (bodyCache.has(key)) return bodyCache.get(key);
118
+ const dots = [];
119
+ for (let y = 0; y < L.H; y++) for (let x = 0; x < L.qw + 2; x++) {
120
+ let n = 0;
121
+ for (const [sx, sy] of [[0.25, 0.25], [0.75, 0.25], [0.25, 0.75], [0.75, 0.75]]) if (bodyAt((x + sx) / L.H, (y + sy) / L.H)) n++;
122
+ if (n >= 2) { const p = bodyAt((x + 0.5) / L.H, (y + 0.5) / L.H) || { part: 'bowl', t: 0, ang: 0 }; dots.push({ x: x + L.qx0, y: y + L.qy0, ...p }); }
123
+ }
124
+ bodyCache.set(key, dots);
125
+ return dots;
126
+ }
127
+
128
+ // ---- poses -------------------------------------------------------------------------------------------------
129
+ /** The settled dragon: tail at rest, no fire (the eyes are the dot layer, see qdragonScenes.js). Also the static (reduced motion) form. */
130
+ export function restPose() {
131
+ return {
132
+ tail: { len: 1.32, bend: -0.6, amp: 0, phase: 0, k: 2.4, curl: 0, wrap: 0, spade: 1 },
133
+ glow: 1, tint: null, tintAmt: 0, mouth: 0, mouthSide: 'right', // 'left' = screen left: the face and the fire mirror
134
+ fire: null, label: null,
135
+ };
136
+ }
137
+ // ---- drawing -----------------------------------------------------------------------------------------------
138
+ function makeField(W, H) {
139
+ const v = new Float32Array(W * H), c = new Float32Array(W * H * 3);
140
+ return {
141
+ W, H, v, c,
142
+ set(x, y, val, rgb) {
143
+ x = Math.round(x); y = Math.round(y);
144
+ if (x < 0 || y < 0 || x >= W || y >= H) return;
145
+ const i = y * W + x;
146
+ if (val > v[i]) { v[i] = val; c[i * 3] = rgb[0]; c[i * 3 + 1] = rgb[1]; c[i * 3 + 2] = rgb[2]; }
147
+ },
148
+ };
149
+ }
150
+
151
+ function drawBody(F, p, L) {
152
+ for (const d of bodyDots(L)) {
153
+ let rgb = L.grad(d.x);
154
+ if (p.tint && p.tintAmt) rgb = mix(rgb, p.tint, p.tintAmt);
155
+ F.set(d.x, d.y, p.glow, rgb);
156
+ }
157
+ }
158
+
159
+ /** The tail spine: fixed through the ring, then bent by sway (a travelling wave), curl (tip spiral) and wrap. */
160
+ export function tailSpine(tp, L) {
161
+ const len = (tp.len + 0.85 * tp.wrap) * TAIL_LEN0, step = 0.5 / L.H, pts = [];
162
+ let x = TAIL0.a[0], y = TAIL0.a[1], th = TAIL_ANG0;
163
+ // wrap: a heading offset (not extra curvature, which spirals into a loop). The tail turns once, runs back to
164
+ // the left under the bowl, and the tip hooks up again: a sweep under the Q and back.
165
+ const wrapOff = (f) => tp.wrap * (2.6 * smooth((f - 0.2) / 0.34) + 0.95 * smooth((f - 0.78) / 0.22));
166
+ for (let s = 0; s <= len; s += step) {
167
+ const f = s > TAIL_FIXED ? (s - TAIL_FIXED) / (len - TAIL_FIXED) : 0, h = th + (tp.wrap ? wrapOff(f) : 0);
168
+ pts.push({ x, y, th: h, s, r: Math.max(0.017, TAIL0.r0 - ((TAIL0.r0 - TAIL0.r1) * s) / TAIL_LEN0) });
169
+ if (s > TAIL_FIXED) {
170
+ let k = tp.bend * 2 * f * (1 - tp.wrap) + tp.amp * Math.sin(tp.phase - tp.k * f) * (0.35 + f) * (1 - 0.6 * tp.wrap);
171
+ k -= tp.curl * 26 * smooth((f - 0.45) / 0.45);
172
+ th += k * step;
173
+ }
174
+ x += Math.cos(h) * step; y += Math.sin(h) * step;
175
+ }
176
+ return pts;
177
+ }
178
+
179
+ // v2: how much of the tail shows at (xd, yd) dots: inside the bowl it is behind the head, so it fades to a ghost
180
+ const INNER = 1 - BOWL.w / ((BOWL.rx + BOWL.ry) / 2);
181
+ function behind(L, xd, yd) {
182
+ const x = (xd - L.qx0) / L.H, y = (yd - L.qy0) / L.H, e = Math.hypot((x - BOWL.cx) / BOWL.rx, (y - BOWL.cy) / BOWL.ry);
183
+ return e < INNER ? 0 : 1; // wholly behind the head
184
+ }
185
+ function drawTail(F, p, L) {
186
+ const tp = p.tail, pts = tailSpine(tp, L);
187
+ const glow = p.glow, tint = p.tint && p.tintAmt ? p.tint : null;
188
+ const col = (xd) => (tint ? mix(L.grad(xd), tint, p.tintAmt) : L.grad(xd));
189
+ const n = pts.length;
190
+ for (let i = 0; i < n; i++) {
191
+ const q = pts[i], f = i / (n - 1);
192
+ const cx = L.X(q.x), cy = L.Y(q.y), R = Math.max(0.6, q.r * L.H * (1 - 0.55 * smooth((f - 0.6) / 0.4)));
193
+ for (let dy = -Math.ceil(R); dy <= Math.ceil(R); dy++) for (let dx = -Math.ceil(R); dx <= Math.ceil(R); dx++) {
194
+ if (dx * dx + dy * dy <= R * R + 0.25) F.set(cx + dx, cy + dy, glow * behind(L, cx + dx, cy + dy), col(cx + dx));
195
+ }
196
+ }
197
+ // v2: little spines along the back of the tail (a dragon, not an imp)
198
+ for (const fs of [0.42, 0.6, 0.76]) {
199
+ const i = Math.round(fs * (n - 1)), q = pts[i], R = q.r * L.H * (1 - 0.55 * smooth((fs - 0.6) / 0.4));
200
+ if (q.s <= TAIL_FIXED * 0.98) continue;
201
+ const c = Math.cos(q.th), s = Math.sin(q.th), nx = s, ny = -c, h = (0.08 - 0.03 * fs) * L.H, b = 0.032 * L.H;
202
+ const bx = L.X(q.x) + nx * R * 0.7, by = L.Y(q.y) + ny * R * 0.7;
203
+ for (let a = -b; a <= b; a += 0.5) for (let u = 0; u <= h * (1 - Math.abs(a + b * 0.5) / (b * 1.5)); u += 0.5) {
204
+ F.set(bx + c * a + nx * u, by + s * a + ny * u, glow, col(bx + c * a));
205
+ }
206
+ }
207
+ if (tp.spade > 0.01) {
208
+ // a sharp spade at the tip: a long point and two barbs swept back, aligned to the tail's last heading
209
+ const e = pts[pts.length - 1], c = Math.cos(e.th), s = Math.sin(e.th), sz = 0.075 * tp.spade;
210
+ const P = (along, side) => [L.X(e.x + c * along * sz - s * side * sz), L.Y(e.y + s * along * sz + c * side * sz)];
211
+ const poly = [P(2.4, 0), P(0.2, 1.0), P(0.55, 0.25), P(-0.3, 0.12), P(-0.3, -0.12), P(0.55, -0.25), P(0.2, -1.0)];
212
+ const xs = poly.map((q) => q[0]), ys = poly.map((q) => q[1]);
213
+ for (let y = Math.floor(Math.min(...ys)); y <= Math.ceil(Math.max(...ys)); y++) for (let x = Math.floor(Math.min(...xs)); x <= Math.ceil(Math.max(...xs)); x++) {
214
+ let inside = false;
215
+ for (let a = 0, b = poly.length - 1; a < poly.length; b = a++) {
216
+ const [xa, ya] = poly[a], [xb, yb] = poly[b];
217
+ if ((ya > y) !== (yb > y) && x < ((xb - xa) * (y - ya)) / (yb - ya) + xa) inside = !inside;
218
+ }
219
+ if (inside) F.set(x, y, glow, col(x));
220
+ }
221
+ }
222
+ }
223
+
224
+ /** The face, so the bowl reads as a head: a smile that opens to talk (and to breathe), pink cheeks. p.frown turns the closed smile over. */
225
+ export const FACE = { y: 0.75, w: 0.07 };
226
+ function drawFace(F, p, L) {
227
+ const ink = [224, 231, 255], o = clamp(p.smile || 0), w = FACE.w, y0 = FACE.y, fx = BOWL.cx + (p.faceX || 0);
228
+ for (let u = -1; u <= 1.0001; u += 0.03) {
229
+ const x = L.X(fx + u * w), top = L.Y(y0 + 0.03 * (1 - u * u)), bot = L.Y(y0 + (0.03 + 0.07 * o) * (1 - u * u));
230
+ if (o > 0.05) { for (let y = Math.round(top); y <= bot; y++) F.set(x, y, 1, Math.abs(u) < 0.6 && y > top + 2 && y < bot - 1 ? [244, 114, 182] : ink); }
231
+ else F.set(x, p.frown ? L.Y(y0 + 0.03 * u * u) : top, 1.05, ink); // frown: the closed smile turned over (a mood, with the eyes)
232
+ }
233
+ for (const sd of [-1, 1]) for (let dy = -1; dy <= 1; dy++) for (let dx = -3; dx <= 3; dx++) {
234
+ if ((dx / 3.4) ** 2 + (dy / 1.6) ** 2 <= 1) F.set(L.X(BOWL.cx + (p.faceX || 0) * 0.5 + sd * 0.2) + dx, L.Y(0.7) + dy, 0.9, [244, 114, 182]);
235
+ }
236
+ }
237
+
238
+ /** v2: two small bat wings tucked behind the head (dim: they are behind it), flapping gently with p.flap (radians). */
239
+ function fillPoly(F, poly, val, rgbAt, L) {
240
+ const xs = poly.map((q) => q[0]), ys = poly.map((q) => q[1]);
241
+ for (let y = Math.floor(Math.min(...ys)); y <= Math.ceil(Math.max(...ys)); y++) for (let x = Math.floor(Math.min(...xs)); x <= Math.ceil(Math.max(...xs)); x++) {
242
+ let inside = false;
243
+ for (let a = 0, b = poly.length - 1; a < poly.length; b = a++) {
244
+ const [xa, ya] = poly[a], [xb, yb] = poly[b];
245
+ if ((ya > y) !== (yb > y) && x < ((xb - xa) * (y - ya)) / (yb - ya) + xa) inside = !inside;
246
+ }
247
+ if (inside && (!L || behind(L, x, y))) F.set(x, y, val(x, y), rgbAt(x, y));
248
+ }
249
+ }
250
+ const WING = [[0, -0.2], [0.34, -0.5], [0.36, -0.3], [0.27, -0.28], [0.25, -0.15], [0.16, -0.17], [0.13, -0.04], [0, 0.02]];
251
+ export let WING_K = 0.66, WING_V = 0.42;
252
+ export const setWing = (k, v) => { WING_K = k; WING_V = v; };
253
+ function drawWings(F, p, L) {
254
+ if (p.wings === 0) return;
255
+ const a = p.flap || 0;
256
+ for (const sd of [-1, 1]) {
257
+ const K = WING_K * (p.wingScale || 1), rx = BOWL.cx + sd * BOWL.rx * 0.86, ry = BOWL.cy - 0.04, c = Math.cos(a * sd), s = Math.sin(a * sd);
258
+ const poly = WING.map(([u, v]) => { const x = K * (u * c + v * s * sd), y = K * (-u * s * sd + v * c); return [L.X(rx + sd * x), L.Y(ry + y)]; });
259
+ fillPoly(F, poly, () => WING_V, (x) => L.grad(x), L);
260
+ }
261
+ }
262
+ /** Fire breath, embers and smoke at ms since the breath began. Particles are seeded, positions are closed-form. */
263
+ const fireCache = new Map();
264
+ function fireModel(L, seed, dur) {
265
+ const key = `${L.size}:${L.cols}:${seed}:${dur}${L.left ? `:L${L.qx0}` : ''}`;
266
+ if (fireCache.has(key)) return fireCache.get(key);
267
+ const R = rng(seed), reach = Math.max(14, Math.min(L.H * 1.25, L.left ? L.mouth[0] - 6 : L.Wd - L.mouth[0] - 6));
268
+ const N = Math.round(reach * 26), parts = [];
269
+ for (let i = 0; i < N; i++) {
270
+ const b = R() * dur, u = b / dur;
271
+ const env = smooth(u / 0.12) * (1 - smooth((u - 0.78) / 0.22));
272
+ if (R() > 0.15 + 0.85 * env) continue;
273
+ const ember = R() < 0.07;
274
+ parts.push({
275
+ b, ember, life: ember ? 1400 + R() * 1300 : 300 + R() * 330, ang: 0.06 + (R() - 0.5) * 0.3, v: (reach / 520) * (0.75 + 0.5 * R()),
276
+ ph: R() * TAU, wf: 0.012 + R() * 0.012, lat: (R() - 0.5) * 2, hj: 0.85 + 0.15 * R(), id: i,
277
+ });
278
+ }
279
+ const smoke = [];
280
+ for (let i = 0; i < Math.round(reach * 0.32); i++) {
281
+ smoke.push({
282
+ b: dur * 0.45 + R() * (dur * 0.6 + 1400), d: (0.15 + 0.8 * R()) * reach, dy: (R() - 0.5) * 4, life: 1700 + R() * 1300,
283
+ rise: 0.010 + R() * 0.007, drift: (R() - 0.25) * 0.004, amp: 1.4 + R() * 1.8, w: 0.004 + R() * 0.003, ph: R() * TAU,
284
+ });
285
+ }
286
+ const m = { parts, smoke, reach };
287
+ fireCache.set(key, m);
288
+ return m;
289
+ }
290
+ function drawFire(F, fire, L) {
291
+ const { t, dur = 1200, seed = 3, scale = 1 } = fire;
292
+ const M = fireModel(L, seed, dur), [mx, my] = L.mouth, sg = L.left ? -1 : 1;
293
+ for (const q of M.parts) {
294
+ const age = t - q.b;
295
+ if (age < 0 || age > q.life) continue;
296
+ const s = age / q.life;
297
+ if (q.ember) {
298
+ const tau = 260, dist = q.v * tau * (1 - Math.exp(-age / tau)) * 1.25 * scale;
299
+ const x = mx + sg * (dist * Math.cos(q.ang) + Math.sin(age * 0.004 + q.ph) * 2.2), y = my + dist * Math.sin(q.ang) + q.lat * 3 - age * 0.009;
300
+ if (hash(q.id * 31 + Math.floor(age / 85)) < 0.28) continue; // flicker
301
+ F.set(x, y, 0.75 + 0.35 * (1 - s), fireRGB(0.72 - 0.4 * s));
302
+ continue;
303
+ }
304
+ for (let k = 0; k < 2; k++) {
305
+ const a = Math.max(0, age - k * 22), sa = a / q.life;
306
+ const dist = q.v * a * (1 - 0.32 * sa) * scale;
307
+ const fr = dist / M.reach;
308
+ const spread = q.lat * dist * 0.2 + Math.sin(a * q.wf + q.ph) * dist * 0.08;
309
+ const x = mx + sg * (dist * Math.cos(q.ang) - Math.sin(q.ang) * spread), y = my + dist * Math.sin(q.ang) + spread * Math.cos(q.ang) - fr * fr * M.reach * 0.14;
310
+ const heat = clamp((1 - sa) ** 0.75 * q.hj * (1 - 0.45 * fr) * (1 - 0.45 * Math.abs(q.lat)) + (dist < 6 ? 0.35 : 0));
311
+ F.set(x, y, (k ? 0.55 : 0.7) + 0.55 * heat, fireRGB(heat - k * 0.08));
312
+ }
313
+ }
314
+ for (const q of M.smoke) drawWisp(F, mx + sg * q.d * Math.cos(0.08), my + q.d * Math.sin(0.08) + q.dy, t - q.b, q, sg);
315
+ }
316
+
317
+ /**
318
+ * A smoke wisp: a rising, gently swaying streak (its head plus a trail of where it has been). Grey shades fade
319
+ * with age (lighter grey to background), and the whole wisp drifts sideways as it rises.
320
+ */
321
+ function drawWisp(F, x0, y0, age, q, sg = 1) {
322
+ if (age < 0 || age > q.life + 500) return;
323
+ const pos = (a) => [x0 + sg * (a * q.drift + Math.sin(a * q.w + q.ph) * q.amp * (0.4 + a / q.life)), y0 - a * q.rise];
324
+ let prev = null;
325
+ for (let k = 0; k < 12; k++) {
326
+ const a = age - k * 45;
327
+ if (a < 0) break;
328
+ if (a > q.life) continue;
329
+ const s = a / q.life, fade = (1 - s) ** 1.2 * smooth(a / 220) * (1 - k / 13);
330
+ if (fade < 0.06) continue;
331
+ const [x, y] = pos(a), rgb = mix(TH.smoke0, TH.smoke1, s);
332
+ F.set(x, y, 0.2 + 0.6 * fade, rgb);
333
+ if (prev && Math.hypot(x - prev[0], y - prev[1]) > 1.2) F.set((x + prev[0]) / 2, (y + prev[1]) / 2, 0.2 + 0.55 * fade, rgb);
334
+ prev = [x, y];
335
+ }
336
+ }
337
+
338
+ // ---- compose -----------------------------------------------------------------------------------------------
339
+ const BR = [[0x1, 0x8], [0x2, 0x10], [0x4, 0x20], [0x40, 0x80]];
340
+
341
+ /**
342
+ * Render a pose: rows of cells { ch, rgb, bg }. opts: { mono, theme }. (t is accepted and ignored: nothing flickers.)
343
+ * The label (pose.label = { text | cells, rgb, row, col }) is written into the frame to the right of the Q.
344
+ */
345
+ export function renderDragon(pose, L0, { mono = false, theme = 'dark' } = {}) {
346
+ TH = THEMES[theme] || THEMES.dark;
347
+ const L = pose.mouthSide === 'left' ? { ...L0, mouth: [L0.X(BOWL.cx + (pose.faceX || 0) - FACE.w * 0.6), L0.Y(FACE.y + 0.05)], left: true } : L0; // the mouth-dependent parts see the mirrored mouth
348
+ const F = makeField(L.Wd, L.Hd);
349
+ drawWings(F, pose, L);
350
+ drawBody(F, pose, L);
351
+ drawTail(F, pose, L);
352
+ drawFace(F, pose, L);
353
+ if (pose.fire) drawFire(F, pose.fire, L);
354
+ const thr = mono ? 0.35 : 0.04, rows = [];
355
+ for (let cy = 0; cy < L.rows; cy++) {
356
+ const row = [];
357
+ for (let cx = 0; cx < L.cols; cx++) {
358
+ let bits = 0, m = 0, mi = -1;
359
+ for (let dy = 0; dy < 4; dy++) for (let dx = 0; dx < 2; dx++) {
360
+ const i = (cy * 4 + dy) * L.Wd + cx * 2 + dx, val = F.v[i];
361
+ if (val > thr) { bits |= BR[dy][dx]; if (val > m) { m = val; mi = i; } }
362
+ }
363
+ if (!bits) { row.push({ ch: ' ', rgb: null, bg: null }); continue; }
364
+ let rgb = null;
365
+ if (!mono) {
366
+ const base = [F.c[mi * 3], F.c[mi * 3 + 1], F.c[mi * 3 + 2]], f = 0.28 + 0.72 * Math.min(1, m), fl = clamp(m - 1);
367
+ rgb = TH.light
368
+ ? base.map((c, j) => Math.round((TH.bg[j] + (c - TH.bg[j]) * (0.12 + 0.88 * Math.min(1, m))) * (1 - 0.25 * fl)))
369
+ : base.map((c) => { c *= f; return Math.round(c + (255 - c) * fl * 0.9); });
370
+ }
371
+ row.push({ ch: String.fromCharCode(0x2800 + bits), rgb, bg: null });
372
+ }
373
+ rows.push(row);
374
+ }
375
+ const lb = pose.label;
376
+ if (lb) {
377
+ const cells = (lb.cells || [...lb.text].map((ch) => ({ ch, rgb: lb.rgb || null }))).map((cl) => ({ ch: cl.ch, rgb: cl.rgb ? TH.label(cl.rgb) : null }));
378
+ let r = lb.row ?? Math.floor(L.H / 8), c0 = lb.col ?? L.qCols + (L.cols >= 64 ? 7 : 2);
379
+ if (c0 + cells.length > L.cols) { r = L.H / 4 + 1; c0 = Math.max(0, Math.floor((L.qCols - cells.length) / 2) + 2); } // no room beside: under the Q
380
+ const target = r < rows.length ? rows[r] : null;
381
+ if (target) cells.forEach((cl, k) => { if (c0 + k < L.cols) target[c0 + k] = { ch: cl.ch, rgb: mono ? null : cl.rgb, bg: null }; });
382
+ }
383
+ return rows;
384
+ }
385
+
386
+ // ---- output helpers ----------------------------------------------------------------------------------------
387
+ const ANSI16 = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128], [128, 0, 128], [0, 128, 128], [192, 192, 192],
388
+ [128, 128, 128], [255, 0, 0], [0, 255, 0], [255, 255, 0], [92, 92, 255], [255, 0, 255], [0, 255, 255], [255, 255, 255]];
389
+ function sgr(rgb, depth, bg) {
390
+ const [r, g, b] = rgb;
391
+ if (depth === 3) return `\x1b[${bg ? 48 : 38};2;${r};${g};${b}m`;
392
+ if (depth === 2) return `\x1b[${bg ? 48 : 38};5;${16 + 36 * Math.round(r / 51) + 6 * Math.round(g / 51) + Math.round(b / 51)}m`;
393
+ let best = 0, bd = 1e9;
394
+ ANSI16.forEach((c, i) => { const d = (c[0] - r) ** 2 + (c[1] - g) ** 2 + (c[2] - b) ** 2; if (d < bd) { bd = d; best = i; } });
395
+ return `\x1b[${(best < 8 ? 30 + best : 82 + best) + (bg ? 10 : 0)}m`;
396
+ }
397
+ /** Cells -> ANSI lines. depth 3 truecolor, 2 = 256, 1 = 16, 0 = none. */
398
+ export function cellsToAnsi(rows, depth = 3) {
399
+ return rows.map((row) => {
400
+ let s = '', lf = '', lb = '';
401
+ for (const c of row) {
402
+ const f = depth && c.rgb ? sgr(c.rgb, depth, false) : '', b = depth && c.bg ? sgr(c.bg, depth, true) : '';
403
+ if ((lb && !b) || (lf && !f && c.ch !== ' ')) { s += '\x1b[0m'; lf = ''; lb = ''; }
404
+ if (f && f !== lf) { s += f; lf = f; }
405
+ if (b && b !== lb) { s += b; lb = b; }
406
+ s += c.ch;
407
+ }
408
+ return s + (lf || lb ? '\x1b[0m' : '');
409
+ });
410
+ }
@@ -0,0 +1,61 @@
1
+ // /dragon-fly: the v8 dragon in flight (canonical source: quox cli/lib/quoxon/qdragonFly.js).
2
+ //
3
+ // The same dragon as everywhere else (googly dot eyes, the smile, pink cheeks, dim bat wings, the spade tail),
4
+ // made by the same composeCells; in flight the wings are bigger and beat hard, the body bobs with each stroke, the
5
+ // tail streams behind and the eyes look the way it is going. It crosses the sky once, left to right.
6
+ //
7
+ // PURE AND PORTABLE: no DOM, no timers, no Node APIs. flyFrame(ms, cols, opts) -> rows of { ch, rgb, bg } cells.
8
+ import { dragonLayout, restPose, kf, DSIZES } from './qdragon.js';
9
+ import { composeCells, PICK_EYES } from './qdragonScenes.js';
10
+ import { eyeState } from './qeyes.js';
11
+
12
+ const TAU = Math.PI * 2;
13
+ export const FLAP_MS = 760; // one wingbeat
14
+ export const FLY_PASS_MS = 9000; // one pass across the sky
15
+ export const FLY_STILL_MS = 3000; // how long the still frame stays for reduced motion / NO_COLOR
16
+ const SIZE = 'mid';
17
+ const WING_SCALE = 1.7;
18
+ const TOP = 26; // dots of sky above the Q: room for the raised wings and the bob
19
+ const BOB = 5; // dots the body rises and falls with each stroke
20
+ const SPAN = 30; // cells of overshoot either side so the wings enter and leave whole
21
+
22
+ /** The widest sky (in cells) worth drawing: never wider than `cols`; the dragon is 18 cells tall at most, so termRows is not a limit. */
23
+ export function flyCols(cols) {
24
+ return Math.max(40, Math.min(cols, 120));
25
+ }
26
+
27
+ /** The dragon's pose in flight at ms into the pass. */
28
+ export function flyPose(ms) {
29
+ const p = restPose(), ph = (TAU * ms) / FLAP_MS;
30
+ p.wingScale = WING_SCALE;
31
+ p.flap = -0.2 + 0.8 * Math.sin(ph);
32
+ p.tail.len = 1.55; p.tail.k = 3.2; p.tail.amp = 1.5; p.tail.phase = ms * 0.009;
33
+ p.smile = 0.3;
34
+ return p;
35
+ }
36
+
37
+ /** The frame at `ms` since the pass began. still: the one fixed frame (mid-sky, wings raised). mono: shapes only. */
38
+ /** The sky's size for a terminal `termRows` tall: the mid Q, or the small Q (headroom scaled to match) when the mid sky would
39
+ * not leave 10 rows for the transcript and composer. Never taller than max(12, termRows - 10). */
40
+ export function flySky(termRows) {
41
+ const room = Math.max(12, (termRows || 40) - 10);
42
+ const fits = (size, top) => dragonLayout(120, { size, lm: 0, ty: top }).rows <= room;
43
+ if (fits(SIZE, TOP)) return { size: SIZE, top: TOP, bob: BOB };
44
+ const k = DSIZES.small / DSIZES[SIZE];
45
+ return { size: 'small', top: Math.round(TOP * k), bob: Math.max(1, Math.round(BOB * k)) };
46
+ }
47
+
48
+ export function flyFrame(ms, cols, { still = false, mono = false, theme = 'dark', termRows } = {}) {
49
+ const t = still ? 0 : Math.max(0, Math.min(ms, FLY_PASS_MS));
50
+ const { size: SIZE, top: TOP, bob: BOB } = flySky(termRows);
51
+ const probe = dragonLayout(cols, { size: SIZE, lm: 0, ty: TOP });
52
+ const rows = probe.rows;
53
+ const xc = still ? cols / 2 : -SPAN + (cols + 2 * SPAN) * kf(t, [[0, 0], [FLY_PASS_MS, 1]]);
54
+ const lm = Math.round(xc - probe.qw / 4);
55
+ const ph = (TAU * t) / FLAP_MS, bob = still ? 0 : BOB * Math.cos(ph);
56
+ const L = dragonLayout(cols, { size: SIZE, lm, ty: Math.round(TOP - 2 + bob), rows });
57
+ const pose = flyPose(t);
58
+ if (still) pose.flap = 0.55; // wings up
59
+ const eyes = still ? eyeState('open', 0) : { ...eyeState('idle', t), gx: 0.9, gy: 0.5 };
60
+ return composeCells(pose, eyes, L, PICK_EYES, { theme, mono, t });
61
+ }