@vfrey/vfrey 0.0.1 → 1.0.0-beta.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 +33 -0
- package/README.md +78 -3
- package/accounts.example.json +61 -0
- package/accounts.first-run.json +41 -0
- package/bin/vfrey.mjs +36 -0
- package/integration-tools/README.md +43 -0
- package/integration-tools/image/pillow.md +32 -0
- package/integration-tools/image/playwright.md +33 -0
- package/integration-tools/image/resvg.md +36 -0
- package/integration-tools/image/satori.md +36 -0
- package/integration-tools/image/sharp.md +38 -0
- package/integration-tools/video/blender.md +34 -0
- package/integration-tools/video/ffmpeg.md +41 -0
- package/integration-tools/video/manim.md +37 -0
- package/integration-tools/video/motion-canvas.md +37 -0
- package/integration-tools/video/remotion.md +50 -0
- package/integration-tools/video/revideo.md +32 -0
- package/package.json +74 -6
- package/skills/vfrey-orchestrator/SKILL.md +15 -0
- package/skills/vfrey-orchestrator/channel-video/SKILL.md +41 -0
- package/skills/vfrey-product/SKILL.md +63 -0
- package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-one.svg +14 -0
- package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/cook-two.svg +22 -0
- package/skills/vfrey-product/examples/concurrency-vs-parallelism/framey/index.html +70 -0
- package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-one.svg +14 -0
- package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/cook-two.svg +22 -0
- package/skills/vfrey-product/examples/concurrency-vs-parallelism/remotion/index.tsx +49 -0
- package/skills/vfrey-product/examples/concurrency-vs-parallelism/script.json +15 -0
- package/skills/vfrey-product/examples/octopus-facts/index.html +60 -0
- package/skills/vfrey-product/examples/octopus-facts/octopus.svg +8 -0
- package/skills/vfrey-product/examples/octopus-facts/script.json +14 -0
- package/skills/vfrey-product/push/SKILL.md +15 -0
- package/skills/vfrey-product/scenes/NOTICE +5 -0
- package/skills/vfrey-product/scenes/blocks.md +57 -0
- package/skills/vfrey-product/scenes/craft.md +118 -0
- package/skills/vfrey-product/scenes/motion.md +88 -0
- package/src/analytics/dashboard.ts +109 -0
- package/src/analytics/index.ts +260 -0
- package/src/api/client.ts +361 -0
- package/src/api/cloud-files.ts +197 -0
- package/src/api/cloud-runs.ts +75 -0
- package/src/api/cloud.ts +413 -0
- package/src/api/commands.ts +330 -0
- package/src/api/config.ts +34 -0
- package/src/api/creators.ts +463 -0
- package/src/api/credentials.ts +152 -0
- package/src/api/mail.ts +333 -0
- package/src/api/topics.ts +207 -0
- package/src/api/types.ts +273 -0
- package/src/cli.ts +468 -0
- package/src/cloud/bundle.ts +70 -0
- package/src/cloud/cloudrun-executor.ts +237 -0
- package/src/cloud/executor.ts +281 -0
- package/src/cloud/gcs-sign.ts +76 -0
- package/src/cloud/job.ts +106 -0
- package/src/cloud/remote-job.ts +67 -0
- package/src/cloud/render-job.ts +191 -0
- package/src/config.ts +309 -0
- package/src/dashboard-link.ts +180 -0
- package/src/dashboard-start.ts +103 -0
- package/src/desk/channel.ts +64 -0
- package/src/desk/cli.ts +216 -0
- package/src/desk/creators-route.ts +129 -0
- package/src/desk/fonts/JetBrainsMono-OFL.txt +93 -0
- package/src/desk/fonts/google-sans-flex-latin.woff2 +0 -0
- package/src/desk/fonts/jetbrains-mono-medium.woff2 +0 -0
- package/src/desk/http.ts +460 -0
- package/src/desk/mail-route.ts +103 -0
- package/src/desk/overlay.ts +112 -0
- package/src/desk/preview.ts +422 -0
- package/src/desk/screens.ts +149 -0
- package/src/desk/secrets.ts +143 -0
- package/src/desk/series.ts +127 -0
- package/src/desk/state.ts +77 -0
- package/src/desk/studio-route.ts +119 -0
- package/src/desk/tick-runner.ts +66 -0
- package/src/desk/tick.ts +56 -0
- package/src/desk/topics-route.ts +41 -0
- package/src/desk/ui/app.css +505 -0
- package/src/desk/ui/app.js +185 -0
- package/src/desk/ui/apple-icon.png +0 -0
- package/src/desk/ui/components.js +79 -0
- package/src/desk/ui/core.js +156 -0
- package/src/desk/ui/favicon.ico +0 -0
- package/src/desk/ui/icon.svg +1 -0
- package/src/desk/ui/icons.js +49 -0
- package/src/desk/ui/index.html +41 -0
- package/src/desk/ui/metrics-math.d.ts +22 -0
- package/src/desk/ui/metrics-math.js +135 -0
- package/src/desk/ui/theme.js +5 -0
- package/src/desk/ui/views-creators.js +209 -0
- package/src/desk/ui/views-keys.js +114 -0
- package/src/desk/ui/views-mail.js +188 -0
- package/src/desk/ui/views-misc.js +123 -0
- package/src/desk/ui/views-review.js +119 -0
- package/src/desk/ui/views-runs.js +350 -0
- package/src/desk/ui/views-screens.js +163 -0
- package/src/desk/ui/views-series.js +318 -0
- package/src/desk/ui/views-topics.js +87 -0
- package/src/desk/verbs.ts +361 -0
- package/src/doctor.ts +212 -0
- package/src/drain.ts +14 -0
- package/src/engage/index.ts +217 -0
- package/src/generate/index.ts +110 -0
- package/src/generate/script.ts +152 -0
- package/src/generate/title.ts +78 -0
- package/src/help.ts +252 -0
- package/src/home.ts +45 -0
- package/src/llm/client.ts +177 -0
- package/src/log.ts +7 -0
- package/src/oauth/tokens.ts +189 -0
- package/src/oauth/vault.ts +72 -0
- package/src/pipeline/review.ts +642 -0
- package/src/pipeline/run.ts +443 -0
- package/src/pipeline/series-guard.ts +26 -0
- package/src/pipeline/source-fetch.ts +69 -0
- package/src/pipeline/stages.ts +728 -0
- package/src/pipeline/topics-source.ts +90 -0
- package/src/product/commands.ts +296 -0
- package/src/product/config-file.ts +38 -0
- package/src/product/engine-choice.ts +89 -0
- package/src/product/engines.ts +103 -0
- package/src/product/insights.ts +50 -0
- package/src/product/keys.ts +67 -0
- package/src/product/paths.ts +18 -0
- package/src/product/probes.ts +88 -0
- package/src/product/push-flow.ts +90 -0
- package/src/product/render-video.ts +21 -0
- package/src/product/short.ts +62 -0
- package/src/product/update.ts +32 -0
- package/src/project/canonical.ts +14 -0
- package/src/project/commands.ts +177 -0
- package/src/project/dashboard-status.ts +28 -0
- package/src/project/discover.ts +19 -0
- package/src/project/index-file.ts +73 -0
- package/src/project/marker.ts +92 -0
- package/src/project/migrate.ts +201 -0
- package/src/project/names.ts +27 -0
- package/src/project/notice.ts +16 -0
- package/src/project/open.ts +88 -0
- package/src/project/scaffold.ts +112 -0
- package/src/project/templates.ts +42 -0
- package/src/project/videos.ts +64 -0
- package/src/publish/facebook.ts +91 -0
- package/src/publish/index.ts +12 -0
- package/src/publish/instagram.ts +97 -0
- package/src/publish/rate.ts +62 -0
- package/src/publish/session.ts +242 -0
- package/src/publish/tiktok.ts +202 -0
- package/src/publish/youtube.ts +177 -0
- package/src/queue/desk-ops.ts +1170 -0
- package/src/queue/seal.ts +3 -0
- package/src/queue/store.ts +1006 -0
- package/src/remotion/AiLabel.tsx +26 -0
- package/src/remotion/Root.tsx +73 -0
- package/src/remotion/defaults.ts +26 -0
- package/src/remotion/films/claude/ClaudeFilm.tsx +1014 -0
- package/src/remotion/films/engine/EngineMark.tsx +17 -0
- package/src/remotion/films/rea/ReaShort.tsx +552 -0
- package/src/remotion/films/rea/drawings.tsx +907 -0
- package/src/remotion/films/rea/timing.ts +144 -0
- package/src/remotion/index.ts +4 -0
- package/src/remotion/templates/EditorialSplit.tsx +39 -0
- package/src/remotion/templates/KineticType.tsx +39 -0
- package/src/remotion/templates/SignalBoard.tsx +50 -0
- package/src/remotion/timing.ts +22 -0
- package/src/render/chrome.ts +78 -0
- package/src/render/engine-mark.ts +29 -0
- package/src/render/framey-template.ts +130 -0
- package/src/render/html-engine.ts +149 -0
- package/src/render/node-crypto-stub.ts +11 -0
- package/src/render/probe.ts +29 -0
- package/src/render/props.ts +17 -0
- package/src/render/vertical-short.ts +35 -0
- package/src/render/webpack.ts +33 -0
- package/src/render/worker.ts +65 -0
- package/src/scene/assets/fonts/TitanOne-OFL.txt +94 -0
- package/src/scene/assets/fonts/titan-one.woff2 +0 -0
- package/src/scene/assets/gsap/LICENSE.txt +8 -0
- package/src/scene/assets/gsap/gsap.min.js +11 -0
- package/src/scene/audio.ts +54 -0
- package/src/scene/blocks/LICENSE +190 -0
- package/src/scene/blocks/NOTICE +5 -0
- package/src/scene/blocks/bar-chart-race/bar-chart-race.html +585 -0
- package/src/scene/blocks/beat-freeze-cut/beat-freeze-cut.html +874 -0
- package/src/scene/blocks/camcorder-hud/camcorder-hud.html +164 -0
- package/src/scene/blocks/camera-dolly-zoom/camera-dolly-zoom.html +355 -0
- package/src/scene/blocks/code-diff/code-diff.html +817 -0
- package/src/scene/blocks/code-snippet-apple-terminal-pro/code-snippet-apple-terminal-pro.html +248 -0
- package/src/scene/blocks/code-typing/code-typing.html +764 -0
- package/src/scene/blocks/data-chart/data-chart.html +452 -0
- package/src/scene/blocks/flowchart-vertical/flowchart-vertical.html +454 -0
- package/src/scene/blocks/hw-scribble-transition/hw-scribble-transition.html +153 -0
- package/src/scene/blocks/index.json +824 -0
- package/src/scene/blocks/lt-accent-underline/lt-accent-underline.html +107 -0
- package/src/scene/blocks/lt-bold-block/lt-bold-block.html +109 -0
- package/src/scene/blocks/lt-clean-bar/lt-clean-bar.html +112 -0
- package/src/scene/blocks/lt-dark-card/lt-dark-card.html +111 -0
- package/src/scene/blocks/lt-kicker-name/lt-kicker-name.html +114 -0
- package/src/scene/blocks/lt-mask-reveal/lt-mask-reveal.html +120 -0
- package/src/scene/blocks/lt-neon-border/lt-neon-border.html +391 -0
- package/src/scene/blocks/lt-stack-bars/lt-stack-bars.html +109 -0
- package/src/scene/blocks/macos-notification/macos-notification.html +194 -0
- package/src/scene/blocks/mk-background/mk-background.html +236 -0
- package/src/scene/blocks/mk-callout-highlight/mk-callout-highlight.html +183 -0
- package/src/scene/blocks/mk-clone-wall-transition/mk-clone-wall-transition.html +226 -0
- package/src/scene/blocks/mk-line-graph/mk-line-graph.html +293 -0
- package/src/scene/blocks/mk-progress-stat/mk-progress-stat.html +186 -0
- package/src/scene/blocks/mk-specs-list/mk-specs-list.html +223 -0
- package/src/scene/blocks/news-ticker/news-ticker.html +409 -0
- package/src/scene/blocks/organic-light-leak-overlay/organic-light-leak-overlay.html +126 -0
- package/src/scene/blocks/oscilloscope-trace/oscilloscope-trace.html +519 -0
- package/src/scene/blocks/snow/snow.html +205 -0
- package/src/scene/blocks/split-flap-board/split-flap-board.html +347 -0
- package/src/scene/blocks/spotify-card/spotify-card.html +294 -0
- package/src/scene/blocks/starfield/starfield.html +188 -0
- package/src/scene/blocks/thread-message-stack/thread-message-stack.html +239 -0
- package/src/scene/blocks/week-in-merges/week-in-merges.html +470 -0
- package/src/scene/blocks/x-post/x-post.html +437 -0
- package/src/scene/blocks/yt-comment-card/yt-comment-card.html +319 -0
- package/src/scene/blocks/yt-lcd-background/yt-lcd-background.html +307 -0
- package/src/scene/blocks/yt-prism-title/yt-prism-title.html +205 -0
- package/src/scene/blocks.ts +229 -0
- package/src/scene/command.ts +272 -0
- package/src/scene/figure.ts +181 -0
- package/src/scene/glyphs.ts +107 -0
- package/src/scene/init.ts +86 -0
- package/src/scene/inspect/css-tree.d.ts +6 -0
- package/src/scene/inspect/page-scripts.ts +272 -0
- package/src/scene/inspect/report.ts +405 -0
- package/src/scene/inspect/run.ts +200 -0
- package/src/scene/inspect/source.ts +236 -0
- package/src/scene/label.ts +131 -0
- package/src/scene/net-guard.ts +74 -0
- package/src/scene/render.ts +292 -0
- package/src/scene/runtime/browser.ts +199 -0
- package/src/scene/runtime/core.ts +181 -0
- package/src/scene/runtime/react.tsx +115 -0
- package/src/scene/runtime/transitions.ts +133 -0
- package/src/scene/sanitize.ts +181 -0
- package/src/scene/scene.ts +152 -0
- package/src/scene/studio-command.ts +48 -0
- package/src/scene/studio-skin.ts +59 -0
- package/src/scene/studio.ts +337 -0
- package/src/scene/supply.ts +111 -0
- package/src/scene/timing.ts +288 -0
- package/src/scene/transitions/LICENSE +190 -0
- package/src/scene/transitions/NOTICE +5 -0
- package/src/scene/transitions/SOURCE.json +24 -0
- package/src/scene/transitions/transitions.global.js +38 -0
- package/src/scene/transitions.ts +26 -0
- package/src/service/all-projects.ts +153 -0
- package/src/service/commands.ts +256 -0
- package/src/service/due.ts +82 -0
- package/src/service/lock.ts +101 -0
- package/src/service/log-file.ts +56 -0
- package/src/service/state.ts +41 -0
- package/src/service/units.ts +90 -0
- package/src/service/worker.ts +51 -0
- package/src/skill-agents.ts +74 -0
- package/src/skill-install.ts +334 -0
- package/src/sync-write.ts +21 -0
- package/src/tick-report.ts +205 -0
- package/src/tts.ts +124 -0
- package/vendor/@vfrey/contracts/dist/account.d.ts +97 -0
- package/vendor/@vfrey/contracts/dist/account.js +27 -0
- package/vendor/@vfrey/contracts/dist/checks.d.ts +8 -0
- package/vendor/@vfrey/contracts/dist/checks.js +1 -0
- package/vendor/@vfrey/contracts/dist/credentials/crypto.d.ts +4 -0
- package/vendor/@vfrey/contracts/dist/credentials/crypto.js +38 -0
- package/vendor/@vfrey/contracts/dist/domain/advice-persona.d.ts +10 -0
- package/vendor/@vfrey/contracts/dist/domain/advice-persona.js +24 -0
- package/vendor/@vfrey/contracts/dist/domain/backoff.d.ts +13 -0
- package/vendor/@vfrey/contracts/dist/domain/backoff.js +27 -0
- package/vendor/@vfrey/contracts/dist/domain/cadence.d.ts +29 -0
- package/vendor/@vfrey/contracts/dist/domain/cadence.js +95 -0
- package/vendor/@vfrey/contracts/dist/domain/creators.d.ts +146 -0
- package/vendor/@vfrey/contracts/dist/domain/creators.js +2 -0
- package/vendor/@vfrey/contracts/dist/domain/disclosure.d.ts +127 -0
- package/vendor/@vfrey/contracts/dist/domain/disclosure.js +250 -0
- package/vendor/@vfrey/contracts/dist/domain/errors.d.ts +34 -0
- package/vendor/@vfrey/contracts/dist/domain/errors.js +68 -0
- package/vendor/@vfrey/contracts/dist/domain/redact.d.ts +1 -0
- package/vendor/@vfrey/contracts/dist/domain/redact.js +21 -0
- package/vendor/@vfrey/contracts/dist/domain/revenue.d.ts +13 -0
- package/vendor/@vfrey/contracts/dist/domain/revenue.js +16 -0
- package/vendor/@vfrey/contracts/dist/domain/safety.d.ts +20 -0
- package/vendor/@vfrey/contracts/dist/domain/safety.js +61 -0
- package/vendor/@vfrey/contracts/dist/domain/similarity.d.ts +13 -0
- package/vendor/@vfrey/contracts/dist/domain/similarity.js +100 -0
- package/vendor/@vfrey/contracts/dist/domain/templates.d.ts +18 -0
- package/vendor/@vfrey/contracts/dist/domain/templates.js +67 -0
- package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.d.ts +19 -0
- package/vendor/@vfrey/contracts/dist/domain/tiktok-chunks.js +52 -0
- package/vendor/@vfrey/contracts/dist/domain/topics.d.ts +78 -0
- package/vendor/@vfrey/contracts/dist/domain/topics.js +4 -0
- package/vendor/@vfrey/contracts/dist/domain/types.d.ts +216 -0
- package/vendor/@vfrey/contracts/dist/domain/types.js +1 -0
- package/vendor/@vfrey/contracts/dist/domain/variation.d.ts +57 -0
- package/vendor/@vfrey/contracts/dist/domain/variation.js +278 -0
- package/vendor/@vfrey/contracts/dist/events.d.ts +20 -0
- package/vendor/@vfrey/contracts/dist/events.js +1 -0
- package/vendor/@vfrey/contracts/dist/http.d.ts +11 -0
- package/vendor/@vfrey/contracts/dist/http.js +37 -0
- package/vendor/@vfrey/contracts/dist/index.d.ts +22 -0
- package/vendor/@vfrey/contracts/dist/index.js +22 -0
- package/vendor/@vfrey/contracts/dist/log.d.ts +2 -0
- package/vendor/@vfrey/contracts/dist/log.js +10 -0
- package/vendor/@vfrey/contracts/dist/mail.d.ts +55 -0
- package/vendor/@vfrey/contracts/dist/mail.js +1 -0
- package/vendor/@vfrey/contracts/package.json +18 -0
- package/vendor/@vfrey/ingest/dist/index.d.ts +41 -0
- package/vendor/@vfrey/ingest/dist/index.js +221 -0
- package/vendor/@vfrey/ingest/dist/parse.d.ts +5 -0
- package/vendor/@vfrey/ingest/dist/parse.js +165 -0
- package/vendor/@vfrey/ingest/package.json +21 -0
- package/vendor/framey/LICENSE +190 -0
- package/vendor/framey/NOTICE +15 -0
- package/vendor/framey/SOURCE.json +24 -0
- package/vendor/framey/STUDIO-SOURCE.json +9 -0
- package/vendor/framey/bin/framey-localize-fonts.mjs +12 -0
- package/vendor/framey/bin/framey.mjs +16 -0
- package/vendor/framey/dist/add-VMJD5KBS.js +75 -0
- package/vendor/framey/dist/animatedGifPrep-QPKGJ6PM.js +43 -0
- package/vendor/framey/dist/api.d.ts +211 -0
- package/vendor/framey/dist/api.js +76 -0
- package/vendor/framey/dist/appHistory-WW56FZTT.js +31 -0
- package/vendor/framey/dist/asset-WQKGOELE.js +26 -0
- package/vendor/framey/dist/audio-RSJWVWRA.js +1936 -0
- package/vendor/framey/dist/batchRender-3HPICDCT.js +366 -0
- package/vendor/framey/dist/beats-HL2BDUZI.js +273 -0
- package/vendor/framey/dist/benchmark-RWCWHI5Z.js +230 -0
- package/vendor/framey/dist/browser-ECYET3Q2.js +206 -0
- package/vendor/framey/dist/bundleWithLocalizedFonts-ALYBQEQT.js +52 -0
- package/vendor/framey/dist/captureCompositionFrame-4DA6SEH2.js +94 -0
- package/vendor/framey/dist/catalog-5JVDEUWK.js +979 -0
- package/vendor/framey/dist/catch-up-NEBCL5NO.js +106 -0
- package/vendor/framey/dist/check-F5N544ML.js +111 -0
- package/vendor/framey/dist/checkBrowser-LZ66CMJG.js +110 -0
- package/vendor/framey/dist/chunk-2K7Z2HVP.js +372 -0
- package/vendor/framey/dist/chunk-2UZQHDM7.js +323 -0
- package/vendor/framey/dist/chunk-2X4PQEYM.js +34 -0
- package/vendor/framey/dist/chunk-3422KMTD.js +168 -0
- package/vendor/framey/dist/chunk-3FYD4YEK.js +72 -0
- package/vendor/framey/dist/chunk-3GXQPCJC.js +682 -0
- package/vendor/framey/dist/chunk-3LM6YPBR.js +179 -0
- package/vendor/framey/dist/chunk-442JNXRM.js +20 -0
- package/vendor/framey/dist/chunk-4BNN5FGX.js +182 -0
- package/vendor/framey/dist/chunk-4P7NX5BM.js +11532 -0
- package/vendor/framey/dist/chunk-4UMPIPCQ.js +88 -0
- package/vendor/framey/dist/chunk-4YYJOFKS.js +28 -0
- package/vendor/framey/dist/chunk-54HJ63Q2.js +29 -0
- package/vendor/framey/dist/chunk-5ETJX6WM.js +89 -0
- package/vendor/framey/dist/chunk-5SG54JRS.js +68 -0
- package/vendor/framey/dist/chunk-634HSJ3J.js +58 -0
- package/vendor/framey/dist/chunk-66LREXGS.js +48 -0
- package/vendor/framey/dist/chunk-6BEFEWFB.js +25 -0
- package/vendor/framey/dist/chunk-6BNTGNGD.js +286 -0
- package/vendor/framey/dist/chunk-6DDPOHMK.js +140 -0
- package/vendor/framey/dist/chunk-6GV5XSOR.js +214 -0
- package/vendor/framey/dist/chunk-6JR2XUEE.js +127 -0
- package/vendor/framey/dist/chunk-73QVATIM.js +362 -0
- package/vendor/framey/dist/chunk-7FMUTGOH.js +279 -0
- package/vendor/framey/dist/chunk-7JQFJ6JJ.js +291 -0
- package/vendor/framey/dist/chunk-AHPGAESX.js +113 -0
- package/vendor/framey/dist/chunk-AHX34EFP.js +15 -0
- package/vendor/framey/dist/chunk-AJ5CSAEZ.js +487 -0
- package/vendor/framey/dist/chunk-B7RJV74O.js +5047 -0
- package/vendor/framey/dist/chunk-BL4U6U52.js +254 -0
- package/vendor/framey/dist/chunk-BSQ7XANM.js +210 -0
- package/vendor/framey/dist/chunk-BZ56MTDX.js +6 -0
- package/vendor/framey/dist/chunk-C5BO7PMT.js +282 -0
- package/vendor/framey/dist/chunk-CFUCHO4T.js +358 -0
- package/vendor/framey/dist/chunk-CZGHFATT.js +31 -0
- package/vendor/framey/dist/chunk-DLA44CMS.js +5649 -0
- package/vendor/framey/dist/chunk-DPVXBVLL.js +31292 -0
- package/vendor/framey/dist/chunk-DQBY7FRR.js +397 -0
- package/vendor/framey/dist/chunk-EAMLBAHA.js +154 -0
- package/vendor/framey/dist/chunk-EOVYQ3IG.js +143 -0
- package/vendor/framey/dist/chunk-EVMY7IPL.js +612 -0
- package/vendor/framey/dist/chunk-FG4BBFZI.js +122 -0
- package/vendor/framey/dist/chunk-FI4I7CME.js +56 -0
- package/vendor/framey/dist/chunk-FLREUEHW.js +2081 -0
- package/vendor/framey/dist/chunk-FUFP7A7S.js +1126 -0
- package/vendor/framey/dist/chunk-FV3PIKGH.js +56 -0
- package/vendor/framey/dist/chunk-FXMKHHPO.js +123 -0
- package/vendor/framey/dist/chunk-GGZAM5VH.js +1187 -0
- package/vendor/framey/dist/chunk-GKZEVJIB.js +39 -0
- package/vendor/framey/dist/chunk-GMECXFAN.js +57 -0
- package/vendor/framey/dist/chunk-GNEFDLFB.js +621 -0
- package/vendor/framey/dist/chunk-GPMLSOEG.js +19274 -0
- package/vendor/framey/dist/chunk-GPYVT5EE.js +59 -0
- package/vendor/framey/dist/chunk-H6IEMZEV.js +40 -0
- package/vendor/framey/dist/chunk-HEFQCIXR.js +170 -0
- package/vendor/framey/dist/chunk-HFQ4CWHA.js +118 -0
- package/vendor/framey/dist/chunk-HPDTCOKE.js +304 -0
- package/vendor/framey/dist/chunk-HTUHQKDB.js +548 -0
- package/vendor/framey/dist/chunk-HU2SPFNG.js +103 -0
- package/vendor/framey/dist/chunk-HVW7ABXD.js +19 -0
- package/vendor/framey/dist/chunk-IG7NDKXO.js +26 -0
- package/vendor/framey/dist/chunk-II3J3WXK.js +246 -0
- package/vendor/framey/dist/chunk-IR35BCLK.js +13 -0
- package/vendor/framey/dist/chunk-ISN5GRYI.js +20 -0
- package/vendor/framey/dist/chunk-IUONB55J.js +669 -0
- package/vendor/framey/dist/chunk-IVSUQR2B.js +161 -0
- package/vendor/framey/dist/chunk-IXU6PQSW.js +259 -0
- package/vendor/framey/dist/chunk-IZCW2NKT.js +29 -0
- package/vendor/framey/dist/chunk-JGXJU5PF.js +68 -0
- package/vendor/framey/dist/chunk-JHOCK3DG.js +27 -0
- package/vendor/framey/dist/chunk-JVBRJMOP.js +121 -0
- package/vendor/framey/dist/chunk-K4MJX7SR.js +17 -0
- package/vendor/framey/dist/chunk-K4WKGXRC.js +18 -0
- package/vendor/framey/dist/chunk-KGPLIH7B.js +127 -0
- package/vendor/framey/dist/chunk-KLIKCX6Q.js +63 -0
- package/vendor/framey/dist/chunk-KXTKKBOC.js +61 -0
- package/vendor/framey/dist/chunk-KZI44OPA.js +185 -0
- package/vendor/framey/dist/chunk-LEKZNRKI.js +45 -0
- package/vendor/framey/dist/chunk-LFGJWOVA.js +61 -0
- package/vendor/framey/dist/chunk-LLMSX6V6.js +17 -0
- package/vendor/framey/dist/chunk-LTGTN2TH.js +195 -0
- package/vendor/framey/dist/chunk-M2WBOQ2Q.js +54 -0
- package/vendor/framey/dist/chunk-MI5FTLYK.js +399 -0
- package/vendor/framey/dist/chunk-MLQP2QUF.js +1809 -0
- package/vendor/framey/dist/chunk-MMQ52NIZ.js +956 -0
- package/vendor/framey/dist/chunk-ND46XKK3.js +742 -0
- package/vendor/framey/dist/chunk-NYEXNSHM.js +504 -0
- package/vendor/framey/dist/chunk-O4YRB27L.js +57 -0
- package/vendor/framey/dist/chunk-O7BGSQ5F.js +92 -0
- package/vendor/framey/dist/chunk-OFQWTKPW.js +117 -0
- package/vendor/framey/dist/chunk-P5ZBLXJ6.js +91 -0
- package/vendor/framey/dist/chunk-P6LJ4Y32.js +4662 -0
- package/vendor/framey/dist/chunk-PKZ7RK5N.js +281 -0
- package/vendor/framey/dist/chunk-PURHAXFL.js +15 -0
- package/vendor/framey/dist/chunk-Q5X2B5WT.js +29 -0
- package/vendor/framey/dist/chunk-QAMKOG67.js +248 -0
- package/vendor/framey/dist/chunk-R6YBK4XX.js +514 -0
- package/vendor/framey/dist/chunk-RGLQURIX.js +2997 -0
- package/vendor/framey/dist/chunk-RNV3DM4S.js +3573 -0
- package/vendor/framey/dist/chunk-ROEW726S.js +4638 -0
- package/vendor/framey/dist/chunk-RQVDTPGD.js +6 -0
- package/vendor/framey/dist/chunk-RVZHGOGR.js +26 -0
- package/vendor/framey/dist/chunk-RXATE6FZ.js +385 -0
- package/vendor/framey/dist/chunk-S3S4TGEH.js +424 -0
- package/vendor/framey/dist/chunk-SDYDNHEE.js +11202 -0
- package/vendor/framey/dist/chunk-SSWBU67I.js +173 -0
- package/vendor/framey/dist/chunk-ST35C4K6.js +28 -0
- package/vendor/framey/dist/chunk-SZNTYTIV.js +990 -0
- package/vendor/framey/dist/chunk-T2EUWCJE.js +29 -0
- package/vendor/framey/dist/chunk-T6AGUTZJ.js +444 -0
- package/vendor/framey/dist/chunk-THJALHFJ.js +11131 -0
- package/vendor/framey/dist/chunk-TIQB63MX.js +18128 -0
- package/vendor/framey/dist/chunk-U242RTCT.js +134 -0
- package/vendor/framey/dist/chunk-UJZREAV6.js +3901 -0
- package/vendor/framey/dist/chunk-UMD3V7CU.js +264 -0
- package/vendor/framey/dist/chunk-UOFAE5RF.js +42 -0
- package/vendor/framey/dist/chunk-UTEIUGAZ.js +29 -0
- package/vendor/framey/dist/chunk-VAS6HQX3.js +138 -0
- package/vendor/framey/dist/chunk-VC76R6W2.js +27 -0
- package/vendor/framey/dist/chunk-VFZ7W5W7.js +226 -0
- package/vendor/framey/dist/chunk-VHNLZAE2.js +348 -0
- package/vendor/framey/dist/chunk-VMC4WSH5.js +278 -0
- package/vendor/framey/dist/chunk-VORQIH64.js +108 -0
- package/vendor/framey/dist/chunk-VTXFRIHO.js +186 -0
- package/vendor/framey/dist/chunk-W2LGJSEN.js +182 -0
- package/vendor/framey/dist/chunk-WKBM7NDG.js +32 -0
- package/vendor/framey/dist/chunk-WMQNIQDJ.js +2057 -0
- package/vendor/framey/dist/chunk-WN4XZC5F.js +504 -0
- package/vendor/framey/dist/chunk-WQ6ZXHFQ.js +133 -0
- package/vendor/framey/dist/chunk-X7HBSTCZ.js +53 -0
- package/vendor/framey/dist/chunk-X7MTZ4T2.js +6 -0
- package/vendor/framey/dist/chunk-XPTOJZJF.js +308 -0
- package/vendor/framey/dist/chunk-XT6MXC7A.js +6 -0
- package/vendor/framey/dist/chunk-XT7X6QCP.js +6 -0
- package/vendor/framey/dist/chunk-XTMDWNEC.js +2820 -0
- package/vendor/framey/dist/chunk-XUHOIDKG.js +6 -0
- package/vendor/framey/dist/chunk-XX7LTW5Y.js +138 -0
- package/vendor/framey/dist/chunk-Y3YGTZEG.js +382 -0
- package/vendor/framey/dist/chunk-Y5SBSGN7.js +346 -0
- package/vendor/framey/dist/chunk-YCMVI4MZ.js +625 -0
- package/vendor/framey/dist/chunk-YOR4CTCE.js +261 -0
- package/vendor/framey/dist/chunk-YPRBGITP.js +2748 -0
- package/vendor/framey/dist/chunk-ZKDMAOFU.js +32 -0
- package/vendor/framey/dist/chunk-ZW6DURPF.js +1318 -0
- package/vendor/framey/dist/clean-ZJOGDKDM.js +336 -0
- package/vendor/framey/dist/cli.js +439 -0
- package/vendor/framey/dist/cloudrun-HGJ3B6ZV.js +767 -0
- package/vendor/framey/dist/commands/contrast-audit.browser.js +643 -0
- package/vendor/framey/dist/commands/layout-audit.browser.js +2914 -0
- package/vendor/framey/dist/commands/motion-sample.browser.js +74 -0
- package/vendor/framey/dist/commands/motion-signature.browser.js +475 -0
- package/vendor/framey/dist/compare-W7UY3BAZ.js +463 -0
- package/vendor/framey/dist/compiler-TM3W6GYF.js +136 -0
- package/vendor/framey/dist/component-QF5VGYMU.js +176 -0
- package/vendor/framey/dist/compositions-XT3PMNDF.js +238 -0
- package/vendor/framey/dist/contactSheet-7W6GYHBQ.js +24 -0
- package/vendor/framey/dist/deploy-6FJPWKF2.js +299 -0
- package/vendor/framey/dist/destroy-HE2RIPKZ.js +57 -0
- package/vendor/framey/dist/deterministicFonts-RADD3BSX.js +50 -0
- package/vendor/framey/dist/dist-4S2FGGVY.js +422 -0
- package/vendor/framey/dist/dist-BE4B2EZE.js +32 -0
- package/vendor/framey/dist/dist-EWXJGN63.js +129 -0
- package/vendor/framey/dist/docs-VKIRFEEX.js +131 -0
- package/vendor/framey/dist/doctor-2UNJ2G7U.js +74 -0
- package/vendor/framey/dist/dom-37K6YOH4.js +14 -0
- package/vendor/framey/dist/dotEnv-7PZQTVIM.js +54 -0
- package/vendor/framey/dist/events-ACY3P2PA.js +76 -0
- package/vendor/framey/dist/events-IHB3B2MK.js +69 -0
- package/vendor/framey/dist/ffmpeg-DR5LGGSK.js +63 -0
- package/vendor/framey/dist/figma-BODVUPHB.js +63 -0
- package/vendor/framey/dist/fontData.generated-NXAOI4GH.js +13 -0
- package/vendor/framey/dist/fontLocalizeCli.js +142 -0
- package/vendor/framey/dist/gpuPolicy-XLEXORZY.js +49 -0
- package/vendor/framey/dist/grade-compare-GAXFQ74C.js +661 -0
- package/vendor/framey/dist/gsapParser-IEUSLYDJ.js +2885 -0
- package/vendor/framey/dist/gsapParserAcorn-LZJKCFQI.js +30 -0
- package/vendor/framey/dist/help-VCB5X2HS.js +184 -0
- package/vendor/framey/dist/history-ENGZEVFT.js +471 -0
- package/vendor/framey/dist/hyperframe.manifest.json +22 -0
- package/vendor/framey/dist/hyperframe.runtime.iife.js +1132 -0
- package/vendor/framey/dist/hyperframes-player.global.js +478 -0
- package/vendor/framey/dist/hyperframes-slideshow.global.js +148 -0
- package/vendor/framey/dist/info-WPCJHBMU.js +182 -0
- package/vendor/framey/dist/init-G4WGLYGD.js +1176 -0
- package/vendor/framey/dist/inspect-5IQ6CNEQ.js +106 -0
- package/vendor/framey/dist/installer-ML4HWUV7.js +40 -0
- package/vendor/framey/dist/keyframes-Q6XJO7VW.js +2755 -0
- package/vendor/framey/dist/lambda-A7JC74JF.js +468 -0
- package/vendor/framey/dist/layout-YET6XNXA.js +95 -0
- package/vendor/framey/dist/lint-I7FZN2VJ.js +162 -0
- package/vendor/framey/dist/lintProject-PDB3UN72.js +30 -0
- package/vendor/framey/dist/manager-CD6LJ7ZN.js +45 -0
- package/vendor/framey/dist/manager-WA4F2GST.js +67 -0
- package/vendor/framey/dist/media-treatment-BXYS4WVA.js +1030 -0
- package/vendor/framey/dist/media-use-LWH3MANK.js +113 -0
- package/vendor/framey/dist/models-K363FYM4.js +195 -0
- package/vendor/framey/dist/motionShot-GPAVWXLH.js +640 -0
- package/vendor/framey/dist/normalize-FASIPBUM.js +24 -0
- package/vendor/framey/dist/normalize-audio-VDWYRHN6.js +268 -0
- package/vendor/framey/dist/open-E3TB6P6J.js +128 -0
- package/vendor/framey/dist/parakeetRunner-UP34UOI2.js +58 -0
- package/vendor/framey/dist/pipeline-VXIUYEBU.js +64 -0
- package/vendor/framey/dist/play-BUTDQ4DV.js +353 -0
- package/vendor/framey/dist/policies-OLDYGFK5.js +309 -0
- package/vendor/framey/dist/preflight-2KZ2GWAZ.js +55 -0
- package/vendor/framey/dist/present-GXYSM7NX.js +353 -0
- package/vendor/framey/dist/preview-EKZ33JOJ.js +1910 -0
- package/vendor/framey/dist/producer-SKU5EV3J.js +13 -0
- package/vendor/framey/dist/progress-ZWB4Z4ET.js +76 -0
- package/vendor/framey/dist/projectConfig-3MZAYVTS.js +60 -0
- package/vendor/framey/dist/publication-DTKWNF74.js +33 -0
- package/vendor/framey/dist/remove-background-OY5L7XN2.js +265 -0
- package/vendor/framey/dist/render-CDV4GDFX.js +187 -0
- package/vendor/framey/dist/render-YE5YAMOD.js +2620 -0
- package/vendor/framey/dist/render-batch-ZAMFPCLL.js +274 -0
- package/vendor/framey/dist/renderSetupWorker.js +120 -0
- package/vendor/framey/dist/resolver-D5BIPSEW.js +42 -0
- package/vendor/framey/dist/runtimeVersion.js +18 -0
- package/vendor/framey/dist/sam-WFZXI4F7.js +23 -0
- package/vendor/framey/dist/shaderTransitionWorker.js +44 -0
- package/vendor/framey/dist/sherpa-RQWLV7I3.js +79 -0
- package/vendor/framey/dist/sherpaWorker.js +84 -0
- package/vendor/framey/dist/sites-AMOVABTK.js +54 -0
- package/vendor/framey/dist/skill-ZHVLH7KX.js +15 -0
- package/vendor/framey/dist/slideshow-SJGK4RQS.js +24 -0
- package/vendor/framey/dist/snapshot-TUXL6LBQ.js +1515 -0
- package/vendor/framey/dist/src-JHQGB2S6.js +215 -0
- package/vendor/framey/dist/src-Z5PGEMXB.js +532 -0
- package/vendor/framey/dist/state-B6H3WHCF.js +28 -0
- package/vendor/framey/dist/staticProjectServer-DFVZOUGI.js +63 -0
- package/vendor/framey/dist/studio/assets/hyperframes-player-DLaKjw0L.js +478 -0
- package/vendor/framey/dist/studio/assets/index-BX3KHhGX.js +71 -0
- package/vendor/framey/dist/studio/assets/index-CYbvOVp-.css +1 -0
- package/vendor/framey/dist/studio/assets/index-Dp3QEUGL.js +402 -0
- package/vendor/framey/dist/studio/assets/index-qrTAXbqc.js +531 -0
- package/vendor/framey/dist/studio/favicon.svg +14 -0
- package/vendor/framey/dist/studio/icons/timeline/audio.svg +7 -0
- package/vendor/framey/dist/studio/icons/timeline/captions.svg +5 -0
- package/vendor/framey/dist/studio/icons/timeline/composition.svg +12 -0
- package/vendor/framey/dist/studio/icons/timeline/image.svg +18 -0
- package/vendor/framey/dist/studio/icons/timeline/music.svg +10 -0
- package/vendor/framey/dist/studio/icons/timeline/text.svg +3 -0
- package/vendor/framey/dist/studio/index.html +23 -0
- package/vendor/framey/dist/studio-api-2NECGRMB.js +179 -0
- package/vendor/framey/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
- package/vendor/framey/dist/studioServer-N2OPUMOQ.js +1569 -0
- package/vendor/framey/dist/synthesize-PKTB5ATG.js +183 -0
- package/vendor/framey/dist/system-7F3UEHQT.js +27 -0
- package/vendor/framey/dist/telemetry-DQGPEKM6.js +145 -0
- package/vendor/framey/dist/telemetry-UN55N6U6.js +77 -0
- package/vendor/framey/dist/timeline-LHUUMK63.js +1295 -0
- package/vendor/framey/dist/tokens-OLECWDFK.js +92 -0
- package/vendor/framey/dist/transcribe-O7HQKMIV.js +331 -0
- package/vendor/framey/dist/transcribe-UJESPBT5.js +76 -0
- package/vendor/framey/dist/tts-YCCQHZD4.js +234 -0
- package/vendor/framey/dist/urlDownloader-H2LXLG4U.js +48 -0
- package/vendor/framey/dist/usage-HG4WMM7A.js +2167 -0
- package/vendor/framey/dist/validate-F2XMN6EV.js +87 -0
- package/vendor/framey/dist/vendor/npm/gsap@3.15.0/GSAP-LICENSE.txt +8 -0
- package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/CustomEase.min.js +11 -0
- package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/MotionPathPlugin.min.js +11 -0
- package/vendor/framey/dist/vendor/npm/gsap@3.15.0/dist/gsap.min.js +11 -0
- package/vendor/framey/dist/warmCheck.js +220 -0
- package/vendor/framey/dist/warmCheckClient.js +139 -0
- package/vendor/framey/dist/workspaceBuildCheck-XYD2YTFW.js +133 -0
- package/vendor/framey-player/LICENSE +190 -0
- package/vendor/framey-player/NOTICE +16 -0
- package/vendor/framey-player/SOURCE.json +6 -0
- package/vendor/framey-player/hyperframes-player.global.js +478 -0
- package/vendor/framey.pin +1 -0
- package/bin/index.js +0 -3
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
// `vfrey login`, `logout`, `whoami`, and the doctor account line.
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { ApiClient, ApiFailure, clean, type FetchLike } from "./client.js";
|
|
4
|
+
import { apiHost, ApiConfigError, resolveApiUrl } from "./config.js";
|
|
5
|
+
import { deleteToken, loadStoredToken, loadToken, readHint, saveHint, saveToken, type CredentialDeps, type Runner } from "./credentials.js";
|
|
6
|
+
import { formatUserCode, type MeResponse, type OrgSummary } from "./types.js";
|
|
7
|
+
|
|
8
|
+
type Env = Record<string, string | undefined>;
|
|
9
|
+
|
|
10
|
+
export interface ApiIo {
|
|
11
|
+
env: Env;
|
|
12
|
+
stdout: (text: string) => void;
|
|
13
|
+
stderr: (text: string) => void;
|
|
14
|
+
homedir?: string;
|
|
15
|
+
platform?: NodeJS.Platform;
|
|
16
|
+
run?: Runner;
|
|
17
|
+
fetch?: FetchLike;
|
|
18
|
+
sleep?: (ms: number) => Promise<void>;
|
|
19
|
+
now?: () => number;
|
|
20
|
+
/** Opens a URL in the browser. Defaults to the `open` package. */
|
|
21
|
+
openUrl?: (url: string) => Promise<void>;
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const NOT_LIVE_FIX = "free features work without an account. If you run your own vfrey server, set VFREY_API_URL or pass --api <url>.";
|
|
26
|
+
|
|
27
|
+
function creds(io: ApiIo): CredentialDeps {
|
|
28
|
+
return { env: io.env, homedir: io.homedir ?? os.homedir(), ...(io.platform ? { platform: io.platform } : {}), ...(io.run ? { run: io.run } : {}) };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function refuse(io: ApiIo, message: string, fix: string): number {
|
|
32
|
+
io.stderr(`✗ ${message}\nFix: ${fix}\n`);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function failure(io: ApiIo, error: unknown): number {
|
|
37
|
+
if (error instanceof ApiFailure || error instanceof ApiConfigError) return refuse(io, error.message, error.fix);
|
|
38
|
+
return refuse(io, error instanceof Error ? clean(error.message) : "Something went wrong.", "run `npx vfrey doctor` and check the line above.");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function client(io: ApiIo, base: string, token?: string | null): ApiClient {
|
|
42
|
+
return new ApiClient({ baseUrl: base, token: token ?? null, ...(io.fetch ? { fetch: io.fetch } : {}), ...(io.timeoutMs ? { timeoutMs: io.timeoutMs } : {}) });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The flag value after `--api`, or `--api=URL`. */
|
|
46
|
+
function flagValue(args: string[], name: string): string | null | undefined {
|
|
47
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
48
|
+
const arg = args[i]!;
|
|
49
|
+
if (arg === name) return args[i + 1] && !args[i + 1]!.startsWith("--") ? args[i + 1]! : null;
|
|
50
|
+
if (arg.startsWith(`${name}=`)) return arg.slice(name.length + 1);
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Parses the flags these commands share. Returns an error text for an unknown or malformed flag. */
|
|
56
|
+
function parse(args: string[], allowed: string[], valued: string[]): { flags: Set<string>; api?: string; error?: string } {
|
|
57
|
+
const flags = new Set<string>();
|
|
58
|
+
let api: string | undefined;
|
|
59
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
60
|
+
const arg = args[i]!;
|
|
61
|
+
const name = arg.includes("=") ? arg.slice(0, arg.indexOf("=")) : arg;
|
|
62
|
+
if (!allowed.includes(name) && !valued.includes(name)) return { flags, error: `Unknown option "${arg}".` };
|
|
63
|
+
if (valued.includes(name)) {
|
|
64
|
+
const value = flagValue(args, name);
|
|
65
|
+
if (!value) return { flags, error: `${name} needs a value.` };
|
|
66
|
+
api = value;
|
|
67
|
+
if (!arg.includes("=")) i += 1;
|
|
68
|
+
} else flags.add(name);
|
|
69
|
+
}
|
|
70
|
+
return { flags, ...(api ? { api } : {}) };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function resolve(io: ApiIo, api?: string): string | null {
|
|
74
|
+
return resolveApiUrl(io.env, api ?? null);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function notLive(io: ApiIo): number {
|
|
78
|
+
return refuse(io, "vfrey accounts are not live yet.", NOT_LIVE_FIX);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const defaultSleep = (ms: number) => new Promise<void>((done) => setTimeout(done, ms));
|
|
82
|
+
|
|
83
|
+
async function defaultOpen(url: string): Promise<void> {
|
|
84
|
+
const { default: open } = await import("open");
|
|
85
|
+
await open(url);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function browserUrl(url: string): string | null {
|
|
89
|
+
try {
|
|
90
|
+
const parsed = new URL(url);
|
|
91
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.href : null;
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function runLogin(args: string[], io: ApiIo): Promise<number> {
|
|
98
|
+
const parsed = parse(args, ["--no-browser"], ["--api"]);
|
|
99
|
+
if (parsed.error) return refuse(io, parsed.error, "usage: npx vfrey login [--api URL] [--no-browser].");
|
|
100
|
+
try {
|
|
101
|
+
const base = resolve(io, parsed.api);
|
|
102
|
+
if (!base) return notLive(io);
|
|
103
|
+
const host = apiHost(base);
|
|
104
|
+
const api = client(io, base);
|
|
105
|
+
const sleep = io.sleep ?? defaultSleep;
|
|
106
|
+
const now = io.now ?? Date.now;
|
|
107
|
+
|
|
108
|
+
const code = await api.deviceCode();
|
|
109
|
+
const link = browserUrl(code.verification_uri_complete);
|
|
110
|
+
if (!link) return refuse(io, "The server sent a sign-in link that is not a web address.", "check the API address and try again.");
|
|
111
|
+
io.stdout(`Open ${link} and confirm the code ${formatUserCode(code.user_code)}\n`);
|
|
112
|
+
if (!parsed.flags.has("--no-browser") && !io.env.VFREY_NO_BROWSER) {
|
|
113
|
+
try {
|
|
114
|
+
await (io.openUrl ?? defaultOpen)(link);
|
|
115
|
+
} catch {
|
|
116
|
+
/* the link is printed: the person can open it themselves */
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const deadline = now() + (Number.isFinite(code.expires_in) ? code.expires_in : 600) * 1000;
|
|
121
|
+
let intervalSec = Number.isFinite(code.interval) && code.interval >= 0 ? code.interval : 5;
|
|
122
|
+
let networkErrors = 0;
|
|
123
|
+
for (;;) {
|
|
124
|
+
await sleep(intervalSec * 1000);
|
|
125
|
+
if (now() >= deadline) return refuse(io, "The sign-in code expired.", "run `npx vfrey login` again.");
|
|
126
|
+
let answer;
|
|
127
|
+
try {
|
|
128
|
+
answer = await api.deviceToken(code.device_code);
|
|
129
|
+
networkErrors = 0;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (error instanceof ApiFailure && error.status === undefined && (networkErrors += 1) < 3) continue;
|
|
132
|
+
if (error instanceof ApiFailure && error.status === 429) {
|
|
133
|
+
intervalSec += 5;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
if ("access_token" in answer) {
|
|
139
|
+
const org = clean(answer.org.name);
|
|
140
|
+
let plan = "";
|
|
141
|
+
try {
|
|
142
|
+
plan = clean((await client(io, base, answer.access_token).me()).plan);
|
|
143
|
+
} catch {
|
|
144
|
+
/* signed in all the same; the plan shows on whoami */
|
|
145
|
+
}
|
|
146
|
+
let saved;
|
|
147
|
+
try {
|
|
148
|
+
saved = saveToken(host, answer.access_token, { org, plan }, creds(io));
|
|
149
|
+
} catch {
|
|
150
|
+
return refuse(io, "Signed in, but the token could not be saved on this machine.", "make the vfrey home folder writable (VFREY_HOME), then run `npx vfrey login` again.");
|
|
151
|
+
}
|
|
152
|
+
io.stdout(`✓ Signed in to ${org}${plan ? ` (${plan})` : ""}\n`);
|
|
153
|
+
if (saved.where === "file") io.stdout(`Token saved in ${saved.file} (readable only by you).\n`);
|
|
154
|
+
if (io.env.VFREY_TOKEN) io.stderr("Note: VFREY_TOKEN is set in this shell and overrides the token you just saved.\n");
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
if (answer.error === "slow_down") intervalSec += 5;
|
|
158
|
+
else if (answer.error === "access_denied") return refuse(io, "Sign-in was denied in the browser.", "run `npx vfrey login` again and choose Approve.");
|
|
159
|
+
else if (answer.error === "expired_token") return refuse(io, "The sign-in code expired.", "run `npx vfrey login` again.");
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return failure(io, error);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export async function runLogout(args: string[], io: ApiIo): Promise<number> {
|
|
167
|
+
const parsed = parse(args, [], ["--api"]);
|
|
168
|
+
if (parsed.error) return refuse(io, parsed.error, "usage: npx vfrey logout [--api URL].");
|
|
169
|
+
try {
|
|
170
|
+
const base = resolve(io, parsed.api);
|
|
171
|
+
if (!base) {
|
|
172
|
+
io.stdout("✓ Not signed in (vfrey accounts are not live yet).\n");
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
const host = apiHost(base);
|
|
176
|
+
const stored = loadStoredToken(host, creds(io));
|
|
177
|
+
if (!stored) {
|
|
178
|
+
io.stdout(`✓ Not signed in to ${host}.\n`);
|
|
179
|
+
if (io.env.VFREY_TOKEN) io.stderr("Note: VFREY_TOKEN is set in this shell; unset it to stop using that token.\n");
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
await client(io, base, stored.token).revokeCurrentToken();
|
|
184
|
+
} catch (error) {
|
|
185
|
+
// 401 means the server already treats the token as revoked. Anything else leaves it live: say so, still sign out here.
|
|
186
|
+
if (!(error instanceof ApiFailure && error.status === 401)) {
|
|
187
|
+
io.stderr(`! Could not revoke the token on ${host} (${error instanceof ApiFailure ? error.message : "unknown error"}). It stays valid there until you revoke it at ${base}/settings/tokens.\n`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
deleteToken(host, creds(io));
|
|
191
|
+
io.stdout(`✓ Signed out of ${host}\n`);
|
|
192
|
+
if (io.env.VFREY_TOKEN) io.stderr("Note: VFREY_TOKEN is set in this shell; unset it to stop using that token.\n");
|
|
193
|
+
return 0;
|
|
194
|
+
} catch (error) {
|
|
195
|
+
return failure(io, error);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function formatMe(me: MeResponse): string {
|
|
200
|
+
const lines = [
|
|
201
|
+
`✓ Signed in as ${clean(me.user.email)}`,
|
|
202
|
+
`Org: ${clean(me.org.name)} (${clean(me.org.role)})`,
|
|
203
|
+
`Plan: ${clean(me.plan)}`,
|
|
204
|
+
`Entitlements: ${Object.entries(me.entitlements).map(([name, on]) => `${clean(name)} ${on ? "yes" : "no"}`).join(", ")}`,
|
|
205
|
+
];
|
|
206
|
+
if (me.credits) {
|
|
207
|
+
const soon = me.credits.expiringSoon > 0 ? ` (${me.credits.expiringSoon} expiring soon)` : "";
|
|
208
|
+
lines.push(`Credits: ${me.credits.balance}${soon}`);
|
|
209
|
+
}
|
|
210
|
+
const meters = Object.entries(me.usage ?? {});
|
|
211
|
+
if (meters.length > 0) {
|
|
212
|
+
lines.push("Usage this month:");
|
|
213
|
+
for (const [meter, reading] of meters) {
|
|
214
|
+
lines.push(` ${clean(meter)}: ${reading.used} of ${reading.limit ?? "unlimited"}, resets ${clean(reading.resetsAt)}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (me.upgradeUrl) lines.push(`Upgrade or manage: ${clean(me.upgradeUrl)}`);
|
|
218
|
+
return lines.join("\n") + "\n";
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export async function runWhoami(args: string[], io: ApiIo): Promise<number> {
|
|
222
|
+
const parsed = parse(args, ["--json"], ["--api"]);
|
|
223
|
+
if (parsed.error) return refuse(io, parsed.error, "usage: npx vfrey whoami [--json] [--api URL].");
|
|
224
|
+
try {
|
|
225
|
+
const base = resolve(io, parsed.api);
|
|
226
|
+
if (!base) return notLive(io);
|
|
227
|
+
const host = apiHost(base);
|
|
228
|
+
const found = loadToken(host, creds(io));
|
|
229
|
+
if (!found) return refuse(io, "You are not signed in.", "run `npx vfrey login`.");
|
|
230
|
+
const me = await client(io, base, found.token).me();
|
|
231
|
+
if (found.source !== "env") saveHint(host, { org: clean(me.org.name), plan: clean(me.plan) }, creds(io));
|
|
232
|
+
io.stdout(parsed.flags.has("--json") ? JSON.stringify(me, null, 2) + "\n" : formatMe(me));
|
|
233
|
+
return 0;
|
|
234
|
+
} catch (error) {
|
|
235
|
+
return failure(io, error);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const ORG_USAGE = "usage: npx vfrey org list [--json] [--api URL] | npx vfrey org use ORG [--api URL].";
|
|
240
|
+
|
|
241
|
+
/** The org named by an id or an exact name (any case). Null when none match; "many" when a name is not unique. */
|
|
242
|
+
function pickOrg(orgs: OrgSummary[], wanted: string): OrgSummary | null | "many" {
|
|
243
|
+
const byId = orgs.find((o) => o.id === wanted);
|
|
244
|
+
if (byId) return byId;
|
|
245
|
+
const byName = orgs.filter((o) => o.name.toLowerCase() === wanted.toLowerCase());
|
|
246
|
+
return byName.length === 1 ? byName[0]! : byName.length > 1 ? "many" : null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* `vfrey org list` and `vfrey org use ORG` (spec 019 A). A token is bound to one org for life, so `use` asks the server
|
|
251
|
+
* to trade the stored token for one bound to the chosen org (the server checks membership and revokes the old one),
|
|
252
|
+
* then stores the new token. A token from VFREY_TOKEN is never replaced: it stays what the shell says it is.
|
|
253
|
+
*/
|
|
254
|
+
export async function runOrg(args: string[], io: ApiIo): Promise<number> {
|
|
255
|
+
const [sub, ...rest] = args;
|
|
256
|
+
if (sub !== "list" && sub !== "use") return refuse(io, sub ? `Unknown org command "${clean(sub)}".` : "Say what to do with orgs.", ORG_USAGE);
|
|
257
|
+
const positional: string[] = [];
|
|
258
|
+
const flagArgs: string[] = [];
|
|
259
|
+
for (let i = 0; i < rest.length; i += 1) {
|
|
260
|
+
const arg = rest[i]!;
|
|
261
|
+
if (arg.startsWith("--")) {
|
|
262
|
+
flagArgs.push(arg);
|
|
263
|
+
if (arg === "--api" && rest[i + 1] !== undefined) flagArgs.push(rest[(i += 1)]!);
|
|
264
|
+
} else positional.push(arg);
|
|
265
|
+
}
|
|
266
|
+
const parsed = parse(flagArgs, sub === "list" ? ["--json"] : [], ["--api"]);
|
|
267
|
+
if (parsed.error) return refuse(io, parsed.error, ORG_USAGE);
|
|
268
|
+
if (positional.length > (sub === "use" ? 1 : 0)) return refuse(io, `Unexpected "${clean(positional[sub === "use" ? 1 : 0])}".`, ORG_USAGE);
|
|
269
|
+
const wanted = sub === "use" ? positional[0] : undefined;
|
|
270
|
+
if (sub === "use" && !wanted) return refuse(io, "Say which org to use.", "run `npx vfrey org list`, then `npx vfrey org use ORG` with its name or id.");
|
|
271
|
+
try {
|
|
272
|
+
const base = resolve(io, parsed.api);
|
|
273
|
+
if (!base) return notLive(io);
|
|
274
|
+
const host = apiHost(base);
|
|
275
|
+
const found = loadToken(host, creds(io));
|
|
276
|
+
if (!found) return refuse(io, "You are not signed in.", "run `npx vfrey login`.");
|
|
277
|
+
const api = client(io, base, found.token);
|
|
278
|
+
const { orgs } = await api.orgs();
|
|
279
|
+
if (sub === "list") {
|
|
280
|
+
if (parsed.flags.has("--json")) io.stdout(JSON.stringify({ orgs }, null, 2) + "\n");
|
|
281
|
+
else io.stdout(orgs.map((o) => `${o.current ? "*" : " "} ${clean(o.name)} (${clean(o.role)}) ${clean(o.id)}`).join("\n") + "\n");
|
|
282
|
+
return 0;
|
|
283
|
+
}
|
|
284
|
+
const target = pickOrg(orgs, wanted!);
|
|
285
|
+
if (target === "many") return refuse(io, `More than one org is named "${clean(wanted)}".`, "use the id from `npx vfrey org list`.");
|
|
286
|
+
if (!target) return refuse(io, `You are not in an org called "${clean(wanted)}".`, "run `npx vfrey org list` to see yours.");
|
|
287
|
+
if (target.current) {
|
|
288
|
+
io.stdout(`✓ Already using ${clean(target.name)} (${clean(target.role)})\n`);
|
|
289
|
+
return 0;
|
|
290
|
+
}
|
|
291
|
+
if (found.source === "env") return refuse(io, "VFREY_TOKEN is set, and that token is bound to one org.", "unset VFREY_TOKEN, run `npx vfrey login`, then `npx vfrey org use` again.");
|
|
292
|
+
let switched;
|
|
293
|
+
try {
|
|
294
|
+
switched = await api.switchOrg(target.id);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
if (error instanceof ApiFailure && error.status === 403) return refuse(io, "This token is fixed to its org.", `run \`npx vfrey login\` while ${clean(target.name)} is selected in the vfrey console.`);
|
|
297
|
+
throw error;
|
|
298
|
+
}
|
|
299
|
+
let plan = "";
|
|
300
|
+
try {
|
|
301
|
+
plan = clean((await client(io, base, switched.access_token).me()).plan);
|
|
302
|
+
} catch {
|
|
303
|
+
/* switched all the same; the plan shows on whoami */
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
saveToken(host, switched.access_token, { org: clean(switched.org.name), plan }, creds(io));
|
|
307
|
+
} catch {
|
|
308
|
+
return refuse(io, "Switched, but the new token could not be saved on this machine.", "make the vfrey home folder writable (VFREY_HOME), then run `npx vfrey login`.");
|
|
309
|
+
}
|
|
310
|
+
io.stdout(`✓ Now using ${clean(switched.org.name)} (${clean(switched.org.role)})\n`);
|
|
311
|
+
return 0;
|
|
312
|
+
} catch (error) {
|
|
313
|
+
return failure(io, error);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** The doctor line. Local only (no network, no Keychain), and never a failure. */
|
|
318
|
+
export function accountLine(env: Env, homedir: string = os.homedir()): string {
|
|
319
|
+
const none = "not signed in (free features work without it)";
|
|
320
|
+
try {
|
|
321
|
+
const base = resolveApiUrl(env, null);
|
|
322
|
+
if (!base) return none;
|
|
323
|
+
const host = apiHost(base);
|
|
324
|
+
const hint = readHint(host, { env, homedir });
|
|
325
|
+
if (env.VFREY_TOKEN?.trim()) return hint ? `signed in as ${hint.org} (${hint.plan}) with VFREY_TOKEN` : "signed in with VFREY_TOKEN";
|
|
326
|
+
return hint ? `signed in as ${hint.org} (${hint.plan})` : none;
|
|
327
|
+
} catch {
|
|
328
|
+
return none;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Where the vfrey accounts server is. Set DEFAULT_API_URL at release, when the console is deployed.
|
|
2
|
+
|
|
3
|
+
type Env = Record<string, string | undefined>;
|
|
4
|
+
|
|
5
|
+
/** The release-time default. Unset until the server is live: `login` then refuses without any network call. */
|
|
6
|
+
export const DEFAULT_API_URL: string | null = null;
|
|
7
|
+
|
|
8
|
+
export class ApiConfigError extends Error {
|
|
9
|
+
constructor(message: string, readonly fix: string) {
|
|
10
|
+
super(message);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** `--api URL`, else VFREY_API_URL, else the release default. Null means accounts are not live. */
|
|
15
|
+
export function resolveApiUrl(env: Env, flag?: string | null): string | null {
|
|
16
|
+
const raw = (flag ?? env.VFREY_API_URL ?? DEFAULT_API_URL ?? "").trim();
|
|
17
|
+
if (!raw) return null;
|
|
18
|
+
let url: URL;
|
|
19
|
+
try {
|
|
20
|
+
url = new URL(raw);
|
|
21
|
+
} catch {
|
|
22
|
+
throw new ApiConfigError(`"${raw}" is not a URL.`, "pass a full address such as https://vfrey.example.com with --api or VFREY_API_URL.");
|
|
23
|
+
}
|
|
24
|
+
const loopback = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
|
|
25
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback)) {
|
|
26
|
+
throw new ApiConfigError(`${url.origin} is not https. vfrey sends your token only over https (or to this machine).`, "use an https:// address.");
|
|
27
|
+
}
|
|
28
|
+
return url.origin;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The key a token is stored under: the API's host (with port when it has one). */
|
|
32
|
+
export function apiHost(base: string): string {
|
|
33
|
+
return new URL(base).host;
|
|
34
|
+
}
|