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.
- package/LICENSE +35 -0
- package/README.md +144 -2
- package/bin/quox.js +265 -0
- package/bin/quoxon.js +8 -0
- package/lib/api/endpoints/admin.js +151 -0
- package/lib/api/endpoints/aee.js +38 -0
- package/lib/api/endpoints/agent-attach.js +126 -0
- package/lib/api/endpoints/agent-schedules.js +26 -0
- package/lib/api/endpoints/agents.js +63 -0
- package/lib/api/endpoints/assistants.js +62 -0
- package/lib/api/endpoints/audit.js +14 -0
- package/lib/api/endpoints/auth.js +50 -0
- package/lib/api/endpoints/awareness.js +34 -0
- package/lib/api/endpoints/away.js +15 -0
- package/lib/api/endpoints/backup-schedules.js +20 -0
- package/lib/api/endpoints/backups.js +86 -0
- package/lib/api/endpoints/brain.js +140 -0
- package/lib/api/endpoints/budgets.js +62 -0
- package/lib/api/endpoints/calendarq.js +71 -0
- package/lib/api/endpoints/catalog.js +14 -0
- package/lib/api/endpoints/chat.js +61 -0
- package/lib/api/endpoints/consent.js +26 -0
- package/lib/api/endpoints/contactsq.js +68 -0
- package/lib/api/endpoints/conversations.js +46 -0
- package/lib/api/endpoints/custom-roles.js +92 -0
- package/lib/api/endpoints/divisions.js +56 -0
- package/lib/api/endpoints/domains.js +38 -0
- package/lib/api/endpoints/engagement.js +231 -0
- package/lib/api/endpoints/engine.js +11 -0
- package/lib/api/endpoints/entity.js +50 -0
- package/lib/api/endpoints/executions.js +45 -0
- package/lib/api/endpoints/fetchAllowlist.js +27 -0
- package/lib/api/endpoints/file.js +20 -0
- package/lib/api/endpoints/files.js +40 -0
- package/lib/api/endpoints/github.js +21 -0
- package/lib/api/endpoints/governance.js +43 -0
- package/lib/api/endpoints/hat.js +66 -0
- package/lib/api/endpoints/inbox.js +52 -0
- package/lib/api/endpoints/inboxq.js +120 -0
- package/lib/api/endpoints/index.js +242 -0
- package/lib/api/endpoints/invites.js +19 -0
- package/lib/api/endpoints/llm-policy.js +43 -0
- package/lib/api/endpoints/lucid.js +89 -0
- package/lib/api/endpoints/members.js +32 -0
- package/lib/api/endpoints/memory.js +94 -0
- package/lib/api/endpoints/mfa.js +32 -0
- package/lib/api/endpoints/mind.js +13 -0
- package/lib/api/endpoints/mon.js +184 -0
- package/lib/api/endpoints/notesq.js +43 -0
- package/lib/api/endpoints/objectives.js +68 -0
- package/lib/api/endpoints/orgs.js +38 -0
- package/lib/api/endpoints/plugins.js +152 -0
- package/lib/api/endpoints/powers.js +75 -0
- package/lib/api/endpoints/presence.js +33 -0
- package/lib/api/endpoints/prompts.js +69 -0
- package/lib/api/endpoints/qlarity.js +122 -0
- package/lib/api/endpoints/quoxbox.js +55 -0
- package/lib/api/endpoints/quoxchat.js +54 -0
- package/lib/api/endpoints/quoxflow.js +32 -0
- package/lib/api/endpoints/quoxplan.js +121 -0
- package/lib/api/endpoints/quoxseo.js +114 -0
- package/lib/api/endpoints/reach.js +47 -0
- package/lib/api/endpoints/router.js +17 -0
- package/lib/api/endpoints/runs.js +38 -0
- package/lib/api/endpoints/safety.js +53 -0
- package/lib/api/endpoints/scim.js +46 -0
- package/lib/api/endpoints/scopes.js +14 -0
- package/lib/api/endpoints/security.js +69 -0
- package/lib/api/endpoints/setup.js +90 -0
- package/lib/api/endpoints/skills.js +200 -0
- package/lib/api/endpoints/sso.js +67 -0
- package/lib/api/endpoints/stepup.js +20 -0
- package/lib/api/endpoints/tags.js +32 -0
- package/lib/api/endpoints/teams.js +56 -0
- package/lib/api/endpoints/telephony.js +46 -0
- package/lib/api/endpoints/tg.js +56 -0
- package/lib/api/endpoints/tools.js +50 -0
- package/lib/api/endpoints/traces.js +157 -0
- package/lib/api/endpoints/triggers.js +96 -0
- package/lib/api/endpoints/user-library.js +41 -0
- package/lib/api/endpoints/users.js +20 -0
- package/lib/api/endpoints/v1.js +585 -0
- package/lib/api/endpoints/vault.js +192 -0
- package/lib/api/endpoints/voice.js +22 -0
- package/lib/api/endpoints/volt.js +84 -0
- package/lib/api/endpoints/ward.js +47 -0
- package/lib/api/endpoints/webhooks.js +46 -0
- package/lib/api/endpoints/workflows.js +169 -0
- package/lib/api/endpoints/x.js +32 -0
- package/lib/api/endpoints.js +15 -0
- package/lib/commands/actions.js +61 -0
- package/lib/commands/admin.js +375 -0
- package/lib/commands/aee.js +99 -0
- package/lib/commands/agent.js +337 -0
- package/lib/commands/agentAttach.js +1528 -0
- package/lib/commands/approvals.js +119 -0
- package/lib/commands/aside.js +24 -0
- package/lib/commands/ask.js +144 -0
- package/lib/commands/assistant.js +169 -0
- package/lib/commands/auth.js +464 -0
- package/lib/commands/awareness.js +88 -0
- package/lib/commands/backup.js +377 -0
- package/lib/commands/brain.js +1085 -0
- package/lib/commands/budget.js +241 -0
- package/lib/commands/build.js +170 -0
- package/lib/commands/calendar.js +216 -0
- package/lib/commands/capabilities.js +34 -0
- package/lib/commands/chat.js +295 -0
- package/lib/commands/claude.js +380 -0
- package/lib/commands/config-cmd.js +106 -0
- package/lib/commands/consent.js +84 -0
- package/lib/commands/contacts.js +1016 -0
- package/lib/commands/contactsSelftest.js +132 -0
- package/lib/commands/conversation.js +105 -0
- package/lib/commands/dashboard.js +43 -0
- package/lib/commands/department.js +96 -0
- package/lib/commands/dev.js +620 -0
- package/lib/commands/devResident.js +326 -0
- package/lib/commands/devSupervisor.js +1062 -0
- package/lib/commands/discord.js +132 -0
- package/lib/commands/doctor.js +181 -0
- package/lib/commands/domain.js +114 -0
- package/lib/commands/done.js +347 -0
- package/lib/commands/engagement.js +597 -0
- package/lib/commands/entity.js +119 -0
- package/lib/commands/facebook.js +212 -0
- package/lib/commands/fetchAllowlist.js +71 -0
- package/lib/commands/file.js +165 -0
- package/lib/commands/fleet.js +1189 -0
- package/lib/commands/governance.js +647 -0
- package/lib/commands/gripe.js +355 -0
- package/lib/commands/hat.js +374 -0
- package/lib/commands/helpers.js +96 -0
- package/lib/commands/hyperion.js +58 -0
- package/lib/commands/inbox.js +173 -0
- package/lib/commands/instagram.js +264 -0
- package/lib/commands/integration.js +100 -0
- package/lib/commands/inventory.js +115 -0
- package/lib/commands/invites.js +45 -0
- package/lib/commands/licence.js +139 -0
- package/lib/commands/linkedin.js +178 -0
- package/lib/commands/llm-policy.js +117 -0
- package/lib/commands/llm.js +45 -0
- package/lib/commands/lucid.js +597 -0
- package/lib/commands/mail.js +531 -0
- package/lib/commands/memory.js +361 -0
- package/lib/commands/mind.js +71 -0
- package/lib/commands/mon.js +581 -0
- package/lib/commands/monitoring.js +86 -0
- package/lib/commands/motion.js +22 -0
- package/lib/commands/notes.js +1246 -0
- package/lib/commands/notesBatch.js +160 -0
- package/lib/commands/notesBridges.js +56 -0
- package/lib/commands/notesLinks.js +60 -0
- package/lib/commands/notification.js +57 -0
- package/lib/commands/nucleus.js +123 -0
- package/lib/commands/objective.js +240 -0
- package/lib/commands/offload.js +89 -0
- package/lib/commands/onboard.js +329 -0
- package/lib/commands/open.js +56 -0
- package/lib/commands/org.js +276 -0
- package/lib/commands/peek.js +28 -0
- package/lib/commands/plan.js +944 -0
- package/lib/commands/plugin-doctor.js +1091 -0
- package/lib/commands/plugin.js +649 -0
- package/lib/commands/policy.js +78 -0
- package/lib/commands/powers.js +296 -0
- package/lib/commands/presence.js +89 -0
- package/lib/commands/prompt.js +350 -0
- package/lib/commands/provider.js +159 -0
- package/lib/commands/qlarity.js +706 -0
- package/lib/commands/quoxbox.js +270 -0
- package/lib/commands/quoxchat.js +275 -0
- package/lib/commands/quoxseo.js +378 -0
- package/lib/commands/reach.js +159 -0
- package/lib/commands/role.js +286 -0
- package/lib/commands/router.js +77 -0
- package/lib/commands/rows.js +358 -0
- package/lib/commands/run.js +187 -0
- package/lib/commands/safety.js +107 -0
- package/lib/commands/scim.js +88 -0
- package/lib/commands/scope.js +58 -0
- package/lib/commands/security.js +157 -0
- package/lib/commands/server.js +292 -0
- package/lib/commands/service.js +89 -0
- package/lib/commands/settings.js +99 -0
- package/lib/commands/setup.js +569 -0
- package/lib/commands/skillManifest.js +113 -0
- package/lib/commands/skillRightsFormat.js +38 -0
- package/lib/commands/skills.js +687 -0
- package/lib/commands/slot.js +1451 -0
- package/lib/commands/sso.js +229 -0
- package/lib/commands/status.js +137 -0
- package/lib/commands/tag.js +91 -0
- package/lib/commands/team.js +142 -0
- package/lib/commands/tg.js +240 -0
- package/lib/commands/tiktok.js +218 -0
- package/lib/commands/tips.js +23 -0
- package/lib/commands/tool.js +304 -0
- package/lib/commands/trace.js +530 -0
- package/lib/commands/trigger.js +223 -0
- package/lib/commands/update.js +46 -0
- package/lib/commands/vault.js +1447 -0
- package/lib/commands/vm.js +237 -0
- package/lib/commands/voice.js +213 -0
- package/lib/commands/volt.js +570 -0
- package/lib/commands/walkthrough.js +32 -0
- package/lib/commands/watch.js +167 -0
- package/lib/commands/webhook.js +137 -0
- package/lib/commands/welcome.js +14 -0
- package/lib/commands/workflow.js +660 -0
- package/lib/commands/x.js +448 -0
- package/lib/core/actingAs.js +136 -0
- package/lib/core/activeSummary.js +186 -0
- package/lib/core/aee.js +53 -0
- package/lib/core/agentAlias.js +163 -0
- package/lib/core/approvalContext.js +61 -0
- package/lib/core/aside.js +54 -0
- package/lib/core/askDecision.js +60 -0
- package/lib/core/auth.js +501 -0
- package/lib/core/banner.js +143 -0
- package/lib/core/brainPrime.js +90 -0
- package/lib/core/callerSource.js +129 -0
- package/lib/core/claudeLs.js +94 -0
- package/lib/core/cliBuild.js +62 -0
- package/lib/core/client.js +693 -0
- package/lib/core/commandRegistrars.js +121 -0
- package/lib/core/completions.js +163 -0
- package/lib/core/config.js +669 -0
- package/lib/core/confirm.js +37 -0
- package/lib/core/customHats.js +168 -0
- package/lib/core/deeplinks.js +76 -0
- package/lib/core/doneEngineFetch.js +227 -0
- package/lib/core/errors.js +441 -0
- package/lib/core/global-flags.js +190 -0
- package/lib/core/governedSession.js +402 -0
- package/lib/core/hyperion.js +102 -0
- package/lib/core/inboxResolution.js +65 -0
- package/lib/core/lazyCommands.js +122 -0
- package/lib/core/liveSessionsReport.js +112 -0
- package/lib/core/offload.js +504 -0
- package/lib/core/org-override.js +52 -0
- package/lib/core/orgResolve.js +70 -0
- package/lib/core/output.js +239 -0
- package/lib/core/peek.js +126 -0
- package/lib/core/prodEnv.js +7 -0
- package/lib/core/profileUsers.js +51 -0
- package/lib/core/promptCancel.js +18 -0
- package/lib/core/quoxglyph.js +158 -0
- package/lib/core/repoPath.js +11 -0
- package/lib/core/residentAlarm.js +282 -0
- package/lib/core/residentAuth.js +243 -0
- package/lib/core/residentPump.js +229 -0
- package/lib/core/residentSeed.js +106 -0
- package/lib/core/rootOptions.js +39 -0
- package/lib/core/router.js +168 -0
- package/lib/core/selfUpdate.js +188 -0
- package/lib/core/sessionHeartbeat.js +192 -0
- package/lib/core/sessionsOverview.js +224 -0
- package/lib/core/slotKeeper.js +527 -0
- package/lib/core/slotWake.js +120 -0
- package/lib/core/supervisorEngine.js +933 -0
- package/lib/core/systemdInstaller.js +256 -0
- package/lib/core/version.js +87 -0
- package/lib/core/vm.js +361 -0
- package/lib/core/vmTui.js +86 -0
- package/lib/core/walkthrough.js +35 -0
- package/lib/hyperion/deck.js +29 -0
- package/lib/lucid/LucidCard.jsx +68 -0
- package/lib/lucid/LucidIntro.jsx +92 -0
- package/lib/lucid/blind.js +71 -0
- package/lib/lucid/cards.js +86 -0
- package/lib/lucid/deck.js +32 -0
- package/lib/lucid/fmt.js +139 -0
- package/lib/lucid/markdown.js +81 -0
- package/lib/lucid/motion.js +56 -0
- package/lib/lucid/sitrep.js +173 -0
- package/lib/plugins/loader.js +93 -0
- package/lib/quoxon/activity.js +116 -0
- package/lib/quoxon/aocl.js +117 -0
- package/lib/quoxon/api.js +952 -0
- package/lib/quoxon/app.js +4032 -0
- package/lib/quoxon/approvalFacts.js +94 -0
- package/lib/quoxon/approvalsView.js +325 -0
- package/lib/quoxon/asideView.js +40 -0
- package/lib/quoxon/ask.js +121 -0
- package/lib/quoxon/away.js +52 -0
- package/lib/quoxon/bang.js +224 -0
- package/lib/quoxon/bulkRisk.js +17 -0
- package/lib/quoxon/capabilities.js +82 -0
- package/lib/quoxon/cells.js +53 -0
- package/lib/quoxon/commandShort.js +112 -0
- package/lib/quoxon/commands.js +479 -0
- package/lib/quoxon/connect.js +654 -0
- package/lib/quoxon/connectCard.js +45 -0
- package/lib/quoxon/consent.js +86 -0
- package/lib/quoxon/context.js +68 -0
- package/lib/quoxon/copy.js +34 -0
- package/lib/quoxon/countdownLine.js +11 -0
- package/lib/quoxon/demo.autoplay.js +29 -0
- package/lib/quoxon/demo.fixtures.js +24 -0
- package/lib/quoxon/demo.js +76 -0
- package/lib/quoxon/devObserver.js +20 -0
- package/lib/quoxon/dividerAocl.js +191 -0
- package/lib/quoxon/dividerRule.js +57 -0
- package/lib/quoxon/dragonModes.js +150 -0
- package/lib/quoxon/dragonView.js +41 -0
- package/lib/quoxon/earlyInput.js +40 -0
- package/lib/quoxon/echo.js +15 -0
- package/lib/quoxon/egg.js +36 -0
- package/lib/quoxon/events.js +677 -0
- package/lib/quoxon/feedback.js +50 -0
- package/lib/quoxon/gallery.js +237 -0
- package/lib/quoxon/handoffOffer.js +78 -0
- package/lib/quoxon/hatSwitch.js +37 -0
- package/lib/quoxon/headless.js +161 -0
- package/lib/quoxon/hostUrls.js +41 -0
- package/lib/quoxon/indicator.js +197 -0
- package/lib/quoxon/intent.js +52 -0
- package/lib/quoxon/keys.js +164 -0
- package/lib/quoxon/launcher.js +103 -0
- package/lib/quoxon/main.js +176 -0
- package/lib/quoxon/markdown.js +341 -0
- package/lib/quoxon/markdownSettle.js +19 -0
- package/lib/quoxon/matrixDomains.json +46 -0
- package/lib/quoxon/mentions.js +90 -0
- package/lib/quoxon/mind.js +103 -0
- package/lib/quoxon/mode.js +46 -0
- package/lib/quoxon/model.js +311 -0
- package/lib/quoxon/modelPrefs.js +345 -0
- package/lib/quoxon/motion/clock.js +70 -0
- package/lib/quoxon/motion/color.js +35 -0
- package/lib/quoxon/motion/frame.js +14 -0
- package/lib/quoxon/motion/level.js +91 -0
- package/lib/quoxon/motion/reveal.js +54 -0
- package/lib/quoxon/motion/ring.js +79 -0
- package/lib/quoxon/mouse.js +211 -0
- package/lib/quoxon/noai.js +57 -0
- package/lib/quoxon/objects/agent.js +61 -0
- package/lib/quoxon/objects/away.js +72 -0
- package/lib/quoxon/objects/crystal.js +100 -0
- package/lib/quoxon/objects/fetch.js +182 -0
- package/lib/quoxon/objects/fleet.js +149 -0
- package/lib/quoxon/objects/health.js +186 -0
- package/lib/quoxon/objects/index.js +106 -0
- package/lib/quoxon/objects/ladder.js +71 -0
- package/lib/quoxon/objects/memory.js +44 -0
- package/lib/quoxon/objects/mirror.js +137 -0
- package/lib/quoxon/objects/model.js +118 -0
- package/lib/quoxon/objects/peek.js +17 -0
- package/lib/quoxon/objects/proof.js +110 -0
- package/lib/quoxon/objects/prove.js +130 -0
- package/lib/quoxon/objects/replay.js +125 -0
- package/lib/quoxon/objects/sitrep.js +58 -0
- package/lib/quoxon/objects/skill.js +105 -0
- package/lib/quoxon/objects/view.js +87 -0
- package/lib/quoxon/objects/workflow.js +119 -0
- package/lib/quoxon/observers.js +42 -0
- package/lib/quoxon/onboarding/copy.js +263 -0
- package/lib/quoxon/onboarding/credential.js +108 -0
- package/lib/quoxon/onboarding/detect.js +22 -0
- package/lib/quoxon/onboarding/dockerOffer.js +45 -0
- package/lib/quoxon/onboarding/failureCause.js +33 -0
- package/lib/quoxon/onboarding/finish.js +134 -0
- package/lib/quoxon/onboarding/index.js +94 -0
- package/lib/quoxon/onboarding/installRunner.js +284 -0
- package/lib/quoxon/onboarding/intent.js +53 -0
- package/lib/quoxon/onboarding/journey.js +73 -0
- package/lib/quoxon/onboarding/preflight.js +156 -0
- package/lib/quoxon/onboarding/probe.js +65 -0
- package/lib/quoxon/onboarding/runner.js +58 -0
- package/lib/quoxon/onboarding/view.js +682 -0
- package/lib/quoxon/orgLabel.js +10 -0
- package/lib/quoxon/orgSwitch.js +33 -0
- package/lib/quoxon/ownBroadcast.js +22 -0
- package/lib/quoxon/palette.js +43 -0
- package/lib/quoxon/print.js +98 -0
- package/lib/quoxon/profileSwitch.js +53 -0
- package/lib/quoxon/promptHistory.js +41 -0
- package/lib/quoxon/providers.js +48 -0
- package/lib/quoxon/qart.js +348 -0
- package/lib/quoxon/qdragon.js +410 -0
- package/lib/quoxon/qdragonFly.js +61 -0
- package/lib/quoxon/qdragonScenes.js +282 -0
- package/lib/quoxon/qeyes.js +213 -0
- package/lib/quoxon/qglyph.js +143 -0
- package/lib/quoxon/qhello.js +58 -0
- package/lib/quoxon/qmotion.js +132 -0
- package/lib/quoxon/render.js +1167 -0
- package/lib/quoxon/resend.js +72 -0
- package/lib/quoxon/roster.js +307 -0
- package/lib/quoxon/route.js +39 -0
- package/lib/quoxon/rows.js +711 -0
- package/lib/quoxon/rowsStore.js +80 -0
- package/lib/quoxon/rules.js +130 -0
- package/lib/quoxon/screenContext.js +150 -0
- package/lib/quoxon/screenFrames.js +254 -0
- package/lib/quoxon/session.js +238 -0
- package/lib/quoxon/sessionDead.js +17 -0
- package/lib/quoxon/signin.js +125 -0
- package/lib/quoxon/skills.js +30 -0
- package/lib/quoxon/slash/agents.js +112 -0
- package/lib/quoxon/slash/argSources.js +65 -0
- package/lib/quoxon/slash/args.js +65 -0
- package/lib/quoxon/slash/automate.js +89 -0
- package/lib/quoxon/slash/broadcast.js +140 -0
- package/lib/quoxon/slash/broadcastRun.js +108 -0
- package/lib/quoxon/slash/card.js +30 -0
- package/lib/quoxon/slash/challenge.js +114 -0
- package/lib/quoxon/slash/cliCommand.js +53 -0
- package/lib/quoxon/slash/cliLeaves.json +948 -0
- package/lib/quoxon/slash/compact.js +90 -0
- package/lib/quoxon/slash/confirm.js +30 -0
- package/lib/quoxon/slash/crystallize.js +69 -0
- package/lib/quoxon/slash/dashboard.js +136 -0
- package/lib/quoxon/slash/draft.js +54 -0
- package/lib/quoxon/slash/hatWalk.js +206 -0
- package/lib/quoxon/slash/inverses.js +77 -0
- package/lib/quoxon/slash/killer.js +24 -0
- package/lib/quoxon/slash/killerApi.js +16 -0
- package/lib/quoxon/slash/ledger.js +88 -0
- package/lib/quoxon/slash/listView.js +30 -0
- package/lib/quoxon/slash/modelCmd.js +261 -0
- package/lib/quoxon/slash/palette.js +118 -0
- package/lib/quoxon/slash/paletteController.js +169 -0
- package/lib/quoxon/slash/panels.js +116 -0
- package/lib/quoxon/slash/picker.js +56 -0
- package/lib/quoxon/slash/restart.js +202 -0
- package/lib/quoxon/slash/resume.js +59 -0
- package/lib/quoxon/slash/rowCmd.js +157 -0
- package/lib/quoxon/slash/rowWalk.js +175 -0
- package/lib/quoxon/slash/settings.js +60 -0
- package/lib/quoxon/slash/spawn.js +177 -0
- package/lib/quoxon/slash/stepUp.js +274 -0
- package/lib/quoxon/slash/stepUpCard.js +60 -0
- package/lib/quoxon/slash/stepUpCmds.js +78 -0
- package/lib/quoxon/slash/undoApi.js +38 -0
- package/lib/quoxon/slash/undoCmd.js +49 -0
- package/lib/quoxon/slash/undoWish.js +15 -0
- package/lib/quoxon/slash/watch.js +164 -0
- package/lib/quoxon/slash/wish.js +23 -0
- package/lib/quoxon/slash/wishCmd.js +32 -0
- package/lib/quoxon/slotChat.js +300 -0
- package/lib/quoxon/slotFormat.js +195 -0
- package/lib/quoxon/slotRun.js +131 -0
- package/lib/quoxon/sound/index.js +186 -0
- package/lib/quoxon/sound/mapping.js +120 -0
- package/lib/quoxon/sound/output.js +52 -0
- package/lib/quoxon/sound/synth.js +122 -0
- package/lib/quoxon/stray.js +22 -0
- package/lib/quoxon/suggestCommand.js +59 -0
- package/lib/quoxon/term.js +141 -0
- package/lib/quoxon/textBuffer.js +416 -0
- package/lib/quoxon/theme.js +286 -0
- package/lib/quoxon/tips.js +433 -0
- package/lib/quoxon/toolError.js +41 -0
- package/lib/quoxon/transcript.js +188 -0
- package/lib/quoxon/web/qface.js +89 -0
- package/lib/quoxon/welcome.js +52 -0
- package/lib/quoxon/whatsnew.js +136 -0
- package/lib/quoxon/whatsnew.jsonl +89 -0
- package/lib/quoxon/windowOrg.js +113 -0
- package/lib/server/diag.js +129 -0
- package/lib/server/doctor.js +71 -0
- package/lib/server/install.js +149 -0
- package/lib/server/pluginEnable.js +161 -0
- package/lib/server/skew.js +56 -0
- package/lib/server/snapshot.js +131 -0
- package/lib/server/status.js +128 -0
- package/lib/server/sys.js +65 -0
- package/lib/server/uninstall.js +63 -0
- package/lib/server/update.js +234 -0
- package/lib/toolOutputShape.js +315 -0
- package/lib/tui/app.jsx +289 -0
- package/lib/tui/components/Breadcrumb.jsx +42 -0
- package/lib/tui/components/ChatInput.jsx +68 -0
- package/lib/tui/components/Confirm.jsx +32 -0
- package/lib/tui/components/DataTable.jsx +270 -0
- package/lib/tui/components/DetailPanel.jsx +241 -0
- package/lib/tui/components/HelpOverlay.jsx +67 -0
- package/lib/tui/components/Layout.jsx +129 -0
- package/lib/tui/components/Palette.jsx +141 -0
- package/lib/tui/components/SearchInput.jsx +125 -0
- package/lib/tui/components/Sparkline.jsx +55 -0
- package/lib/tui/components/StatusBar.jsx +133 -0
- package/lib/tui/components/Toast.jsx +52 -0
- package/lib/tui/hooks/useApi.js +44 -0
- package/lib/tui/hooks/useHealth.js +90 -0
- package/lib/tui/hooks/usePolledApi.js +86 -0
- package/lib/tui/hooks/useTerminalSize.js +46 -0
- package/lib/tui/index.js +56 -0
- package/lib/tui/intro/Intro.jsx +332 -0
- package/lib/tui/jsx-loader.js +32 -0
- package/lib/tui/keys.js +87 -0
- package/lib/tui/registry.js +49 -0
- package/lib/tui/theme.js +103 -0
- package/lib/tui/views/AdminView.jsx +398 -0
- package/lib/tui/views/AgentView.jsx +204 -0
- package/lib/tui/views/BackupView.jsx +225 -0
- package/lib/tui/views/BrainView.jsx +223 -0
- package/lib/tui/views/ChatView.jsx +468 -0
- package/lib/tui/views/FilesView.jsx +218 -0
- package/lib/tui/views/FleetView.jsx +234 -0
- package/lib/tui/views/GovernanceView.jsx +453 -0
- package/lib/tui/views/HealthView.jsx +216 -0
- package/lib/tui/views/HyperionDeck.jsx +79 -0
- package/lib/tui/views/InboxView.jsx +228 -0
- package/lib/tui/views/LucidDeck.jsx +719 -0
- package/lib/tui/views/MainMenu.jsx +123 -0
- package/lib/tui/views/MemoryView.jsx +377 -0
- package/lib/tui/views/ObjectivesView.jsx +230 -0
- package/lib/tui/views/OrgView.jsx +229 -0
- package/lib/tui/views/ToolView.jsx +221 -0
- package/lib/tui/views/VaultView.jsx +422 -0
- package/lib/tui/views/WorkflowView.jsx +329 -0
- package/package.json +75 -4
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The horned Q as Braille art, and every motion the owner reviewed in the lab (~/quoxon-work/intro/lab):
|
|
3
|
+
* Orbit & Lock (the intro), Portal, Particle collapse. CLI-QUOX.
|
|
4
|
+
*
|
|
5
|
+
* PURE AND PORTABLE on purpose: no Ink, no process, no timers, no terminal APIs. Inputs are size, progress
|
|
6
|
+
* (or ms), state and seed; the core output is rows of cells `{ ch, rgb, bg? }` (rgb null = default colour; bg, when
|
|
7
|
+
* present, a background colour: the dragon's eyes in qdragon.js use it). The
|
|
8
|
+
* same module renders in the terminal (cellsToAnsi) and in a browser (web/qface.js), which is how the Q
|
|
9
|
+
* becomes the face of the app on cli.quox.ai as well as in the CLI.
|
|
10
|
+
*
|
|
11
|
+
* The Q is rasterised from a small vector description (ring bowl, tapered tail, two curved horns) at the
|
|
12
|
+
* dot resolution of the target size, so every size has a smooth bowl instead of a scaled bitmap. Each dot
|
|
13
|
+
* knows which part it belongs to (bowl, tail, horn) and how far along that part it sits, which is what the
|
|
14
|
+
* tail sweep, the horn glint and the portal reveal key off.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const SKY = [56, 189, 248];
|
|
18
|
+
export const VIOLET = [168, 85, 247];
|
|
19
|
+
export const AMBER = [245, 158, 11];
|
|
20
|
+
export const RED = [239, 68, 68];
|
|
21
|
+
const TAU = Math.PI * 2;
|
|
22
|
+
const ASPECT = 0.82; // silhouette width / height, in square dots
|
|
23
|
+
|
|
24
|
+
// size -> dot height. A Braille cell is 2 dots wide and 4 tall, so rows = H / 4.
|
|
25
|
+
// small is the lab's compact particle Q (under 60 cols); large/mid are the intro sizes.
|
|
26
|
+
export const SIZES = { large: 72, mid: 44, small: 24 };
|
|
27
|
+
|
|
28
|
+
/** Pick the Q size for a terminal. Under 60 cols the caller uses the half-block compact Q instead. */
|
|
29
|
+
export function qSize(cols, rows) {
|
|
30
|
+
if (cols < 60) return 'compact';
|
|
31
|
+
return cols >= 100 && rows >= 30 ? 'large' : 'mid';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Lab parity sizing: under 60 cols (or under 12 rows) the lab's compact particle Q, never a half-block. */
|
|
35
|
+
export function labSize(cols, rows) {
|
|
36
|
+
if (cols < 60 || rows < 12) return 'small';
|
|
37
|
+
return qSize(cols, rows);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function qDims(size) {
|
|
41
|
+
const H = SIZES[size];
|
|
42
|
+
const cells = Math.ceil((H * ASPECT) / 2);
|
|
43
|
+
return { H, W: cells * 2, cols: cells, rows: H / 4 };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ---- silhouette (unit space: y 0..1 top to bottom, x 0..ASPECT) -----------------------------------
|
|
47
|
+
const distSeg = (px, py, ax, ay, bx, by) => {
|
|
48
|
+
const dx = bx - ax, dy = by - ay;
|
|
49
|
+
const t = Math.max(0, Math.min(1, ((px - ax) * dx + (py - ay) * dy) / (dx * dx + dy * dy)));
|
|
50
|
+
return [Math.sqrt((px - (ax + dx * t)) ** 2 + (py - (ay + dy * t)) ** 2), t];
|
|
51
|
+
};
|
|
52
|
+
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]];
|
|
53
|
+
|
|
54
|
+
export const BOWL = { cx: ASPECT / 2, cy: 0.6, rx: 0.4, ry: 0.385, w: 0.118 };
|
|
55
|
+
// Each horn is a quadratic curve, thick at the base and tapering to a point: out and up like a bull's.
|
|
56
|
+
// The right horn is the exact mirror of the left about the bowl's axis (it was hand-tuned and its tip had
|
|
57
|
+
// drifted to y 0.0 against the left's 0.03, which read as a thin stalk next to a solid horn).
|
|
58
|
+
const LEFT_HORN = { a: [0.2, 0.29], b: [-0.02, 0.27], c: [0.02, 0.03], r0: 0.048 };
|
|
59
|
+
const mirrorX = (p) => [ASPECT - p[0], p[1]];
|
|
60
|
+
const HORNS = [LEFT_HORN, { a: mirrorX(LEFT_HORN.a), b: mirrorX(LEFT_HORN.b), c: mirrorX(LEFT_HORN.c), r0: LEFT_HORN.r0 }];
|
|
61
|
+
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 })));
|
|
62
|
+
const TAIL = { a: [0.4, 0.69], b: [0.79, 0.985], r0: 0.07, r1: 0.04 };
|
|
63
|
+
|
|
64
|
+
/** Which part of the Q a unit point is in: null, or { part: 'bowl'|'tail'|'horn', t } (t = 0 base .. 1 tip). */
|
|
65
|
+
function partAt(x, y) {
|
|
66
|
+
const [d, t] = distSeg(x, y, ...TAIL.a, ...TAIL.b);
|
|
67
|
+
const inTail = d <= TAIL.r0 + (TAIL.r1 - TAIL.r0) * t;
|
|
68
|
+
const dx = (x - BOWL.cx) / BOWL.rx, dy = (y - BOWL.cy) / BOWL.ry;
|
|
69
|
+
const e = Math.sqrt(dx ** 2 + dy ** 2);
|
|
70
|
+
const inner = 1 - BOWL.w / ((BOWL.rx + BOWL.ry) / 2);
|
|
71
|
+
if (e <= 1 && e >= inner) return { part: inTail && t > 0.45 ? 'tail' : 'bowl', t: inTail ? t : 0 };
|
|
72
|
+
if (inTail) return { part: 'tail', t };
|
|
73
|
+
if (y > 0.34) return null;
|
|
74
|
+
for (const pts of HORN_PTS) for (const q of pts) if (Math.sqrt((x - q.p[0]) ** 2 + (y - q.p[1]) ** 2) <= q.r0 * (1 - q.t * 0.93) + 0.004) return { part: 'horn', t: q.t };
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const maskCache = new Map();
|
|
79
|
+
/**
|
|
80
|
+
* Boolean mask of the Q silhouette at a size: { W, H, ox, on(x, y), dots: [{ x, y, part, t }] }.
|
|
81
|
+
* ox is the left offset of the silhouette inside the cell grid (dots).
|
|
82
|
+
*/
|
|
83
|
+
export function qMask(size) {
|
|
84
|
+
if (maskCache.has(size)) return maskCache.get(size);
|
|
85
|
+
const { W, H } = qDims(size);
|
|
86
|
+
const ox = (W - H * ASPECT) / 2; // the Q's axis sits exactly on the grid centre, so the mask mirrors dot for dot
|
|
87
|
+
const dots = [];
|
|
88
|
+
const grid = new Uint8Array(W * H);
|
|
89
|
+
for (let y = 0; y < H; y++) for (let x = 0; x < W; x++) {
|
|
90
|
+
// 2x2 supersample for clean edges
|
|
91
|
+
let n = 0;
|
|
92
|
+
for (const [sx, sy] of [[0.25, 0.25], [0.75, 0.25], [0.25, 0.75], [0.75, 0.75]]) if (partAt((x - ox + sx) / H, (y + sy) / H)) n++;
|
|
93
|
+
if (n >= 2) {
|
|
94
|
+
grid[y * W + x] = 1;
|
|
95
|
+
const p = partAt((x - ox + 0.5) / H, (y + 0.5) / H) || { part: 'bowl', t: 0 };
|
|
96
|
+
dots.push({ x, y, part: p.part, t: p.t });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const m = { W, H, ox, on: (x, y) => grid[y * W + x] === 1, dots };
|
|
100
|
+
maskCache.set(size, m);
|
|
101
|
+
return m;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ---- intensity field -> cells -> text -----------------------------------------------------------------
|
|
105
|
+
const BR = [[0x1, 0x8], [0x2, 0x10], [0x4, 0x20], [0x40, 0x80]];
|
|
106
|
+
const clamp = (x, a = 0, b = 1) => Math.max(a, Math.min(b, x));
|
|
107
|
+
const smooth = (e) => { e = clamp(e); return e * e * (3 - 2 * e); };
|
|
108
|
+
const lerp = (a, b, t) => a.map((v, i) => v + (b[i] - v) * t);
|
|
109
|
+
const RESET = '\x1b[0m';
|
|
110
|
+
|
|
111
|
+
/** A field of dot intensities. 0 = off, 1 = the settled Q, > 1 = a flash (pushes towards white). */
|
|
112
|
+
export function makeField(W, H) {
|
|
113
|
+
const v = new Float32Array(W * H);
|
|
114
|
+
return {
|
|
115
|
+
W, H, v,
|
|
116
|
+
set(x, y, val) {
|
|
117
|
+
x = Math.round(x); y = Math.round(y);
|
|
118
|
+
if (x < 0 || y < 0 || x >= W || y >= H) return;
|
|
119
|
+
const i = y * W + x; if (val > v[i]) v[i] = val;
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Turn a field into rows of cells { ch, rgb }. rgb is null for blanks and in mono.
|
|
126
|
+
* color false (mono): shapes only, dim dots (< 0.35) are dropped, as in the lab.
|
|
127
|
+
* quant true (terminal default): 4 hue bands x 6 brightness levels, so SGR runs stay long (Ink tokenising
|
|
128
|
+
* a per-cell colour was ~100 ms a frame); trails keep their own levels so the drag still reads.
|
|
129
|
+
* quant false (web): the lab's continuous shade, every cell its own colour.
|
|
130
|
+
* tint: one rgb for every cell instead of the sky to violet gradient (amber, red, ...).
|
|
131
|
+
*/
|
|
132
|
+
export function fieldToCells(field, { color = true, quant = true, tint = null } = {}) {
|
|
133
|
+
const { W, H, v } = field;
|
|
134
|
+
const thr = color ? 0.04 : 0.35;
|
|
135
|
+
const cols = W / 2, rows = H / 4, out = [];
|
|
136
|
+
for (let cy = 0; cy < rows; cy++) {
|
|
137
|
+
const row = [];
|
|
138
|
+
for (let cx = 0; cx < cols; cx++) {
|
|
139
|
+
let bits = 0, m = 0;
|
|
140
|
+
for (let dy = 0; dy < 4; dy++) for (let dx = 0; dx < 2; dx++) {
|
|
141
|
+
const val = v[(cy * 4 + dy) * W + cx * 2 + dx];
|
|
142
|
+
if (val > thr) { bits |= BR[dy][dx]; if (val > m) m = val; }
|
|
143
|
+
}
|
|
144
|
+
if (!bits) { row.push({ ch: ' ', rgb: null }); continue; }
|
|
145
|
+
let rgb = null;
|
|
146
|
+
if (color) {
|
|
147
|
+
if (quant) {
|
|
148
|
+
const base = tint || lerp(SKY, VIOLET, (Math.min(3, Math.floor((cx / cols) * 4)) + 0.5) / 4);
|
|
149
|
+
const [lum, fl] = m > 1.5 ? [1, 0.85] : m > 1.05 ? [1, 0.45] : m >= 0.95 ? [1, 0] : m > 0.6 ? [0.72, 0] : m > 0.38 ? [0.48, 0] : [0.3, 0];
|
|
150
|
+
rgb = base.map((c) => Math.round(c * lum + (255 - c * lum) * fl));
|
|
151
|
+
} else {
|
|
152
|
+
const base = tint || lerp(SKY, VIOLET, cols > 1 ? cx / (cols - 1) : 0);
|
|
153
|
+
const f = 0.28 + 0.72 * Math.min(1, m), fl = clamp(m - 1);
|
|
154
|
+
rgb = base.map((c) => { c *= f; return Math.round(c + (255 - c) * fl * 0.9); });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
row.push({ ch: String.fromCharCode(0x2800 + bits), rgb });
|
|
158
|
+
}
|
|
159
|
+
out.push(row);
|
|
160
|
+
}
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const sgr = (rgb, bg = false) => `\x1b[${bg ? 48 : 38};2;${rgb.map((x) => Math.max(0, Math.min(255, Math.round(x)))).join(';')}m`;
|
|
165
|
+
/**
|
|
166
|
+
* Cells -> ANSI lines (truecolor SGR, one escape per colour run). Mono cells carry no SGR at all. A cell may
|
|
167
|
+
* also carry `bg` (the dragon's eyes are quadrant blocks with a foreground AND a background colour); a
|
|
168
|
+
* background run is closed with a reset before the next cell without one, so it never bleeds. Cells without
|
|
169
|
+
* bg render exactly as they always have.
|
|
170
|
+
*/
|
|
171
|
+
export function cellsToAnsi(rows) {
|
|
172
|
+
return rows.map((row) => {
|
|
173
|
+
let s = '', last = '', lastBg = '';
|
|
174
|
+
for (const c of row) {
|
|
175
|
+
const b = c.bg ? sgr(c.bg, true) : '';
|
|
176
|
+
if (lastBg && !b) { s += RESET; last = ''; lastBg = ''; }
|
|
177
|
+
if (c.rgb) { const e = sgr(c.rgb); if (e !== last) { s += e; last = e; } }
|
|
178
|
+
else if (last && c.ch !== ' ') { s += RESET; last = ''; if (lastBg) lastBg = ''; }
|
|
179
|
+
if (b && b !== lastBg) { s += b; lastBg = b; }
|
|
180
|
+
s += c.ch;
|
|
181
|
+
}
|
|
182
|
+
return s + (last || lastBg ? RESET : '');
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/** Cells -> plain text lines. */
|
|
186
|
+
export const cellsToText = (rows) => rows.map((r) => r.map((c) => c.ch).join(''));
|
|
187
|
+
|
|
188
|
+
const rng = (seed) => () => { 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; };
|
|
189
|
+
|
|
190
|
+
// ---- the settled Q ------------------------------------------------------------------------------------
|
|
191
|
+
/** Cells of the settled Q. */
|
|
192
|
+
export function qCells(size, opts = {}) {
|
|
193
|
+
const m = qMask(size), f = makeField(m.W, m.H);
|
|
194
|
+
for (const d of m.dots) f.v[d.y * m.W + d.x] = 1;
|
|
195
|
+
return fieldToCells(f, opts);
|
|
196
|
+
}
|
|
197
|
+
/** Rows of text for the settled Q (identical to orbitFrame(size, 1)). */
|
|
198
|
+
export function qLines(size, { color = true } = {}) { return cellsToAnsi(qCells(size, { color })); }
|
|
199
|
+
|
|
200
|
+
// ---- 1: Orbit & Lock (and 3: Particle collapse) ---------------------------------------------------------
|
|
201
|
+
/** The intro's whole budget, ms. Orbit runs ORBIT_MS of it; the rest holds the finished mark. */
|
|
202
|
+
export const INTRO_MS = 900;
|
|
203
|
+
export const ORBIT_MS = 820;
|
|
204
|
+
const FLASH_MS = 170;
|
|
205
|
+
// Lab parameters, verbatim (lab.mjs build()): orbit for large/mid, particle for the compact Q.
|
|
206
|
+
const SWARM = {
|
|
207
|
+
orbit: { band: 0.3, appearMax: 0.08, lockStart: 0.42, lockSpan: 0.2, lockLen: 0.2, byAngle: true, spin: [0.5, 5] },
|
|
208
|
+
particle: { band: 0.05, appearMax: 0.5, lockStart: 0.55, lockSpan: 0.12, lockLen: 0.2, byAngle: false, spin: [1.2, 2.5] },
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const swarmCache = new Map();
|
|
212
|
+
function swarm(size, kind, seed) {
|
|
213
|
+
const key = `${size}:${kind}:${seed}`;
|
|
214
|
+
if (swarmCache.has(key)) return swarmCache.get(key);
|
|
215
|
+
const P = SWARM[kind], m = qMask(size), R = rng(seed + m.H);
|
|
216
|
+
const cx = m.W / 2, cy = m.H / 2, Rmax = Math.min(m.W, m.H) / 2 - 1.5;
|
|
217
|
+
const parts = m.dots.map((d) => ({
|
|
218
|
+
tx: d.x, ty: d.y, part: d.part, pt: d.t, ang: Math.atan2(d.y - cy, d.x - cx), th0: R() * TAU,
|
|
219
|
+
rho: Rmax - Rmax * P.band * R() ** 2, w: 0.85 + 0.3 * R(), ap: R() * P.appearMax, rnd: R(),
|
|
220
|
+
}));
|
|
221
|
+
const key2 = (p) => (P.byAngle ? p.ang : p.rnd);
|
|
222
|
+
[...parts].sort((a, b) => key2(a) - key2(b)).forEach((p, i) => { p.s = P.lockStart + P.lockSpan * (i / (parts.length - 1)); });
|
|
223
|
+
// Tail sweep: the tail is the last stroke to land, base to tip, so the Q finishes with a flourish.
|
|
224
|
+
// Horns land tip-last, so each horn grows out of the bowl with its flash travelling up to the point.
|
|
225
|
+
const end = P.lockStart + P.lockSpan;
|
|
226
|
+
for (const p of parts) {
|
|
227
|
+
if (p.part === 'tail') p.s = end - 0.06 + 0.08 * p.pt;
|
|
228
|
+
else if (p.part === 'horn') p.s = Math.min(p.s, end - 0.1) + 0.05 * p.pt;
|
|
229
|
+
}
|
|
230
|
+
const r = { P, parts, cx, cy };
|
|
231
|
+
swarmCache.set(key, r);
|
|
232
|
+
return r;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* The swarm field at t ms. Each particle draws a head plus two trail samples that lag along its path; the
|
|
237
|
+
* lag grows with speed (0.09 * (1 + 2u) rad), which is the "drag" in the lab: fast particles smear.
|
|
238
|
+
*/
|
|
239
|
+
function swarmField(size, t, { kind = 'orbit', dur = ORBIT_MS, seed = 11 } = {}) {
|
|
240
|
+
const m = qMask(size), { P, parts, cx, cy } = swarm(size, kind, seed), f = makeField(m.W, m.H);
|
|
241
|
+
const u = t / dur, settled = t > dur + FLASH_MS + 300;
|
|
242
|
+
const ph = TAU * (P.spin[0] * u + P.spin[1] * u * u);
|
|
243
|
+
for (const p of parts) {
|
|
244
|
+
const e = settled ? 1 : smooth((u - p.s) / P.lockLen);
|
|
245
|
+
if (e >= 1) {
|
|
246
|
+
const lt = (u - (p.s + P.lockLen)) * dur;
|
|
247
|
+
f.set(p.tx, p.ty, settled ? 1 : 1 + Math.max(0, 1 - lt / FLASH_MS) * 0.9);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (u < p.ap) continue;
|
|
251
|
+
const fade = Math.min(1, ((u - p.ap) * dur) / 90);
|
|
252
|
+
for (let k = 0; k < 3; k++) {
|
|
253
|
+
const th = p.th0 + (ph - k * 0.09 * (1 + 2 * u)) * p.w;
|
|
254
|
+
const x = cx + p.rho * Math.cos(th), y = cy + p.rho * Math.sin(th);
|
|
255
|
+
f.set(x + (p.tx - x) * e, y + (p.ty - y) * e, (k === 0 ? 0.9 : k === 1 ? 0.5 : 0.28) * fade + (e > 0 && k === 0 ? 0.4 * e : 0));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return f;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/** Orbit & Lock cells at t ms (0..INTRO_MS; >= INTRO_MS is the settled Q). small plays the particle collapse. */
|
|
262
|
+
export function orbitCellsAt(size, t, opts = {}) {
|
|
263
|
+
if (t >= INTRO_MS) return qCells(size, opts);
|
|
264
|
+
const kind = size === 'small' ? 'particle' : 'orbit';
|
|
265
|
+
return fieldToCells(swarmField(size, t, { kind, dur: kind === 'particle' ? INTRO_MS - 60 : ORBIT_MS, seed: opts.seed ?? 11 }), opts);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* One frame of Orbit & Lock at progress 0..1 of INTRO_MS (lab timing: 820 ms orbit, all locks done by
|
|
270
|
+
* 672 ms, the last flashes fade by ~840 ms). progress >= 1 is exactly the settled Q.
|
|
271
|
+
*/
|
|
272
|
+
export function orbitFrame(size, progress, { color = true } = {}) {
|
|
273
|
+
if (progress >= 1) return qLines(size, { color });
|
|
274
|
+
return cellsToAnsi(orbitCellsAt(size, progress * INTRO_MS, { color }));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Particle collapse at t ms of `dur` (the lab's compact variant, any size). */
|
|
278
|
+
export function particleCellsAt(size, t, opts = {}) {
|
|
279
|
+
const dur = opts.dur ?? 1100;
|
|
280
|
+
if (t >= dur + FLASH_MS + 300) return qCells(size, opts);
|
|
281
|
+
return fieldToCells(swarmField(size, t, { kind: 'particle', dur, seed: opts.seed ?? 12 }), opts);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// ---- 2: Portal -------------------------------------------------------------------------------------------
|
|
285
|
+
export const PORTAL_MS = 1000;
|
|
286
|
+
const portalCache = new Map();
|
|
287
|
+
function portalModel(size) {
|
|
288
|
+
if (portalCache.has(size)) return portalCache.get(size);
|
|
289
|
+
const m = qMask(size), H = m.H;
|
|
290
|
+
const ccx = m.ox + BOWL.cx * H, ccy = BOWL.cy * H, ringR = 0.3 * H, revR = 0.42 * H;
|
|
291
|
+
const phiAt = (u) => (u < 0.3 ? (Math.PI / 2) * smooth(u / 0.3) : u < 0.7 ? Math.PI / 2 + (Math.PI / 2) * smooth((u - 0.3) / 0.4) : Math.PI);
|
|
292
|
+
const pts = m.dots.map((d) => {
|
|
293
|
+
// The tail sweeps in last, base to tip (lab: rt 0.74 .. 0.94 along the tail).
|
|
294
|
+
if (d.part === 'tail') return { ...d, rt: 0.74 + 0.2 * d.t };
|
|
295
|
+
let rt = 0.74 + 0.1 * (d.y / H);
|
|
296
|
+
for (let u = 0.3; u <= 0.7; u += 0.004) {
|
|
297
|
+
const w = Math.max(0.02, Math.abs(Math.cos(phiAt(u))));
|
|
298
|
+
if (((d.x - ccx) / (revR * w)) ** 2 + ((d.y - ccy) / revR) ** 2 <= 1) { rt = u; break; }
|
|
299
|
+
}
|
|
300
|
+
return { ...d, rt };
|
|
301
|
+
});
|
|
302
|
+
const r = { m, ccx, ccy, ringR, phiAt, pts };
|
|
303
|
+
portalCache.set(size, r);
|
|
304
|
+
return r;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** Portal at t ms: a ring spins in 3D (circle, edge-on line, open), the Q fills from the opening, tail last. */
|
|
308
|
+
export function portalCellsAt(size, t, opts = {}) {
|
|
309
|
+
const { m, ccx, ccy, ringR, phiAt, pts } = portalModel(size), f = makeField(m.W, m.H);
|
|
310
|
+
const dur = PORTAL_MS, u = t / dur, settled = t > dur + 500, phi = phiAt(Math.min(u, 1));
|
|
311
|
+
if (settled) return qCells(size, opts);
|
|
312
|
+
const alpha = Math.min(1, u / 0.1) * (1 - clamp((u - 0.68) / 0.12));
|
|
313
|
+
if (alpha > 0) {
|
|
314
|
+
const w = Math.cos(phi), n = Math.round(ringR * 24);
|
|
315
|
+
for (let i = 0; i < n; i++) {
|
|
316
|
+
const th = (i / n) * TAU, z = Math.cos(th) * Math.sin(phi);
|
|
317
|
+
f.set(ccx + ringR * Math.cos(th) * w, ccy + ringR * Math.sin(th), alpha * (0.62 + 0.38 * z));
|
|
318
|
+
}
|
|
319
|
+
if (Math.abs(w) < 0.12) for (let yy = -ringR; yy <= ringR; yy++) f.set(ccx, ccy + yy, alpha * 1.15);
|
|
320
|
+
}
|
|
321
|
+
for (const p of pts) if (u >= p.rt) f.set(p.x, p.y, 1 + Math.max(0, 1 - ((u - p.rt) * dur) / 150) * 0.7);
|
|
322
|
+
return fieldToCells(f, opts);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// ---- resting --------------------------------------------------------------------------------------------
|
|
326
|
+
export const BREATH_MS = 2400;
|
|
327
|
+
/** The settled Q breathing gently (idle on the web face): brightness 0.82 .. 1 over BREATH_MS. */
|
|
328
|
+
export function restCellsAt(size, t, opts = {}) {
|
|
329
|
+
const m = qMask(size), f = makeField(m.W, m.H);
|
|
330
|
+
const g = 0.82 + 0.18 * (0.5 + 0.5 * Math.sin((t / BREATH_MS) * TAU - Math.PI / 2));
|
|
331
|
+
for (const d of m.dots) f.v[d.y * m.W + d.x] = g;
|
|
332
|
+
return fieldToCells(f, opts);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ---- intro plan ------------------------------------------------------------------------------------------
|
|
336
|
+
/**
|
|
337
|
+
* The intro as one timeline: Orbit & Lock, then the settled Q. Returns { ms, at(t) -> cells }. Callers drive t
|
|
338
|
+
* from their own clock.
|
|
339
|
+
*/
|
|
340
|
+
export function introPlan(size, opts = {}) {
|
|
341
|
+
return {
|
|
342
|
+
ms: INTRO_MS,
|
|
343
|
+
at(t) {
|
|
344
|
+
if (t < INTRO_MS) return orbitCellsAt(size, t, opts);
|
|
345
|
+
return qCells(size, opts);
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
}
|