quoxcli 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +2 -0
- package/bin/quox.js +99 -126
- package/lib/api/endpoints/actions.js +15 -0
- package/lib/api/endpoints/admin.js +46 -0
- package/lib/api/endpoints/agent-schedules.js +26 -0
- package/lib/api/endpoints/agents.js +7 -0
- package/lib/api/endpoints/assistants.js +12 -0
- package/lib/api/endpoints/away.js +15 -0
- package/lib/api/endpoints/blog.js +16 -0
- package/lib/api/endpoints/chat.js +14 -0
- package/lib/api/endpoints/contactsq.js +6 -0
- package/lib/api/endpoints/conversations.js +14 -0
- package/lib/api/endpoints/devServerRegistry.js +25 -0
- package/lib/api/endpoints/engagement.js +26 -0
- package/lib/api/endpoints/evidence.js +20 -0
- package/lib/api/endpoints/executions.js +13 -0
- package/lib/api/endpoints/fetchAllowlist.js +27 -0
- package/lib/api/endpoints/files.js +14 -0
- package/lib/api/endpoints/hat.js +44 -0
- package/lib/api/endpoints/inbox.js +20 -0
- package/lib/api/endpoints/index.js +26 -0
- package/lib/api/endpoints/loops.js +26 -0
- package/lib/api/endpoints/memory.js +19 -0
- package/lib/api/endpoints/mind.js +13 -0
- package/lib/api/endpoints/mon.js +179 -0
- package/lib/api/endpoints/objectives.js +12 -0
- package/lib/api/endpoints/plugins.js +18 -0
- package/lib/api/endpoints/presence.js +33 -0
- package/lib/api/endpoints/quoxplan.js +7 -0
- package/lib/api/endpoints/quoxseo.js +12 -0
- package/lib/api/endpoints/router.js +17 -0
- package/lib/api/endpoints/safety.js +7 -0
- package/lib/api/endpoints/server.js +21 -0
- package/lib/api/endpoints/setup.js +6 -0
- package/lib/api/endpoints/skills.js +20 -0
- package/lib/api/endpoints/stepup.js +20 -0
- package/lib/api/endpoints/teams.js +2 -2
- package/lib/api/endpoints/triggers.js +26 -0
- package/lib/api/endpoints/v1.js +120 -0
- package/lib/api/endpoints/ward.js +7 -0
- package/lib/api/endpoints/workflows.js +7 -0
- package/lib/api/endpoints/x.js +8 -0
- package/lib/commands/actions.js +131 -0
- package/lib/commands/admin.js +16 -0
- package/lib/commands/agent.js +170 -27
- package/lib/commands/agentAttach.js +140 -13
- package/lib/commands/approvals.js +78 -1
- package/lib/commands/aside.js +24 -0
- package/lib/commands/ask.js +146 -0
- package/lib/commands/assistant.js +59 -4
- package/lib/commands/auth.js +8 -2
- package/lib/commands/backup.js +8 -4
- package/lib/commands/blog.js +110 -0
- package/lib/commands/brain.js +105 -14
- package/lib/commands/build.js +19 -5
- package/lib/commands/chat.js +180 -26
- package/lib/commands/chatCompanion.js +27 -0
- package/lib/commands/chatState.js +45 -0
- package/lib/commands/claude.js +35 -38
- package/lib/commands/contacts.js +134 -4
- package/lib/commands/contactsSendAt.js +21 -0
- package/lib/commands/conversation.js +35 -4
- package/lib/commands/dashboard.js +43 -0
- package/lib/commands/department.js +28 -7
- package/lib/commands/devResident.js +15 -3
- package/lib/commands/devSupervisor.js +13 -1
- package/lib/commands/discord.js +75 -39
- package/lib/commands/done.js +98 -28
- package/lib/commands/engagement.js +107 -6
- package/lib/commands/evidence.js +154 -0
- package/lib/commands/ext.js +23 -0
- package/lib/commands/fetchAllowlist.js +71 -0
- package/lib/commands/file.js +38 -1
- package/lib/commands/fleet.js +336 -4
- package/lib/commands/governance.js +12 -3
- package/lib/commands/gripe.js +44 -13
- package/lib/commands/hat.js +254 -9
- package/lib/commands/helpers.js +18 -1
- package/lib/commands/hyperion.js +58 -0
- package/lib/commands/image.js +68 -0
- package/lib/commands/inbox.js +74 -23
- package/lib/commands/kuma.js +1050 -0
- package/lib/commands/kumaSla.js +174 -0
- package/lib/commands/licence.js +52 -155
- package/lib/commands/loop.js +291 -0
- package/lib/commands/lucid.js +10 -4
- package/lib/commands/memory.js +85 -8
- package/lib/commands/mind.js +71 -0
- package/lib/commands/mon.js +69 -2
- package/lib/commands/monitoring.js +1 -1
- package/lib/commands/motion.js +2 -2
- package/lib/commands/nucleus.js +48 -17
- package/lib/commands/objective.js +59 -1
- package/lib/commands/offload.js +89 -0
- package/lib/commands/onboard.js +2 -1
- package/lib/commands/org.js +30 -3
- package/lib/commands/peek.js +28 -0
- package/lib/commands/plan.js +38 -0
- package/lib/commands/plugin.js +110 -0
- package/lib/commands/presence.js +89 -0
- package/lib/commands/provider.js +217 -0
- package/lib/commands/qlarity.js +19 -3
- package/lib/commands/quoxchat.js +13 -4
- package/lib/commands/quoxseo.js +69 -0
- package/lib/commands/reach.js +2 -1
- package/lib/commands/research.js +79 -0
- package/lib/commands/router.js +77 -0
- package/lib/commands/rows.js +367 -0
- package/lib/commands/run.js +82 -10
- package/lib/commands/scope.js +2 -2
- package/lib/commands/server.js +405 -0
- package/lib/commands/setup.js +33 -7
- package/lib/commands/shortcut.js +41 -0
- package/lib/commands/skills.js +68 -9
- package/lib/commands/slot.js +260 -7
- package/lib/commands/status.js +1 -1
- package/lib/commands/team.js +3 -1
- package/lib/commands/tips.js +23 -0
- package/lib/commands/tool.js +133 -45
- package/lib/commands/trace.js +12 -7
- package/lib/commands/trigger.js +95 -0
- package/lib/commands/update.js +46 -0
- package/lib/commands/vault.js +31 -8
- package/lib/commands/vm.js +237 -0
- package/lib/commands/voice.js +34 -3
- package/lib/commands/volt.js +45 -3
- package/lib/commands/walkthrough.js +32 -0
- package/lib/commands/watch.js +73 -21
- package/lib/commands/welcome.js +14 -0
- package/lib/commands/workflow.js +189 -32
- package/lib/commands/x.js +13 -4
- package/lib/commands/youtube.js +172 -0
- package/lib/core/actingAs.js +2 -2
- package/lib/core/actionItems.js +115 -0
- package/lib/core/activeSummary.js +186 -0
- package/lib/core/agentAlias.js +2 -0
- package/lib/core/agentFamilies.js +7 -0
- package/lib/core/aside.js +54 -0
- package/lib/core/askDecision.js +60 -0
- package/lib/core/auth.js +164 -13
- package/lib/core/callerSource.js +1 -1
- package/lib/core/cliBuild.js +62 -0
- package/lib/core/client.js +152 -35
- package/lib/core/commandRegistrars.js +130 -0
- package/lib/core/config.js +143 -25
- package/lib/core/customHats.js +168 -0
- package/lib/core/doneEngineFetch.js +8 -0
- package/lib/core/errors.js +329 -20
- package/lib/core/findingReconcile.js +90 -0
- package/lib/core/global-flags.js +105 -5
- package/lib/core/governedSession.js +1 -3
- package/lib/core/hyperion.js +102 -0
- package/lib/core/inboxResolution.js +65 -0
- package/lib/core/lazyCommands.js +4 -1
- package/lib/core/liveSessionsReport.js +1 -1
- package/lib/core/loopGlyph.js +97 -0
- package/lib/core/offload.js +533 -0
- package/lib/core/org-override.js +1 -1
- package/lib/core/orgResolve.js +70 -0
- package/lib/core/output.js +11 -11
- package/lib/core/peek.js +126 -0
- package/lib/core/profileUsers.js +51 -0
- package/lib/core/promptCancel.js +18 -0
- package/lib/core/repoPath.js +11 -0
- package/lib/core/residentSeed.js +3 -1
- 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 +12 -8
- package/lib/core/sessionsOverview.js +64 -0
- package/lib/core/shortcut.js +83 -0
- package/lib/core/slotKeeper.js +248 -3
- package/lib/core/slotWake.js +120 -0
- package/lib/core/supervisorEngine.js +71 -2
- package/lib/core/version.js +1 -1
- package/lib/core/vm.js +366 -0
- package/lib/core/vmTui.js +86 -0
- package/lib/core/walkthrough.js +35 -0
- package/lib/dragon/companionView.js +34 -0
- package/lib/dragon/frames.js +118 -0
- package/lib/dragon/jobs.js +123 -0
- package/lib/dragon/renderWorker.js +15 -0
- package/lib/dragon/select.js +72 -0
- package/lib/evidence/bundleExport.js +47 -0
- package/lib/evidence/bundleVerify.js +77 -0
- package/lib/hyperion/deck.js +29 -0
- package/lib/lucid/LucidCard.jsx +68 -0
- package/lib/lucid/LucidIntro.jsx +45 -58
- package/lib/lucid/cards.js +86 -0
- package/lib/lucid/markdown.js +81 -0
- package/lib/lucid/motion.js +56 -0
- package/lib/quoxon/EXTENSIONS.md +23 -0
- package/lib/quoxon/activity.js +14 -2
- package/lib/quoxon/aocl.js +117 -0
- package/lib/quoxon/api.js +690 -25
- package/lib/quoxon/app.js +3586 -250
- package/lib/quoxon/approvalFacts.js +96 -0
- package/lib/quoxon/approvalSentence.js +44 -0
- package/lib/quoxon/approvalsView.js +384 -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 +13 -6
- package/lib/quoxon/cells.js +53 -0
- package/lib/quoxon/commandShort.js +124 -0
- package/lib/quoxon/commands.js +429 -39
- package/lib/quoxon/connect.js +210 -23
- package/lib/quoxon/connectCard.js +19 -2
- package/lib/quoxon/consent.js +86 -0
- package/lib/quoxon/copy.js +4 -3
- package/lib/quoxon/countdownLine.js +20 -0
- package/lib/quoxon/deck.js +30 -0
- package/lib/quoxon/demo.autoplay.js +29 -0
- package/lib/quoxon/demo.fixtures.js +1 -1
- package/lib/quoxon/demo.js +46 -3
- package/lib/quoxon/devObserver.js +20 -0
- package/lib/quoxon/dividerAocl.js +192 -0
- package/lib/quoxon/dividerRule.js +57 -0
- package/lib/quoxon/dragonCompanion.js +255 -0
- package/lib/quoxon/dragonModes.js +151 -0
- package/lib/quoxon/dragonMoments.js +82 -0
- package/lib/quoxon/dragonReads.js +68 -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 +2 -2
- package/lib/quoxon/events.js +266 -26
- package/lib/quoxon/extensions.js +276 -0
- package/lib/quoxon/feedback.js +50 -0
- package/lib/quoxon/gallery.js +21 -7
- 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/inboxView.js +79 -0
- package/lib/quoxon/indicator.js +6 -2
- package/lib/quoxon/installCli.js +79 -0
- package/lib/quoxon/intent.js +12 -1
- package/lib/quoxon/keys.js +51 -8
- package/lib/quoxon/launcher.js +103 -0
- package/lib/quoxon/loopCard.js +456 -0
- package/lib/quoxon/loopCards.js +180 -0
- package/lib/quoxon/loopStream.js +87 -0
- package/lib/quoxon/main.js +101 -160
- package/lib/quoxon/markdown.js +45 -21
- 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 +132 -26
- package/lib/quoxon/modelPrefs.js +345 -0
- package/lib/quoxon/motion/clock.js +3 -2
- package/lib/quoxon/motion/level.js +91 -0
- package/lib/quoxon/mouse.js +222 -0
- package/lib/quoxon/noai.js +57 -0
- package/lib/quoxon/objectiveOffer.js +82 -0
- package/lib/quoxon/objects/away.js +72 -0
- package/lib/quoxon/objects/fetch.js +17 -5
- package/lib/quoxon/objects/fleet.js +149 -0
- package/lib/quoxon/objects/health.js +186 -0
- package/lib/quoxon/objects/index.js +46 -7
- package/lib/quoxon/objects/mirror.js +137 -0
- package/lib/quoxon/objects/model.js +33 -0
- package/lib/quoxon/objects/peek.js +17 -0
- package/lib/quoxon/objects/proof.js +12 -4
- 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/view.js +11 -0
- package/lib/quoxon/onboarding/copy.js +32 -4
- package/lib/quoxon/onboarding/credential.js +17 -4
- package/lib/quoxon/onboarding/dockerOffer.js +45 -0
- package/lib/quoxon/onboarding/failureCause.js +33 -0
- package/lib/quoxon/onboarding/finish.js +15 -0
- package/lib/quoxon/onboarding/index.js +34 -7
- package/lib/quoxon/onboarding/installRunner.js +64 -5
- package/lib/quoxon/onboarding/preflight.js +17 -3
- package/lib/quoxon/onboarding/probe.js +65 -0
- package/lib/quoxon/onboarding/shortcutOffer.js +28 -0
- package/lib/quoxon/onboarding/view.js +76 -19
- package/lib/quoxon/orgLabel.js +10 -0
- package/lib/quoxon/orgSwitch.js +59 -0
- package/lib/quoxon/ownBroadcast.js +22 -0
- package/lib/quoxon/palette.js +43 -0
- package/lib/quoxon/planSteps.js +51 -0
- package/lib/quoxon/print.js +12 -5
- 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 +20 -51
- package/lib/quoxon/qdragon.js +410 -0
- package/lib/quoxon/qdragonFly.js +62 -0
- package/lib/quoxon/qdragonScenes.js +282 -0
- package/lib/quoxon/qeyes.js +213 -0
- package/lib/quoxon/qmotion.js +75 -37
- package/lib/quoxon/render.js +740 -124
- package/lib/quoxon/resend.js +72 -0
- package/lib/quoxon/roster.js +117 -17
- package/lib/quoxon/route.js +6 -5
- package/lib/quoxon/rows.js +954 -0
- package/lib/quoxon/rowsStore.js +80 -0
- package/lib/quoxon/screenContext.js +150 -0
- package/lib/quoxon/screenFrames.js +254 -0
- package/lib/quoxon/serverChip.js +42 -0
- package/lib/quoxon/session.js +182 -2
- package/lib/quoxon/sessionDead.js +17 -0
- package/lib/quoxon/signin.js +125 -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 +94 -0
- package/lib/quoxon/slash/cliLeaves.json +1023 -0
- package/lib/quoxon/slash/compact.js +1 -1
- 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/evidenceCmd.js +34 -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 +13 -8
- package/lib/quoxon/slash/listView.js +3 -1
- package/lib/quoxon/slash/modelCmd.js +261 -0
- package/lib/quoxon/slash/palette.js +22 -8
- package/lib/quoxon/slash/paletteController.js +117 -7
- package/lib/quoxon/slash/panels.js +21 -6
- package/lib/quoxon/slash/picker.js +20 -2
- package/lib/quoxon/slash/qpeCmd.js +35 -0
- package/lib/quoxon/slash/restart.js +95 -13
- package/lib/quoxon/slash/resume.js +18 -1
- package/lib/quoxon/slash/rowCmd.js +157 -0
- package/lib/quoxon/slash/rowWalk.js +175 -0
- package/lib/quoxon/slash/settings.js +16 -6
- 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/todoCmd.js +122 -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/mapping.js +2 -1
- package/lib/quoxon/stray.js +22 -0
- package/lib/quoxon/suggestCommand.js +90 -0
- package/lib/quoxon/term.js +46 -11
- package/lib/quoxon/textBuffer.js +176 -2
- package/lib/quoxon/theme.js +58 -25
- package/lib/quoxon/tips.js +433 -0
- package/lib/quoxon/toolCards.js +30 -0
- package/lib/quoxon/toolError.js +41 -0
- package/lib/quoxon/transcript.js +42 -4
- package/lib/quoxon/web/qface.js +18 -10
- package/lib/quoxon/welcome.js +1 -1
- package/lib/quoxon/whatsnew.js +136 -0
- package/lib/quoxon/whatsnew.jsonl +134 -0
- package/lib/quoxon/windowOrg.js +123 -0
- package/lib/server/devServers.js +137 -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/views/HyperionDeck.jsx +79 -0
- package/lib/tui/views/LucidDeck.jsx +209 -217
- package/package.json +5 -1
- package/vendor/dragonlab/SOURCE +4 -0
- package/vendor/dragonlab/design/cipher/v1/cipher-master.svg +46 -0
- package/vendor/dragonlab/design/cipher/v2/character.mjs +49 -0
- package/vendor/dragonlab/design/cipher/v2/review.mjs +33 -0
- package/vendor/dragonlab/design/cipher/v2/watch.mjs +56 -0
- package/vendor/dragonlab/design/drago/v1/character.mjs +19 -0
- package/vendor/dragonlab/design/drago/v1/drago-master.svg +56 -0
- package/vendor/dragonlab/design/drago/v2/character.mjs +87 -0
- package/vendor/dragonlab/design/drago/v4/character.mjs +67 -0
- package/vendor/dragonlab/design/drago/v4/profile.mjs +35 -0
- package/vendor/dragonlab/design/drago/v4/review.mjs +33 -0
- package/vendor/dragonlab/design/drago/v4/watch.mjs +56 -0
- package/vendor/dragonlab/design/hyperion/v1/hyperion-master.svg +56 -0
- package/vendor/dragonlab/design/hyperion/v2/character.mjs +79 -0
- package/vendor/dragonlab/design/hyperion/v2/review.mjs +33 -0
- package/vendor/dragonlab/design/hyperion/v2/watch.mjs +56 -0
- package/vendor/dragonlab/design/lucid/recovery/arrival.mjs +22 -0
- package/vendor/dragonlab/design/lucid/recovery/character.mjs +106 -0
- package/vendor/dragonlab/design/lucid/recovery/layout.mjs +50 -0
- package/vendor/dragonlab/design/lucid/recovery/lucid-master.svg +78 -0
- package/vendor/dragonlab/design/lucid/recovery/motion.mjs +42 -0
- package/vendor/dragonlab/design/lucid/recovery/render.mjs +121 -0
- package/vendor/dragonlab/design/lucid/recovery/review.mjs +68 -0
- package/vendor/dragonlab/design/lucid/recovery/verify.mjs +84 -0
- package/vendor/dragonlab/design/lucid/recovery/watch.mjs +56 -0
- package/vendor/dragonlab/design/seer/v1/seer-master.svg +53 -0
- package/vendor/dragonlab/design/seer/v2/character.mjs +88 -0
- package/vendor/dragonlab/design/seer/v3/character.mjs +33 -0
- package/vendor/dragonlab/design/seer/v4/character.mjs +66 -0
- package/vendor/dragonlab/design/seer/v4/review.mjs +33 -0
- package/vendor/dragonlab/design/seer/v4/watch.mjs +56 -0
- package/vendor/dragonlab/design/stage3/companion-review.mjs +28 -0
- package/vendor/dragonlab/design/stage3/sentinel-art.js +39 -0
- package/vendor/dragonlab/design/stage3/sentinel-braille.js +216 -0
- package/vendor/dragonlab/design/stage3/sentinel-character.js +257 -0
- package/vendor/dragonlab/design/stage3/sentinel-icon.js +103 -0
- package/vendor/dragonlab/design/stage3/sentinel-warden-eyes.js +95 -0
- package/vendor/dragonlab/design/stage3/svg-coverage.js +148 -0
- package/vendor/dragonlab/factory/svg-rig.mjs +63 -0
- package/vendor/dragonlab/integration/companions-v1/characters.mjs +88 -0
- package/vendor/dragonlab/integration/companions-v1/cipher.mjs +2 -0
- package/vendor/dragonlab/integration/companions-v1/companion.mjs +63 -0
- package/vendor/dragonlab/integration/companions-v1/drago.mjs +2 -0
- package/vendor/dragonlab/integration/companions-v1/hyperion.mjs +2 -0
- package/vendor/dragonlab/integration/companions-v1/lucid.mjs +2 -0
- package/vendor/dragonlab/integration/companions-v1/seer.mjs +2 -0
- package/vendor/dragonlab/integration/companions-v1/sentinel.mjs +2 -0
- package/vendor/dragonlab/integration/companions-v1/view.mjs +28 -0
- package/vendor/dragonlab/integration/hyperion-v3/activity.mjs +76 -0
- package/vendor/dragonlab/lib/power-effects.js +294 -0
- package/vendor/dragonlab/lib/power-registry.js +74 -0
- package/vendor/dragonlab/vendor/quox-dragon/qart.js +348 -0
- package/vendor/dragonlab/vendor/quox-dragon/qeyes.js +213 -0
- package/lib/core/websiteSession.js +0 -148
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QUOXON-FW3: a message typed while the server is restarting is kept, not dropped (pure helpers).
|
|
3
|
+
* A send is only retried when the connection failed BEFORE any event arrived (so no turn started and
|
|
4
|
+
* nothing can run twice); the caller enforces that.
|
|
5
|
+
*/
|
|
6
|
+
export const SERVER_RESTARTING = "Quox server is restarting. I'll send this when it is back. Esc cancels.";
|
|
7
|
+
export const MAX_WAIT_MS = 180000;
|
|
8
|
+
|
|
9
|
+
/** True for "could not reach the server at all" (refused / fetch failed), never for an HTTP answer. */
|
|
10
|
+
export function isServerDown(e) {
|
|
11
|
+
if (!e || e.status) return false;
|
|
12
|
+
const code = e.cause?.code || e.code || '';
|
|
13
|
+
const msg = String(e.message || '');
|
|
14
|
+
return /ECONNREFUSED|ECONNRESET|ENOTFOUND|EAI_AGAIN|UND_ERR_SOCKET/.test(String(code)) || /Could not connect to|fetch failed|ECONNREFUSED/i.test(msg);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** gh #1157: resume during a collector restart. Connection-class failures (refused, fetch failed, hang up, 502/503/504) are worth retrying; 401/404 are answers. */
|
|
18
|
+
export function isResumeRetryable(e) {
|
|
19
|
+
if (!e) return false;
|
|
20
|
+
if (e.status) return [502, 503, 504].includes(Number(e.status));
|
|
21
|
+
return isServerDown(e) || /socket hang up|ECONNRESET|other side closed|terminated/i.test(String(e.message || ''));
|
|
22
|
+
}
|
|
23
|
+
/** 2, 4, 8, 15, 30 s, then 30 s steps: about 2 minutes in all before giving up. */
|
|
24
|
+
export const RESUME_RETRY_DELAYS = [2000, 4000, 8000, 15000, 30000, 30000, 30000];
|
|
25
|
+
export const RESUME_RECONNECTING = 'Quox server restarting, reconnecting to your conversation…';
|
|
26
|
+
|
|
27
|
+
/** 1s, 2s, 4s, 8s, then 10s (capped). */
|
|
28
|
+
export const backoffMs = (i) => Math.min(10000, 1000 * 2 ** i);
|
|
29
|
+
|
|
30
|
+
const sleepFor = (ms, signal) => new Promise((r) => {
|
|
31
|
+
if (signal?.aborted) return r();
|
|
32
|
+
const t = setTimeout(done, ms);
|
|
33
|
+
function done() { clearTimeout(t); signal?.removeEventListener?.('abort', done); r(); }
|
|
34
|
+
signal?.addEventListener?.('abort', done, { once: true });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Poll health with backoff until it answers 2xx. -> 'up' | 'cancelled' | 'timeout'.
|
|
39
|
+
* delays: optional array (tests); else backoffMs. Total waiting is bounded by maxMs of scheduled sleep.
|
|
40
|
+
*/
|
|
41
|
+
export async function waitForServer({ health, signal, delays = null, maxMs = MAX_WAIT_MS }) {
|
|
42
|
+
let waited = 0;
|
|
43
|
+
for (let i = 0; ; i++) {
|
|
44
|
+
if (signal?.aborted) return 'cancelled';
|
|
45
|
+
const d = delays ? delays[Math.min(i, delays.length - 1)] : backoffMs(i);
|
|
46
|
+
if (waited >= maxMs || (delays && i >= delays.length * 4)) return 'timeout';
|
|
47
|
+
await sleepFor(d, signal);
|
|
48
|
+
waited += d;
|
|
49
|
+
if (signal?.aborted) return 'cancelled';
|
|
50
|
+
let r = null;
|
|
51
|
+
try { r = await health(3000); } catch { r = null; }
|
|
52
|
+
if (r?.ok) return 'up';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* QUOXON-FW4: a stream that died mid-turn ("terminated" is undici's wording) gets a cause and a way
|
|
58
|
+
* forward instead of a bare word. Returns null when the error is not a transport/timeout failure.
|
|
59
|
+
*/
|
|
60
|
+
export function explainTermination(e) {
|
|
61
|
+
if (!e || e.status) return null;
|
|
62
|
+
const msg = String(e.message || '');
|
|
63
|
+
const code = String(e.cause?.code || e.code || '');
|
|
64
|
+
if (e.name === 'TimeoutError' || /timed? ?out|ETIMEDOUT|UND_ERR_(HEADERS|BODY)_TIMEOUT/i.test(`${msg} ${code}`)) return `The turn timed out before the server finished.`;
|
|
65
|
+
if (/^terminated$/i.test(msg.trim()) || /ECONNRESET|UND_ERR_SOCKET|other side closed|premature close|aborted/i.test(`${msg} ${code}`)) {
|
|
66
|
+
return `The connection to the server was cut mid-turn (likely a server restart, proxy timeout or provider error).`;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The second line after a cut turn: the message is kept, and what to do next. */
|
|
72
|
+
export const RETRY_HINT = 'Your message is kept: press Up to recall it, then Enter to resend. Anything it started may or may not have finished; check before repeating it.';
|
package/lib/quoxon/roster.js
CHANGED
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
* nothing (never a placeholder row).
|
|
6
6
|
*/
|
|
7
7
|
import { clip } from './theme.js';
|
|
8
|
+
import { humanReason, wrapText } from './loopCard.js';
|
|
8
9
|
|
|
9
10
|
export const GLYPH = { running: '◐', waiting: '⏸', done: '✔', failed: '✖' };
|
|
11
|
+
/** A row that ended without finishing says HOW: failed is the only error; the rest are neutral (no error colour). */
|
|
12
|
+
export const OUTCOME_GLYPH = { failed: '✖', halted: '⚠', cancelled: '○', expired: '○', rejected: '⊘' };
|
|
10
13
|
export const FRESH_MS = 10 * 60 * 1000; // finished rows linger this long
|
|
11
14
|
export const USER_DONE_MS = 20 * 1000; // a user-started completion vanishes quickly: rows come and go
|
|
12
15
|
export const PENDING_FRESH_MS = 24 * 3600 * 1000; // an older "pending" is stale, not waiting
|
|
@@ -36,7 +39,22 @@ export function elapsed(ms) {
|
|
|
36
39
|
|
|
37
40
|
const ACTIVE_RE = /^(running|planning|decompos|executing|in_progress|active)/;
|
|
38
41
|
const WAITING_RE = /^(paused|awaiting|blocked|plan_review|pending_approval|waiting)/;
|
|
39
|
-
const FAILED = new Set(['failed', 'error', 'halted', 'cancelled', 'canceled', 'timed_out', 'timeout']);
|
|
42
|
+
const FAILED = new Set(['failed', 'error', 'halted', 'cancelled', 'canceled', 'timed_out', 'timeout', 'expired', 'rejected']);
|
|
43
|
+
/** The word for how an ended row ended (state stays 'failed' for the ended-badly group; this says which). */
|
|
44
|
+
export function outcomeOf(status) {
|
|
45
|
+
const st = String(status || '').toLowerCase();
|
|
46
|
+
if (st === 'halted') return 'halted';
|
|
47
|
+
if (st === 'cancelled' || st === 'canceled') return 'cancelled';
|
|
48
|
+
if (st === 'expired') return 'expired';
|
|
49
|
+
if (st === 'rejected') return 'rejected';
|
|
50
|
+
return 'failed';
|
|
51
|
+
}
|
|
52
|
+
/** Word, glyph and whether it is an error, for a row. Non-failed states return their own state. */
|
|
53
|
+
export function endWord(r) { return r.state === 'failed' ? (r.outcome || outcomeOf(r.status)) : r.state; }
|
|
54
|
+
/** A human-halted loop keeps objective status 'failed'; the server says loop_state 'halted' (older servers: the halt text). */
|
|
55
|
+
const HALT_TEXT = /^Loop (?:halted on demand|stopped by human review)/i;
|
|
56
|
+
const isHaltedLoop = (o) => o.execution_mode === 'loop' && (o.loop_state === 'halted' || String(o.status || '').toLowerCase() === 'halted' || (String(o.status || '').toLowerCase() === 'failed' && HALT_TEXT.test(String(o.error_message || ''))));
|
|
57
|
+
export const glyphOf = (r) => (r.state === 'failed' ? OUTCOME_GLYPH[endWord(r)] : GLYPH[r.state]);
|
|
40
58
|
|
|
41
59
|
/** How long a finished row lingers before it leaves the roster (null while running/waiting). */
|
|
42
60
|
const expiryFor = (state, doneMs) => state === 'done' ? doneMs : state === 'failed' ? FRESH_MS : null;
|
|
@@ -59,6 +77,8 @@ function stateOf(status, { startedAt, createdAt, finishedAt, now, doneMs = FRESH
|
|
|
59
77
|
return null;
|
|
60
78
|
}
|
|
61
79
|
|
|
80
|
+
const latest = (...ts) => { const v = ts.filter((t) => t != null); return v.length ? Math.max(...v) : null; };
|
|
81
|
+
|
|
62
82
|
export function fromObjective(o, now = Date.now()) {
|
|
63
83
|
const startedAt = parseTime(o.started_at);
|
|
64
84
|
const createdAt = parseTime(o.created_at);
|
|
@@ -68,17 +88,22 @@ export function fromObjective(o, now = Date.now()) {
|
|
|
68
88
|
if (!state) return null;
|
|
69
89
|
const loop = o.execution_mode === 'loop';
|
|
70
90
|
let activity = '';
|
|
71
|
-
|
|
91
|
+
const haltedLoop = state === 'failed' && isHaltedLoop(o);
|
|
92
|
+
// a halted loop reads its clean sentence (the server's loop_reason, with the person's name), never the raw record text
|
|
93
|
+
const shownError = !haltedLoop ? o.error_message : (o.loop_reason || ((n) => (n ? `Stopped by ${n[1].trim()}` : 'Halted on demand'))(/^Loop halted on demand by \S+ \(([^)]{1,80})\)/i.exec(String(o.error_message || ''))));
|
|
94
|
+
if (state === 'failed' && shownError) activity = humanReason(shownError); // the sentence whole, minus the raw spawner prefix; the view decides how to show it
|
|
95
|
+
else if (loop && state === 'done') activity = o.iteration_count > 0 ? `${o.iteration_count} turn${o.iteration_count === 1 ? '' : 's'}` : ''; // the row prints "done <age>" itself; a stale "iter 0/5" beside it was the lie
|
|
72
96
|
else if (loop && o.max_iterations) activity = `iter ${o.iteration_count || 0}/${o.max_iterations}`;
|
|
73
97
|
else if (o.task_count) activity = `${o.tasks_completed || 0}/${o.task_count} tasks`;
|
|
74
98
|
else if (state === 'waiting') activity = 'waiting to start';
|
|
75
99
|
const from = startedAt ?? createdAt;
|
|
76
100
|
return {
|
|
77
101
|
key: `objective:${o.id}`, id: o.id, source: 'objectives', background: false, kind: loop ? 'loop' : 'objective', state,
|
|
78
|
-
name: o.title || o.id, activity, status: o.status,
|
|
102
|
+
name: o.title || o.id, activity, status: o.status, ...(haltedLoop ? { outcome: 'halted' } : {}),
|
|
79
103
|
startedAt: from, finishedAt, ageMs: from != null ? (state === 'done' || state === 'failed' ? (finishedAt ?? now) - from : now - from) : null,
|
|
80
104
|
expiryMs: expiryFor(state, USER_DONE_MS),
|
|
81
|
-
|
|
105
|
+
progressAt: latest(parseTime(o.updated_at), parseTime(o.last_progress_at), parseTime(o.last_heartbeat_at)),
|
|
106
|
+
detail: { description: o.description, error: shownError ? humanReason(shownError) : shownError, tokens: o.tokens_used, toolCalls: o.tool_calls_used }
|
|
82
107
|
};
|
|
83
108
|
}
|
|
84
109
|
|
|
@@ -95,7 +120,8 @@ const BACKGROUND_BY = /^(schedule|cron|interval|webhook|event|system)\b/i;
|
|
|
95
120
|
export function isBackgroundExecution(e, userId = null) {
|
|
96
121
|
const by = e?.triggeredBy == null ? '' : String(e.triggeredBy);
|
|
97
122
|
if (BACKGROUND_BY.test(by)) return true;
|
|
98
|
-
|
|
123
|
+
// quoxflow records a person-started run as user:<id> (RunActor); a bare id is an older row
|
|
124
|
+
if (userId && by && (by === String(userId) || by === `user:${userId}`)) return false;
|
|
99
125
|
return !USER_TRIGGERS.has(String(e?.triggerData?.trigger || '').toLowerCase());
|
|
100
126
|
}
|
|
101
127
|
|
|
@@ -114,6 +140,7 @@ export function fromExecution(e, now = Date.now(), { userId = null } = {}) {
|
|
|
114
140
|
name: e.workflowName || e.workflowId || e.id, activity, status: e.status,
|
|
115
141
|
startedAt, finishedAt, ageMs: startedAt != null ? (state === 'done' || state === 'failed' ? (finishedAt ?? now) - startedAt : now - startedAt) : null,
|
|
116
142
|
expiryMs: expiryFor(state, background ? FRESH_MS : USER_DONE_MS),
|
|
143
|
+
progressAt: latest(parseTime(e.updatedAt), parseTime(e.lastHeartbeatAt)),
|
|
117
144
|
detail: { workflowId: e.workflowId, correlationId: e.correlationId, trigger: e.triggerData?.trigger, error: e.error }
|
|
118
145
|
};
|
|
119
146
|
}
|
|
@@ -169,40 +196,113 @@ export function toneName(r, pos, now = Date.now()) {
|
|
|
169
196
|
|
|
170
197
|
/** Live age text: a clock for running/waiting rows, recency ("done 3s ago") for finished ones. */
|
|
171
198
|
export function ageText(r, now = Date.now()) {
|
|
172
|
-
if (r.state === 'done' || r.state === 'failed') return r.finishedAt != null ? `${r
|
|
199
|
+
if (r.state === 'done' || r.state === 'failed') return r.finishedAt != null ? `${endWord(r)} ${elapsed(now - r.finishedAt)} ago` : '';
|
|
173
200
|
return r.startedAt != null ? elapsed(now - r.startedAt) : '';
|
|
174
201
|
}
|
|
175
202
|
|
|
203
|
+
/* ---- pulse: is it moving? ---------------------------------------------------------------- */
|
|
204
|
+
|
|
205
|
+
export const PULSE_MOVING_MS = 2 * 60 * 1000; // progress this recently = moving
|
|
206
|
+
export const PULSE_STALL_MS = 15 * 60 * 1000; // running with no progress this long = stalled
|
|
207
|
+
export const SPIN = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
208
|
+
export const SPIN_MS = 120;
|
|
209
|
+
|
|
210
|
+
const sigOf = (r) => `${r.state}|${r.status}|${r.activity}`;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Remember what each row looked like at the last poll so "state changed / iteration advanced" is noticed.
|
|
214
|
+
* Sets r.progressAt (newest of the API's own timestamp and the change we saw; null = nothing seen yet) and
|
|
215
|
+
* r.watchSince (when we first saw the row). Mutates rows and memo (key -> { sig, watchSince, changedAt }).
|
|
216
|
+
*/
|
|
217
|
+
export function applyProgress(rows, memo, now = Date.now()) {
|
|
218
|
+
const keep = new Set();
|
|
219
|
+
for (const r of rows) {
|
|
220
|
+
keep.add(r.key);
|
|
221
|
+
const sig = sigOf(r);
|
|
222
|
+
let m = memo.get(r.key);
|
|
223
|
+
if (!m) { m = { sig, watchSince: now, changedAt: null }; memo.set(r.key, m); }
|
|
224
|
+
else if (m.sig !== sig) { m.sig = sig; m.changedAt = now; }
|
|
225
|
+
r.progressAt = latest(r.progressAt, m.changedAt);
|
|
226
|
+
r.watchSince = m.watchSince;
|
|
227
|
+
}
|
|
228
|
+
for (const k of [...memo.keys()]) if (!keep.has(k)) memo.delete(k);
|
|
229
|
+
return rows;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** -> { kind: 'moving' | 'idle' | 'stalled' | 'none', glyph, role }. motion=false gives static glyphs. */
|
|
233
|
+
export function pulseOf(r, now = Date.now(), { motion = false } = {}) {
|
|
234
|
+
if (r.kind === 'approval' || r.state === 'done' || r.state === 'failed') return { kind: 'none', glyph: ' ', role: 'dim' };
|
|
235
|
+
if (r.state !== 'running') return { kind: 'idle', glyph: '·', role: 'dim' };
|
|
236
|
+
const last = latest(r.progressAt, r.startedAt != null && now - r.startedAt < PULSE_MOVING_MS ? r.startedAt : null);
|
|
237
|
+
if (last != null && now - last < PULSE_MOVING_MS) return { kind: 'moving', glyph: motion ? SPIN[Math.floor(now / SPIN_MS) % SPIN.length] : '●', role: 'sky' };
|
|
238
|
+
const ref = last ?? r.watchSince;
|
|
239
|
+
if (ref != null && now - ref > PULSE_STALL_MS) return { kind: 'stalled', glyph: '!', role: 'warn' };
|
|
240
|
+
return { kind: 'idle', glyph: '·', role: 'dim' };
|
|
241
|
+
}
|
|
242
|
+
|
|
176
243
|
export function countsLine(rows) {
|
|
177
244
|
const n = (s) => rows.filter(r => r.state === s).length;
|
|
178
|
-
|
|
179
|
-
|
|
245
|
+
const o = (w) => rows.filter(r => r.state === 'failed' && endWord(r) === w).length;
|
|
246
|
+
return [['running', 'running', n('running'), GLYPH.running], ['waiting', 'waiting', n('waiting'), GLYPH.waiting],
|
|
247
|
+
['failed', 'failed', o('failed'), OUTCOME_GLYPH.failed], ['halted', 'halted', o('halted'), OUTCOME_GLYPH.halted], ['cancelled', 'cancelled', o('cancelled'), OUTCOME_GLYPH.cancelled],
|
|
248
|
+
['expired', 'expired', o('expired'), OUTCOME_GLYPH.expired], ['rejected', 'rejected', o('rejected'), OUTCOME_GLYPH.rejected], ['done', 'finished', n('done'), GLYPH.done]]
|
|
249
|
+
.filter(([, , k]) => k).map(([, w, k, g]) => `${g} ${k} ${w}`).join(' · ');
|
|
180
250
|
}
|
|
181
251
|
|
|
182
252
|
/**
|
|
183
253
|
* View model. mode: 'hidden' (off or nothing running) | 'summary' (narrow or short terminal) | 'full'.
|
|
184
254
|
* lines: [{ state, text, selected }] where text is already clipped to cols.
|
|
185
255
|
*/
|
|
186
|
-
|
|
256
|
+
/**
|
|
257
|
+
* Two or more waiting approvals are ONE row ("⏸ 4 approvals waiting · oldest 41m · newest: <title>… · /approvals"), not
|
|
258
|
+
* one row each plus a summary line (owner, live 05:29): the bottom area must never grow with the inbox. A single approval
|
|
259
|
+
* keeps its own row. Focus (the user is walking the roster) shows the real rows so selection stays truthful.
|
|
260
|
+
*/
|
|
261
|
+
export function collapseApprovals(rows, now = Date.now()) {
|
|
262
|
+
const aps = rows.filter(r => r.kind === 'approval' && r.state === 'waiting');
|
|
263
|
+
if (aps.length < 2) return rows;
|
|
264
|
+
const started = aps.map(r => r.startedAt).filter(x => x != null);
|
|
265
|
+
const newest = aps.reduce((a, b) => ((b.startedAt ?? -Infinity) > (a.startedAt ?? -Infinity) ? b : a));
|
|
266
|
+
const one = { key: 'approval:*', id: '*', source: 'approvals', kind: 'approval', state: 'waiting', background: false, collapsed: true, count: aps.length,
|
|
267
|
+
name: `${aps.length} approvals waiting`, activity: '/approvals', status: 'pending', startedAt: started.length ? Math.min(...started) : null, finishedAt: null,
|
|
268
|
+
oldestMs: started.length ? now - Math.min(...started) : null, newestTitle: String(newest.detail?.description || newest.name || ''), detail: {} };
|
|
269
|
+
let placed = false;
|
|
270
|
+
return rows.flatMap(r => (aps.includes(r) ? (placed ? [] : (placed = true, [one])) : [r]));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const KIND_ICON = { loop: '∞', objective: '◎' }; // QuoxGlyph registry keys qloop / objective
|
|
274
|
+
export const kindLabel = k => (KIND_ICON[k] ? `${KIND_ICON[k]} ${k}` : k);
|
|
275
|
+
|
|
276
|
+
export function rosterView({ rows, cols, termRows = 40, max = MAX_ROWS, on = true, sel = 0, focus = false, now = Date.now(), motion = false }) {
|
|
187
277
|
if (!on || !rows.length) return { mode: 'hidden', lines: [], more: 0 };
|
|
278
|
+
if (!focus) rows = collapseApprovals(rows, now);
|
|
188
279
|
if (cols < MIN_FULL_COLS || termRows < MIN_FULL_ROWS) {
|
|
189
280
|
return { mode: 'summary', lines: [], more: 0, summary: clip(' ' + countsLine(rows) + ' · /roster', cols - 1) };
|
|
190
281
|
}
|
|
191
282
|
const shown = rows.slice(0, max);
|
|
192
283
|
const ageW = Math.max(5, ...shown.map(r => [...ageText(r, now)].length));
|
|
193
|
-
let pos = 0;
|
|
194
|
-
const kindW = Math.min(
|
|
284
|
+
let pos = 0, reasonShown = false;
|
|
285
|
+
const kindW = Math.min(11, Math.max(...shown.map(r => [...kindLabel(r.kind)].length)));
|
|
195
286
|
const lines = shown.map((r, i) => {
|
|
196
287
|
const el = ageText(r, now).padStart(ageW);
|
|
197
288
|
const tone = toneName(r, pos, now); if (r.kind !== 'approval') pos++;
|
|
198
289
|
const actW = Math.min(18, Math.max(0, ...shown.map(x => [...(x.activity || '')].length)));
|
|
199
|
-
const
|
|
200
|
-
const
|
|
290
|
+
const longReason = r.state === 'failed' && [...(r.activity || '')].length > actW; // a reason is never cut: the column says "stopped", the sentence follows wrapped
|
|
291
|
+
const act = (longReason ? clip('stopped', actW) : clip(r.activity || '', actW)).padEnd(actW);
|
|
292
|
+
const fixed = 1 + 1 + 1 + kindW + 1 + 1 + actW + 1 + ageW + 2; // pulse column (space + glyph); marker glyph kind name act elapsed
|
|
201
293
|
const nameW = Math.max(8, cols - 2 - fixed - 1);
|
|
202
294
|
const name = clip(r.name, nameW).padEnd(nameW);
|
|
203
295
|
const marker = focus && i === sel ? '›' : ' ';
|
|
204
|
-
|
|
205
|
-
|
|
296
|
+
if (r.collapsed) { // one summary row: count, oldest age, newest title, where to go; clipped to the line
|
|
297
|
+
const head = `${r.count} approvals waiting · oldest ${elapsed(r.oldestMs)} · newest: `, tail = ' · /approvals';
|
|
298
|
+
const room = cols - 5 - [...head].length - [...tail].length;
|
|
299
|
+
const text = room >= 12 ? `${head}${clip(r.newestTitle, room)}${tail}` : clip(`${r.count} approvals waiting · oldest ${elapsed(r.oldestMs)}${tail}`, cols - 4); // too narrow for a title
|
|
300
|
+
return { key: r.key, kind: 'approval', state: r.state, tone: toneName(r, pos, now), selected: false, marker: ' ', glyph: GLYPH[r.state], rest: ' ' + text, pulse: '', pulseRole: 'dim', pulseKind: 'none', text: ` ${GLYPH[r.state]} ${text}` };
|
|
301
|
+
}
|
|
302
|
+
const rest = `${kindLabel(r.kind).padEnd(kindW)} ${name} ${act} ${el}`;
|
|
303
|
+
const p = pulseOf(r, now, { motion });
|
|
304
|
+
const extra = longReason && !reasonShown ? (reasonShown = true, wrapText(r.activity, Math.max(20, cols - 8))) : null; // spelled out for the newest stopped row only: the bar must not grow with every old failure
|
|
305
|
+
return { key: r.key, kind: r.kind, state: r.state, tone, extra, selected: focus && i === sel, marker, glyph: glyphOf(r), glyphRole: r.state === 'failed' && endWord(r) === 'halted' ? 'warn' : r.state === 'failed' && endWord(r) !== 'failed' ? 'dim' : null, rest: ' ' + rest, pulse: ' ' + p.glyph, pulseRole: p.role, pulseKind: p.kind, text: `${marker}${glyphOf(r)} ${rest} ${p.glyph}` };
|
|
206
306
|
});
|
|
207
307
|
return { mode: 'full', lines, more: Math.max(0, rows.length - shown.length) };
|
|
208
308
|
}
|
|
@@ -210,12 +310,12 @@ export function rosterView({ rows, cols, termRows = 40, max = MAX_ROWS, on = tru
|
|
|
210
310
|
export function peekLines(row, now = Date.now()) {
|
|
211
311
|
if (!row) return [];
|
|
212
312
|
const age = ageText(row, now);
|
|
213
|
-
const out = [`${row.kind} ${row.id}`, `status ${row.status} · ${row
|
|
313
|
+
const out = [`${row.kind} ${row.id}`, `status ${row.status} · ${endWord(row)}${age ? ` · ${age}` : ''}`, `name ${row.name}`];
|
|
214
314
|
if (row.activity) out.push(`activity ${row.activity}`);
|
|
215
315
|
const d = row.detail || {};
|
|
216
316
|
if (d.description) out.push(`goal ${d.description}`);
|
|
217
317
|
if (d.workflowId) out.push(`workflow ${d.workflowId}`);
|
|
218
318
|
if (d.trigger) out.push(`trigger ${d.trigger}`);
|
|
219
|
-
if (d.error && row.state === 'failed') out.push(`error ${typeof d.error === 'string' ? d.error : JSON.stringify(d.error)}`);
|
|
319
|
+
if (d.error && row.state === 'failed') out.push(`error ${typeof d.error === 'string' ? humanReason(d.error) : JSON.stringify(d.error)}`);
|
|
220
320
|
return out;
|
|
221
321
|
}
|
package/lib/quoxon/route.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
const VALUE_FLAGS = new Set(['-p', '--profile', '-n', '--name']);
|
|
7
7
|
const LEVELS = new Set(['off', 'on', 'full']); // `--verbose` alone means on; it only takes a value that is a level
|
|
8
|
-
const PRINT_VALUE_FLAGS = new Set(['--output', '--conversation', '--turn-id', '--timeout', '--provider', '--model']);
|
|
9
|
-
const BOOL_FLAGS = new Set(['--demo', '--demo-onboarding', '--no-clear', '--color', '--service-key']);
|
|
10
|
-
const ALL_FLAGS = new Set([...VALUE_FLAGS, ...PRINT_VALUE_FLAGS, ...BOOL_FLAGS, '--print', '--resume', '-h', '--help', '--']);
|
|
8
|
+
const PRINT_VALUE_FLAGS = new Set(['--output', '--conversation', '--turn-id', '--timeout', '--provider', '--model', '--agent', '--prompt-profile']);
|
|
9
|
+
const BOOL_FLAGS = new Set(['--demo', '--autoplay', '--demo-onboarding', '--no-clear', '--color', '--service-key']);
|
|
10
|
+
const ALL_FLAGS = new Set([...VALUE_FLAGS, ...PRINT_VALUE_FLAGS, ...BOOL_FLAGS, '--print', '--resume', '--autoplay-exit', '-h', '--help', '--']);
|
|
11
11
|
|
|
12
12
|
export function routesToQuoxon(argv, isTTY) {
|
|
13
13
|
let print = false;
|
|
@@ -18,17 +18,18 @@ export function routesToQuoxon(argv, isTTY) {
|
|
|
18
18
|
for (let i = 0; i < argv.length; i++) {
|
|
19
19
|
const a = argv[i];
|
|
20
20
|
if (a === '--') { return print; } // everything after -- is the prompt
|
|
21
|
-
if (a === '--print') { print = true; const n = argv[i + 1]; if (n !== undefined && !ALL_FLAGS.has(n) && !/^--(profile|verbose|output|conversation|turn-id|timeout|print|provider|model)=/.test(n)) i++; }
|
|
21
|
+
if (a === '--print') { print = true; const n = argv[i + 1]; if (n !== undefined && !ALL_FLAGS.has(n) && !/^--(profile|verbose|output|conversation|turn-id|timeout|print|provider|model|agent|prompt-profile)=/.test(n)) i++; }
|
|
22
22
|
else if (a.startsWith('--print=')) print = true;
|
|
23
23
|
else if (a === '-h' || a === '--help') help = true;
|
|
24
24
|
else if (a === '--verbose') { if (LEVELS.has(argv[i + 1])) i++; }
|
|
25
25
|
else if (a === '--resume') { const n = argv[i + 1]; if (n !== undefined && !n.startsWith('-')) i++; } // optional id or name
|
|
26
|
+
else if (a === '--autoplay-exit') { if (/^\d+(\.\d+)?$/.test(argv[i + 1] || '')) i++; } // optional seconds
|
|
26
27
|
else if (a.startsWith('--resume=')) { /* inline value */ }
|
|
27
28
|
else if (VALUE_FLAGS.has(a)) i++;
|
|
28
29
|
else if (/^--(profile|verbose|name)=/.test(a)) { /* inline value */ }
|
|
29
30
|
else if (BOOL_FLAGS.has(a)) { /* no value */ }
|
|
30
31
|
else if (PRINT_VALUE_FLAGS.has(a)) i++;
|
|
31
|
-
else if (/^--(output|conversation|turn-id|timeout|provider|model)=/.test(a)) { /* inline value */ }
|
|
32
|
+
else if (/^--(output|conversation|turn-id|timeout|provider|model|agent|prompt-profile)=/.test(a)) { /* inline value */ }
|
|
32
33
|
else if (hasPrint && !a.startsWith('-')) { print = true; } // the prompt, wherever it sits among the flags
|
|
33
34
|
else return false; // subcommand, positional, --help, --version, unknown flag
|
|
34
35
|
}
|