Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .opencode/agent/duplicate-pr.md +26 -0
- .opencode/agent/triage.md +43 -0
- .opencode/command/ai-deps.md +24 -0
- .opencode/command/changelog.md +49 -0
- .opencode/command/commit.md +37 -0
- .opencode/command/issues.md +23 -0
- .opencode/command/learn.md +42 -0
- .opencode/command/rmslop.md +15 -0
- .opencode/command/spellcheck.md +5 -0
- .opencode/command/translate.md +14 -0
- .opencode/glossary/README.md +63 -0
- .opencode/glossary/ar.md +28 -0
- .opencode/glossary/br.md +34 -0
- .opencode/glossary/bs.md +33 -0
- .opencode/glossary/da.md +27 -0
- .opencode/glossary/de.md +27 -0
- .opencode/glossary/es.md +27 -0
- .opencode/glossary/fr.md +27 -0
- .opencode/glossary/ja.md +33 -0
- .opencode/glossary/ko.md +27 -0
- .opencode/glossary/no.md +38 -0
- .opencode/glossary/pl.md +27 -0
- .opencode/glossary/ru.md +27 -0
- .opencode/glossary/th.md +34 -0
- .opencode/glossary/tr.md +38 -0
- .opencode/glossary/zh-cn.md +42 -0
- .opencode/glossary/zh-tw.md +42 -0
- .opencode/plugins/smoke-theme.json +223 -0
- .opencode/plugins/tui-smoke.tsx +1019 -0
- .opencode/skills/effect/SKILL.md +38 -0
- .opencode/skills/rtl-aware-development/SKILL.md +63 -0
- .opencode/themes/.gitignore +1 -0
- .opencode/themes/mytheme.json +223 -0
- .opencode/tool/github-pr-search.ts +64 -0
- .opencode/tool/github-triage.ts +60 -0
- artifacts/glm52-rise-video/.gitignore +3 -0
- artifacts/glm52-rise-video/bun.lock +483 -0
- artifacts/glm52-rise-video/out/june-totals.png +0 -0
- artifacts/glm52-rise-video/package.json +24 -0
- artifacts/glm52-rise-video/src/data.ts +156 -0
- artifacts/glm52-rise-video/src/flash.tsx +185 -0
- artifacts/glm52-rise-video/src/index.tsx +36 -0
- artifacts/glm52-rise-video/src/june.tsx +144 -0
- artifacts/glm52-rise-video/src/minimax.tsx +201 -0
- artifacts/glm52-rise-video/src/novel.tsx +135 -0
- artifacts/glm52-rise-video/src/sheep.tsx +139 -0
- artifacts/glm52-rise-video/src/video.tsx +254 -0
- artifacts/glm52-rise-video/sst-env.d.ts +10 -0
- github/script/publish +15 -0
- github/script/release +41 -0
.opencode/agent/duplicate-pr.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
mode: primary
|
| 3 |
+
hidden: true
|
| 4 |
+
model: opencode/claude-haiku-4-5
|
| 5 |
+
color: "#E67E22"
|
| 6 |
+
tools:
|
| 7 |
+
"*": false
|
| 8 |
+
"github-pr-search": true
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
You are a duplicate PR detection agent. When a PR is opened, your job is to search for potentially duplicate or related open PRs.
|
| 12 |
+
|
| 13 |
+
Use the github-pr-search tool to search for PRs that might be addressing the same issue or feature.
|
| 14 |
+
|
| 15 |
+
IMPORTANT: The input will contain a line `CURRENT_PR_NUMBER: NNNN`. This is the current PR number, you should not mark that the current PR as a duplicate of itself.
|
| 16 |
+
|
| 17 |
+
Search using keywords from the PR title and description. Try multiple searches with different relevant terms.
|
| 18 |
+
|
| 19 |
+
If you find potential duplicates:
|
| 20 |
+
|
| 21 |
+
- List them with their titles and URLs
|
| 22 |
+
- Briefly explain why they might be related
|
| 23 |
+
|
| 24 |
+
If no duplicates are found, say so clearly. BUT ONLY SAY "No duplicate PRs found" (don't say anything else if no dups)
|
| 25 |
+
|
| 26 |
+
Keep your response concise and actionable.
|
.opencode/agent/triage.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
mode: primary
|
| 3 |
+
hidden: true
|
| 4 |
+
model: opencode/gpt-5.4-mini
|
| 5 |
+
color: "#44BA81"
|
| 6 |
+
tools:
|
| 7 |
+
"*": false
|
| 8 |
+
"github-triage": true
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
You are a triage agent responsible for triaging github issues.
|
| 12 |
+
|
| 13 |
+
Use your github-triage tool to triage issues.
|
| 14 |
+
|
| 15 |
+
This file is the source of truth for ownership/routing rules.
|
| 16 |
+
|
| 17 |
+
Assign issues by choosing the team with the strongest overlap. The github-triage tool will assign a random member from that team.
|
| 18 |
+
|
| 19 |
+
Do not add labels to issues. Only assign an owner.
|
| 20 |
+
|
| 21 |
+
When calling github-triage, pass one of these team values: tui, desktop_web, core, inference, windows.
|
| 22 |
+
|
| 23 |
+
## Teams
|
| 24 |
+
|
| 25 |
+
### TUI
|
| 26 |
+
|
| 27 |
+
Terminal UI issues, including rendering, keybindings, scrolling, terminal compatibility, SSH behavior, crashes in the TUI, and low-level TUI performance.
|
| 28 |
+
|
| 29 |
+
### Desktop / Web
|
| 30 |
+
|
| 31 |
+
Desktop application and browser-based app issues, including `opencode web`, desktop-specific UI behavior, packaging, and web view problems.
|
| 32 |
+
|
| 33 |
+
### Core
|
| 34 |
+
|
| 35 |
+
Core opencode server and harness issues, including sqlite, snapshots, memory, API behavior, agent context construction, tool execution, provider integrations, model behavior, documentation, and larger architectural features.
|
| 36 |
+
|
| 37 |
+
### Inference
|
| 38 |
+
|
| 39 |
+
OpenCode Zen, OpenCode Go, and billing issues.
|
| 40 |
+
|
| 41 |
+
### Windows
|
| 42 |
+
|
| 43 |
+
Windows-specific issues, including native Windows behavior, WSL interactions, path handling, shell compatibility, and installation or runtime problems that only happen on Windows.
|
.opencode/command/ai-deps.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
description: "Bump AI sdk dependencies minor / patch versions only"
|
| 3 |
+
---
|
| 4 |
+
|
| 5 |
+
Please read @package.json and @packages/opencode/package.json.
|
| 6 |
+
|
| 7 |
+
Your job is to look into AI SDK dependencies, figure out if they have versions that can be upgraded (minor or patch versions ONLY no major ignore major changes).
|
| 8 |
+
|
| 9 |
+
I want a report of every dependency and the version that can be upgraded to.
|
| 10 |
+
What would be even better is if you can give me brief summary of the changes for each dep and a link to the changelog for each dependency, or at least some reference info so I can see what bugs were fixed or new features were added.
|
| 11 |
+
|
| 12 |
+
Consider using subagents for each dep to save your context window.
|
| 13 |
+
|
| 14 |
+
Here is a short list of some deps (please be comprehensive tho):
|
| 15 |
+
|
| 16 |
+
- "ai"
|
| 17 |
+
- "@ai-sdk/openai"
|
| 18 |
+
- "@ai-sdk/anthropic"
|
| 19 |
+
- "@openrouter/ai-sdk-provider"
|
| 20 |
+
- etc, etc
|
| 21 |
+
|
| 22 |
+
DO NOT upgrade the dependencies yet, just make a list of all dependencies and their versions that can be upgraded to minor or patch versions only.
|
| 23 |
+
|
| 24 |
+
Write up your findings to ai-sdk-updates.md
|
.opencode/command/changelog.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
model: opencode/gpt-5.4
|
| 3 |
+
---
|
| 4 |
+
|
| 5 |
+
Create `UPCOMING_CHANGELOG.md` from the structured changelog input below.
|
| 6 |
+
If `UPCOMING_CHANGELOG.md` already exists, ignore its current contents completely.
|
| 7 |
+
Do not preserve, merge, or reuse text from the existing file.
|
| 8 |
+
|
| 9 |
+
The input already contains the exact commit range since the last non-draft release.
|
| 10 |
+
The commits are already filtered to the release-relevant packages and grouped into
|
| 11 |
+
the release sections. Do not fetch GitHub releases, PRs, or build your own commit list.
|
| 12 |
+
The input may also include a `## Community Contributors Input` section.
|
| 13 |
+
|
| 14 |
+
Before writing any entry you keep, inspect the real diff with
|
| 15 |
+
`git show --stat --format='' <hash>` or `git show --format='' <hash>` so you can
|
| 16 |
+
understand the actual code changes and not just the commit message (they may be misleading).
|
| 17 |
+
Do not use `git log` or author metadata when deciding attribution.
|
| 18 |
+
|
| 19 |
+
Rules:
|
| 20 |
+
|
| 21 |
+
- Write the final file with release sections in this order:
|
| 22 |
+
`## Core`, `## TUI`, `## Desktop`, `## SDK`, `## Extensions`
|
| 23 |
+
- Only include sections that have at least one notable entry
|
| 24 |
+
- Within each release section, keep bug fixes grouped under `### Bugfixes`
|
| 25 |
+
- Keep other notable entries under `### Improvements` when a section has bug fixes too
|
| 26 |
+
- Omit empty subsections
|
| 27 |
+
- Keep one bullet per commit you keep
|
| 28 |
+
- Skip commits that are entirely internal, CI, tests, refactors, or otherwise not user-facing
|
| 29 |
+
- Start each bullet with a capital letter
|
| 30 |
+
- Prefer what changed for users over what code changed internally
|
| 31 |
+
- Do not copy raw commit prefixes like `fix:` or `feat:` or trailing PR numbers like `(#123)`
|
| 32 |
+
- Community attribution is deterministic: only preserve an existing `(@username)` suffix from the changelog input
|
| 33 |
+
- If an input bullet has no `(@username)` suffix, do not add one
|
| 34 |
+
- Never add a new `(@username)` suffix from `git show`, commit authors, names, or email addresses
|
| 35 |
+
- If no notable entries remain and there is no contributor block, write exactly `No notable changes.`
|
| 36 |
+
- If no notable entries remain but there is a contributor block, omit all release sections and return only the contributor block
|
| 37 |
+
- If the input contains `## Community Contributors Input`, append the block below that heading to the end of the final file verbatim
|
| 38 |
+
- Do not add, remove, rewrite, or reorder contributor names or commit titles in that block
|
| 39 |
+
- Do not derive the thank-you section from the main summary bullets
|
| 40 |
+
- Do not include the heading `## Community Contributors Input` in the final file
|
| 41 |
+
- Focus on writing the least words to get your point across - users will skim read the changelog, so we should be precise
|
| 42 |
+
|
| 43 |
+
**Importantly, the changelog is for users (who are at least slightly technical), they may use the TUI, Desktop, SDK, Plugins and so forth. Be thorough in understanding flow on effects may not be immediately apparent. e.g. a package upgrade looks internal but may patch a bug. Or a refactor may also stabilise some race condition that fixes bugs for users. The PR title/body + commit message will give you the authors context, usually containing the outcome not just technical detail**
|
| 44 |
+
|
| 45 |
+
<changelog_input>
|
| 46 |
+
|
| 47 |
+
!`bun script/raw-changelog.ts $ARGUMENTS`
|
| 48 |
+
|
| 49 |
+
</changelog_input>
|
.opencode/command/commit.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
description: git commit and push
|
| 3 |
+
model: opencode/kimi-k2.5
|
| 4 |
+
subtask: true
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
commit and push
|
| 8 |
+
|
| 9 |
+
make sure it includes a prefix like
|
| 10 |
+
docs:
|
| 11 |
+
tui:
|
| 12 |
+
core:
|
| 13 |
+
ci:
|
| 14 |
+
ignore:
|
| 15 |
+
wip:
|
| 16 |
+
|
| 17 |
+
For anything in the packages/web use the docs: prefix.
|
| 18 |
+
|
| 19 |
+
prefer to explain WHY something was done from an end user perspective instead of
|
| 20 |
+
WHAT was done.
|
| 21 |
+
|
| 22 |
+
do not do generic messages like "improved agent experience" be very specific
|
| 23 |
+
about what user facing changes were made
|
| 24 |
+
|
| 25 |
+
if there are conflicts DO NOT FIX THEM. notify me and I will fix them
|
| 26 |
+
|
| 27 |
+
## GIT DIFF
|
| 28 |
+
|
| 29 |
+
!`git diff`
|
| 30 |
+
|
| 31 |
+
## GIT DIFF --cached
|
| 32 |
+
|
| 33 |
+
!`git diff --cached`
|
| 34 |
+
|
| 35 |
+
## GIT STATUS --short
|
| 36 |
+
|
| 37 |
+
!`git status --short`
|
.opencode/command/issues.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
description: "find issue(s) on github"
|
| 3 |
+
model: opencode/claude-haiku-4-5
|
| 4 |
+
---
|
| 5 |
+
|
| 6 |
+
Search through existing issues in anomalyco/opencode using the gh cli to find issues matching this query:
|
| 7 |
+
|
| 8 |
+
$ARGUMENTS
|
| 9 |
+
|
| 10 |
+
Consider:
|
| 11 |
+
|
| 12 |
+
1. Similar titles or descriptions
|
| 13 |
+
2. Same error messages or symptoms
|
| 14 |
+
3. Related functionality or components
|
| 15 |
+
4. Similar feature requests
|
| 16 |
+
|
| 17 |
+
Please list any matching issues with:
|
| 18 |
+
|
| 19 |
+
- Issue number and title
|
| 20 |
+
- Brief explanation of why it matches the query
|
| 21 |
+
- Link to the issue
|
| 22 |
+
|
| 23 |
+
If no clear matches are found, say so.
|
.opencode/command/learn.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
description: Extract non-obvious learnings from session to AGENTS.md files to build codebase understanding
|
| 3 |
+
---
|
| 4 |
+
|
| 5 |
+
Analyze this session and extract non-obvious learnings to add to AGENTS.md files.
|
| 6 |
+
|
| 7 |
+
AGENTS.md files can exist at any directory level, not just the project root. When an agent reads a file, any AGENTS.md in parent directories are automatically loaded into the context of the tool read. Place learnings as close to the relevant code as possible:
|
| 8 |
+
|
| 9 |
+
- Project-wide learnings → root AGENTS.md
|
| 10 |
+
- Package/module-specific → packages/foo/AGENTS.md
|
| 11 |
+
- Feature-specific → src/auth/AGENTS.md
|
| 12 |
+
|
| 13 |
+
What counts as a learning (non-obvious discoveries only):
|
| 14 |
+
|
| 15 |
+
- Hidden relationships between files or modules
|
| 16 |
+
- Execution paths that differ from how code appears
|
| 17 |
+
- Non-obvious configuration, env vars, or flags
|
| 18 |
+
- Debugging breakthroughs when error messages were misleading
|
| 19 |
+
- API/tool quirks and workarounds
|
| 20 |
+
- Build/test commands not in README
|
| 21 |
+
- Architectural decisions and constraints
|
| 22 |
+
- Files that must change together
|
| 23 |
+
|
| 24 |
+
What NOT to include:
|
| 25 |
+
|
| 26 |
+
- Obvious facts from documentation
|
| 27 |
+
- Standard language/framework behavior
|
| 28 |
+
- Things already in an AGENTS.md
|
| 29 |
+
- Verbose explanations
|
| 30 |
+
- Session-specific details
|
| 31 |
+
|
| 32 |
+
Process:
|
| 33 |
+
|
| 34 |
+
1. Review session for discoveries, errors that took multiple attempts, unexpected connections
|
| 35 |
+
2. Determine scope - what directory does each learning apply to?
|
| 36 |
+
3. Read existing AGENTS.md files at relevant levels
|
| 37 |
+
4. Create or update AGENTS.md at the appropriate level
|
| 38 |
+
5. Keep entries to 1-3 lines per insight
|
| 39 |
+
|
| 40 |
+
After updating, summarize which AGENTS.md files were created/updated and how many learnings per file.
|
| 41 |
+
|
| 42 |
+
$ARGUMENTS
|
.opencode/command/rmslop.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
description: Remove AI code slop
|
| 3 |
+
---
|
| 4 |
+
|
| 5 |
+
Check the diff against dev, and remove all AI generated slop introduced in this branch.
|
| 6 |
+
|
| 7 |
+
This includes:
|
| 8 |
+
|
| 9 |
+
- Extra comments that a human wouldn't add or is inconsistent with the rest of the file
|
| 10 |
+
- Extra defensive checks or try/catch blocks that are abnormal for that area of the codebase (especially if called by trusted / validated codepaths)
|
| 11 |
+
- Casts to any to get around type issues
|
| 12 |
+
- Any other style that is inconsistent with the file
|
| 13 |
+
- Unnecessary emoji usage
|
| 14 |
+
|
| 15 |
+
Report at the end with only a 1-3 sentence summary of what you changed
|
.opencode/command/spellcheck.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
description: spellcheck all markdown file changes
|
| 3 |
+
---
|
| 4 |
+
|
| 5 |
+
Look at all the unstaged changes to markdown (.md, .mdx) files, pull out the lines that have changed, and check for spelling and grammar errors.
|
.opencode/command/translate.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
description: translate English to other languages
|
| 3 |
+
model: opencode/gpt-5.6-sol
|
| 4 |
+
---
|
| 5 |
+
|
| 6 |
+
run git diff and translate changed english doc and UI copy files to other international languages. Translate all languages in parallel to save time.
|
| 7 |
+
|
| 8 |
+
Requirements:
|
| 9 |
+
|
| 10 |
+
- Preserve meaning, intent, tone, and formatting (including Markdown/MDX structure).
|
| 11 |
+
- Preserve all technical terms and artifacts exactly: product/company names, API names, identifiers, code, commands/flags, file paths, URLs, versions, error messages, config keys/values, and anything inside inline code or code blocks.
|
| 12 |
+
- Also preserve every term listed in the Do-Not-Translate glossary below.
|
| 13 |
+
- Also apply locale-specific guidance from `.opencode/glossary/<locale>.md` when available (for example, `zh-cn.md`).
|
| 14 |
+
- Do not modify fenced code blocks.
|
.opencode/glossary/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Locale Glossaries
|
| 2 |
+
|
| 3 |
+
Use this folder for locale-specific translation guidance that supplements `.opencode/agent/translator.md`.
|
| 4 |
+
|
| 5 |
+
The global glossary in `translator.md` remains the source of truth for shared do-not-translate terms (commands, code, paths, product names, etc.). These locale files capture community learnings about phrasing and terminology preferences.
|
| 6 |
+
|
| 7 |
+
## File Naming
|
| 8 |
+
|
| 9 |
+
- One file per locale
|
| 10 |
+
- Use lowercase locale slugs that match docs locales when possible (for example, `zh-cn.md`, `zh-tw.md`)
|
| 11 |
+
- If only language-level guidance exists, use the language code (for example, `fr.md`)
|
| 12 |
+
- Some repo locale slugs may be aliases/non-BCP47 for consistency (for example, `br` for Brazilian Portuguese / `pt-BR`)
|
| 13 |
+
|
| 14 |
+
## What To Put In A Locale File
|
| 15 |
+
|
| 16 |
+
- **Sources**: PRs/issues/discussions that motivated the guidance
|
| 17 |
+
- **Do Not Translate (Locale Additions)**: locale-specific terms or casing decisions
|
| 18 |
+
- **Preferred Terms**: recurring UI/docs words with preferred translations
|
| 19 |
+
- **Guidance**: tone, style, and consistency notes
|
| 20 |
+
- **Avoid** (optional): common literal translations or wording we should avoid
|
| 21 |
+
- If the repo uses a locale alias slug, document the alias in **Guidance** (for example, prose may mention `pt-BR` while config/examples use `br`)
|
| 22 |
+
|
| 23 |
+
Prefer guidance that is:
|
| 24 |
+
|
| 25 |
+
- Repeated across multiple docs/screens
|
| 26 |
+
- Easy to apply consistently
|
| 27 |
+
- Backed by a community contribution or review discussion
|
| 28 |
+
|
| 29 |
+
## Template
|
| 30 |
+
|
| 31 |
+
```md
|
| 32 |
+
# <locale> Glossary
|
| 33 |
+
|
| 34 |
+
## Sources
|
| 35 |
+
|
| 36 |
+
- PR #12345: https://github.com/anomalyco/opencode/pull/12345
|
| 37 |
+
|
| 38 |
+
## Do Not Translate (Locale Additions)
|
| 39 |
+
|
| 40 |
+
- `OpenCode` (preserve casing)
|
| 41 |
+
|
| 42 |
+
## Preferred Terms
|
| 43 |
+
|
| 44 |
+
| English | Preferred | Notes |
|
| 45 |
+
| ------- | --------- | --------- |
|
| 46 |
+
| prompt | ... | preferred |
|
| 47 |
+
| session | ... | preferred |
|
| 48 |
+
|
| 49 |
+
## Guidance
|
| 50 |
+
|
| 51 |
+
- Prefer natural phrasing over literal translation
|
| 52 |
+
|
| 53 |
+
## Avoid
|
| 54 |
+
|
| 55 |
+
- Avoid ... when ...
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
## Contribution Notes
|
| 59 |
+
|
| 60 |
+
- Mark entries as preferred when they may evolve
|
| 61 |
+
- Keep examples short
|
| 62 |
+
- Add or update the `Sources` section whenever you add a new rule
|
| 63 |
+
- Prefer PR-backed guidance over invented term mappings; start with general guidance if no term-level corrections exist yet
|
.opencode/glossary/ar.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ar Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9947: https://github.com/anomalyco/opencode/pull/9947
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural Arabic phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
- For RTL text, treat code, commands, and paths as LTR artifacts and keep their character order unchanged
|
| 24 |
+
|
| 25 |
+
## Avoid
|
| 26 |
+
|
| 27 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 28 |
+
- Avoid mixing multiple Arabic terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/br.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# br Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #10086: https://github.com/anomalyco/opencode/pull/10086
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Locale code `br` in repo config, code, and paths (repo alias for Brazilian Portuguese)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
These are PR-backed locale naming preferences and may evolve.
|
| 17 |
+
|
| 18 |
+
| English / Context | Preferred | Notes |
|
| 19 |
+
| ---------------------------------------- | ------------------------------ | ------------------------------------------------------------- |
|
| 20 |
+
| Brazilian Portuguese (prose locale name) | `pt-BR` | Use standard locale naming in prose when helpful |
|
| 21 |
+
| Repo locale slug (code/config) | `br` | PR #10086 uses `br` for consistency/simplicity |
|
| 22 |
+
| Browser locale detection | `pt`, `pt-br`, `pt-BR` -> `br` | Preserve this mapping in docs/examples about locale detection |
|
| 23 |
+
|
| 24 |
+
## Guidance
|
| 25 |
+
|
| 26 |
+
- This file covers Brazilian Portuguese (`pt-BR`), but the repo locale code is `br`
|
| 27 |
+
- Use natural Brazilian Portuguese phrasing over literal translation
|
| 28 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 29 |
+
- Keep repo locale identifiers as implemented in code/config (`br`) even when prose mentions `pt-BR`
|
| 30 |
+
|
| 31 |
+
## Avoid
|
| 32 |
+
|
| 33 |
+
- Avoid changing repo locale code references from `br` to `pt-br` in code snippets, paths, or config examples
|
| 34 |
+
- Avoid mixing Portuguese variants when a Brazilian Portuguese form is established
|
.opencode/glossary/bs.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# bs Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #12283: https://github.com/anomalyco/opencode/pull/12283
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
These are PR-backed locale naming preferences and may evolve.
|
| 17 |
+
|
| 18 |
+
| English / Context | Preferred | Notes |
|
| 19 |
+
| ---------------------------------- | ---------- | ------------------------------------------------- |
|
| 20 |
+
| Bosnian language label (UI) | `Bosanski` | PR #12283 tested switching language to `Bosanski` |
|
| 21 |
+
| Repo locale slug (code/config) | `bs` | Preserve in code, config, paths, and examples |
|
| 22 |
+
| Browser locale detection (Bosnian) | `bs` | PR #12283 added `bs` locale auto-detection |
|
| 23 |
+
|
| 24 |
+
## Guidance
|
| 25 |
+
|
| 26 |
+
- Use natural Bosnian phrasing over literal translation
|
| 27 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 28 |
+
- Keep repo locale references as `bs` in code/config, and use `Bosanski` for the user-facing language name when applicable
|
| 29 |
+
|
| 30 |
+
## Avoid
|
| 31 |
+
|
| 32 |
+
- Avoid changing repo locale references from `bs` to another slug in code snippets or config examples
|
| 33 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
.opencode/glossary/da.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# da Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9821: https://github.com/anomalyco/opencode/pull/9821
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural Danish phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
|
| 24 |
+
## Avoid
|
| 25 |
+
|
| 26 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 27 |
+
- Avoid mixing multiple Danish terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/de.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# de Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9817: https://github.com/anomalyco/opencode/pull/9817
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural German phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
|
| 24 |
+
## Avoid
|
| 25 |
+
|
| 26 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 27 |
+
- Avoid mixing multiple German terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/es.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# es Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9817: https://github.com/anomalyco/opencode/pull/9817
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural Spanish phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
|
| 24 |
+
## Avoid
|
| 25 |
+
|
| 26 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 27 |
+
- Avoid mixing multiple Spanish terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/fr.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# fr Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9821: https://github.com/anomalyco/opencode/pull/9821
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural French phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
|
| 24 |
+
## Avoid
|
| 25 |
+
|
| 26 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 27 |
+
- Avoid mixing multiple French terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/ja.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ja Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9821: https://github.com/anomalyco/opencode/pull/9821
|
| 6 |
+
- PR #13160: https://github.com/anomalyco/opencode/pull/13160
|
| 7 |
+
|
| 8 |
+
## Do Not Translate (Locale Additions)
|
| 9 |
+
|
| 10 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 11 |
+
- `OpenCode CLI`
|
| 12 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 13 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 14 |
+
|
| 15 |
+
## Preferred Terms
|
| 16 |
+
|
| 17 |
+
These are PR-backed wording preferences and may evolve.
|
| 18 |
+
|
| 19 |
+
| English / Context | Preferred | Notes |
|
| 20 |
+
| --------------------------- | ----------------------- | ------------------------------------- |
|
| 21 |
+
| WSL integration (UI label) | `WSL連携` | PR #13160 prefers this over `WSL統合` |
|
| 22 |
+
| WSL integration description | `WindowsのWSL環境で...` | PR #13160 improved phrasing naturally |
|
| 23 |
+
|
| 24 |
+
## Guidance
|
| 25 |
+
|
| 26 |
+
- Prefer natural Japanese phrasing over literal translation
|
| 27 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 28 |
+
- In WSL integration text, follow PR #13160 wording direction for more natural Japanese phrasing
|
| 29 |
+
|
| 30 |
+
## Avoid
|
| 31 |
+
|
| 32 |
+
- Avoid `WSL統合` in the WSL integration UI context where `WSL連携` is the reviewed wording
|
| 33 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
.opencode/glossary/ko.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ko Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9817: https://github.com/anomalyco/opencode/pull/9817
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural Korean phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
|
| 24 |
+
## Avoid
|
| 25 |
+
|
| 26 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 27 |
+
- Avoid mixing multiple Korean terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/no.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# no Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #10018: https://github.com/anomalyco/opencode/pull/10018
|
| 6 |
+
- PR #12935: https://github.com/anomalyco/opencode/pull/12935
|
| 7 |
+
|
| 8 |
+
## Do Not Translate (Locale Additions)
|
| 9 |
+
|
| 10 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 11 |
+
- `OpenCode CLI`
|
| 12 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 13 |
+
- Sound names (PR #10018 notes these were intentionally left untranslated)
|
| 14 |
+
|
| 15 |
+
## Preferred Terms
|
| 16 |
+
|
| 17 |
+
These are PR-backed corrections and may evolve.
|
| 18 |
+
|
| 19 |
+
| English / Context | Preferred | Notes |
|
| 20 |
+
| ----------------------------------- | ------------ | ----------------------------- |
|
| 21 |
+
| Save (data persistence action) | `Lagre` | Prefer over `Spare` |
|
| 22 |
+
| Disabled (feature/state) | `deaktivert` | Prefer over `funksjonshemmet` |
|
| 23 |
+
| API keys | `API Nøkler` | Prefer over `API Taster` |
|
| 24 |
+
| Cost (noun) | `Kostnad` | Prefer over verb form `Koste` |
|
| 25 |
+
| Show/View (imperative button label) | `Vis` | Prefer over `Utsikt` |
|
| 26 |
+
|
| 27 |
+
## Guidance
|
| 28 |
+
|
| 29 |
+
- Prefer natural Norwegian Bokmal (Bokmål) wording over literal translation
|
| 30 |
+
- Keep tone clear and practical in UI labels
|
| 31 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 32 |
+
- Keep recurring UI terms consistent once a preferred term is chosen
|
| 33 |
+
|
| 34 |
+
## Avoid
|
| 35 |
+
|
| 36 |
+
- Avoid `Spare` for save actions in persistence contexts
|
| 37 |
+
- Avoid `funksjonshemmet` for disabled feature states
|
| 38 |
+
- Avoid `API Taster`, `Koste`, and `Utsikt` in the corrected contexts above
|
.opencode/glossary/pl.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# pl Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9884: https://github.com/anomalyco/opencode/pull/9884
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural Polish phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
|
| 24 |
+
## Avoid
|
| 25 |
+
|
| 26 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 27 |
+
- Avoid mixing multiple Polish terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/ru.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ru Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #9882: https://github.com/anomalyco/opencode/pull/9882
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode CLI`
|
| 11 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
No PR-backed term mappings yet. Add entries here when review PRs introduce repeated wording corrections.
|
| 17 |
+
|
| 18 |
+
## Guidance
|
| 19 |
+
|
| 20 |
+
- Prefer natural Russian phrasing over literal translation
|
| 21 |
+
- Keep tone clear and direct in UI labels and docs prose
|
| 22 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 23 |
+
|
| 24 |
+
## Avoid
|
| 25 |
+
|
| 26 |
+
- Avoid translating product and protocol names that are fixed identifiers
|
| 27 |
+
- Avoid mixing multiple Russian terms for the same recurring UI action once a preferred term is established
|
.opencode/glossary/th.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# th Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #10809: https://github.com/anomalyco/opencode/pull/10809
|
| 6 |
+
- PR #11496: https://github.com/anomalyco/opencode/pull/11496
|
| 7 |
+
|
| 8 |
+
## Do Not Translate (Locale Additions)
|
| 9 |
+
|
| 10 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only in commands, package names, paths, or code)
|
| 11 |
+
- `OpenCode CLI`
|
| 12 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 13 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 14 |
+
|
| 15 |
+
## Preferred Terms
|
| 16 |
+
|
| 17 |
+
These are PR-backed preferences and may evolve.
|
| 18 |
+
|
| 19 |
+
| English / Context | Preferred | Notes |
|
| 20 |
+
| ------------------------------------- | --------------------- | -------------------------------------------------------------------------------- |
|
| 21 |
+
| Thai language label in language lists | `ไทย` | PR #10809 standardized this across locales |
|
| 22 |
+
| Language names in language pickers | Native names (static) | PR #11496: keep names like `English`, `Deutsch`, `ไทย` consistent across locales |
|
| 23 |
+
|
| 24 |
+
## Guidance
|
| 25 |
+
|
| 26 |
+
- Prefer natural Thai phrasing over literal translation
|
| 27 |
+
- Keep tone short and clear for buttons and labels
|
| 28 |
+
- Preserve technical artifacts exactly: commands, flags, code, URLs, model IDs, and file paths
|
| 29 |
+
- Keep language names static/native in language pickers instead of translating them per current locale (PR #11496)
|
| 30 |
+
|
| 31 |
+
## Avoid
|
| 32 |
+
|
| 33 |
+
- Avoid translating language names differently per current locale in language lists
|
| 34 |
+
- Avoid changing `ไทย` to another display form for the Thai language option unless the product standard changes
|
.opencode/glossary/tr.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# tr Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #15835: https://github.com/anomalyco/opencode/pull/15835
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose, docs, and UI copy)
|
| 10 |
+
- Keep lowercase `opencode` in commands, package names, paths, URLs, and other exact identifiers
|
| 11 |
+
- `<TAB>` stays the literal key token in code blocks; use `Tab` for the nearby explanatory label in prose
|
| 12 |
+
- Commands, flags, file paths, and code literals (keep exactly as written)
|
| 13 |
+
|
| 14 |
+
## Preferred Terms
|
| 15 |
+
|
| 16 |
+
These are PR-backed wording preferences and may evolve.
|
| 17 |
+
|
| 18 |
+
| English / Context | Preferred | Notes |
|
| 19 |
+
| ------------------------- | --------------------------------------- | ------------------------------------------------------------- |
|
| 20 |
+
| available in beta | `beta olarak mevcut` | Prefer this over `beta olarak kullanılabilir` |
|
| 21 |
+
| privacy-first | `Gizlilik öncelikli tasarlandı` | Prefer this over `Önce gizlilik için tasarlandı` |
|
| 22 |
+
| connect your local models | `yerel modellerinizi bağlayabilirsiniz` | Use the fuller, more direct action phrase |
|
| 23 |
+
| `<TAB>` key label | `Tab` | Use `Tab` in prose; keep `<TAB>` in literal UI or code blocks |
|
| 24 |
+
| cross-platform | `cross-platform (tüm platformlarda)` | Keep the English term, add a short clarification when helpful |
|
| 25 |
+
|
| 26 |
+
## Guidance
|
| 27 |
+
|
| 28 |
+
- Prefer natural Turkish phrasing over literal translation
|
| 29 |
+
- Merge broken sentence fragments into one clear sentence when the source is a single thought
|
| 30 |
+
- Keep product naming consistent: `OpenCode` in prose, `opencode` only for exact technical identifiers
|
| 31 |
+
- When an English technical term is intentionally kept, add a short Turkish clarification only if it improves readability
|
| 32 |
+
|
| 33 |
+
## Avoid
|
| 34 |
+
|
| 35 |
+
- Avoid `beta olarak kullanılabilir` when `beta olarak mevcut` fits
|
| 36 |
+
- Avoid `Önce gizlilik için tasarlandı`; use the more natural reviewed wording instead
|
| 37 |
+
- Avoid `Sekme` for the translated key label in prose when referring to `<TAB>`
|
| 38 |
+
- Avoid changing `opencode` to `OpenCode` inside commands, URLs, package names, or code literals
|
.opencode/glossary/zh-cn.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# zh-cn Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #13942: https://github.com/anomalyco/opencode/pull/13942
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only when it is part of commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode Zen`
|
| 11 |
+
- `OpenCode CLI`
|
| 12 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 13 |
+
- `Model Context Protocol` (prefer the English expansion when introducing `MCP`)
|
| 14 |
+
|
| 15 |
+
## Preferred Terms
|
| 16 |
+
|
| 17 |
+
These are preferred terms for docs/UI prose and may evolve.
|
| 18 |
+
|
| 19 |
+
| English | Preferred | Notes |
|
| 20 |
+
| ----------------------- | --------- | ------------------------------------------- |
|
| 21 |
+
| prompt | 提示词 | Keep `--prompt` unchanged in flags/code |
|
| 22 |
+
| session | 会话 | |
|
| 23 |
+
| provider | 提供商 | |
|
| 24 |
+
| share link / shared URL | 分享链接 | Prefer `分享` for user-facing share actions |
|
| 25 |
+
| headless (server) | 无界面 | Docs wording |
|
| 26 |
+
| authentication | 认证 | Prefer in auth/OAuth contexts |
|
| 27 |
+
| cache | 缓存 | |
|
| 28 |
+
| keybind / shortcut | 快捷键 | User-facing docs wording |
|
| 29 |
+
| workflow | 工作流 | e.g. GitHub Actions workflow |
|
| 30 |
+
|
| 31 |
+
## Guidance
|
| 32 |
+
|
| 33 |
+
- Prefer natural, concise phrasing over literal translation
|
| 34 |
+
- Keep the tone direct and friendly (PR #13942 consistently moved wording in this direction)
|
| 35 |
+
- Preserve technical artifacts exactly: commands, flags, code, inline code, URLs, file paths, model IDs
|
| 36 |
+
- Keep enum-like values in English when they are literals (for example, `default`, `json`)
|
| 37 |
+
- Prefer consistent terminology across pages once a term is chosen (`会话`, `提供商`, `提示词`, etc.)
|
| 38 |
+
|
| 39 |
+
## Avoid
|
| 40 |
+
|
| 41 |
+
- Avoid `opencode` in prose when referring to the product name; use `OpenCode`
|
| 42 |
+
- Avoid mixing alternative terms for the same concept across docs when a preferred term is already established
|
.opencode/glossary/zh-tw.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# zh-tw Glossary
|
| 2 |
+
|
| 3 |
+
## Sources
|
| 4 |
+
|
| 5 |
+
- PR #13942: https://github.com/anomalyco/opencode/pull/13942
|
| 6 |
+
|
| 7 |
+
## Do Not Translate (Locale Additions)
|
| 8 |
+
|
| 9 |
+
- `OpenCode` (preserve casing in prose; keep `opencode` only when it is part of commands, package names, paths, or code)
|
| 10 |
+
- `OpenCode Zen`
|
| 11 |
+
- `OpenCode CLI`
|
| 12 |
+
- `CLI`, `TUI`, `MCP`, `OAuth`
|
| 13 |
+
- `Model Context Protocol` (prefer the English expansion when introducing `MCP`)
|
| 14 |
+
|
| 15 |
+
## Preferred Terms
|
| 16 |
+
|
| 17 |
+
These are preferred terms for docs/UI prose and may evolve.
|
| 18 |
+
|
| 19 |
+
| English | Preferred | Notes |
|
| 20 |
+
| ----------------------- | --------- | ------------------------------------------- |
|
| 21 |
+
| prompt | 提示詞 | Keep `--prompt` unchanged in flags/code |
|
| 22 |
+
| session | 工作階段 | |
|
| 23 |
+
| provider | 供應商 | |
|
| 24 |
+
| share link / shared URL | 分享連結 | Prefer `分享` for user-facing share actions |
|
| 25 |
+
| headless (server) | 無介面 | Docs wording |
|
| 26 |
+
| authentication | 認證 | Prefer in auth/OAuth contexts |
|
| 27 |
+
| cache | 快取 | |
|
| 28 |
+
| keybind / shortcut | 快捷鍵 | User-facing docs wording |
|
| 29 |
+
| workflow | 工作流程 | e.g. GitHub Actions workflow |
|
| 30 |
+
|
| 31 |
+
## Guidance
|
| 32 |
+
|
| 33 |
+
- Prefer natural, concise phrasing over literal translation
|
| 34 |
+
- Keep the tone direct and friendly (PR #13942 consistently moved wording in this direction)
|
| 35 |
+
- Preserve technical artifacts exactly: commands, flags, code, inline code, URLs, file paths, model IDs
|
| 36 |
+
- Keep enum-like values in English when they are literals (for example, `default`, `json`)
|
| 37 |
+
- Prefer consistent terminology across pages once a term is chosen (`工作階段`, `供應商`, `提示詞`, etc.)
|
| 38 |
+
|
| 39 |
+
## Avoid
|
| 40 |
+
|
| 41 |
+
- Avoid `opencode` in prose when referring to the product name; use `OpenCode`
|
| 42 |
+
- Avoid mixing alternative terms for the same concept across docs when a preferred term is already established
|
.opencode/plugins/smoke-theme.json
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://opencode.ai/theme.json",
|
| 3 |
+
"defs": {
|
| 4 |
+
"nord0": "#2E3440",
|
| 5 |
+
"nord1": "#3B4252",
|
| 6 |
+
"nord2": "#434C5E",
|
| 7 |
+
"nord3": "#4C566A",
|
| 8 |
+
"nord4": "#D8DEE9",
|
| 9 |
+
"nord5": "#E5E9F0",
|
| 10 |
+
"nord6": "#ECEFF4",
|
| 11 |
+
"nord7": "#8FBCBB",
|
| 12 |
+
"nord8": "#88C0D0",
|
| 13 |
+
"nord9": "#81A1C1",
|
| 14 |
+
"nord10": "#5E81AC",
|
| 15 |
+
"nord11": "#BF616A",
|
| 16 |
+
"nord12": "#D08770",
|
| 17 |
+
"nord13": "#EBCB8B",
|
| 18 |
+
"nord14": "#A3BE8C",
|
| 19 |
+
"nord15": "#B48EAD"
|
| 20 |
+
},
|
| 21 |
+
"theme": {
|
| 22 |
+
"primary": {
|
| 23 |
+
"dark": "nord10",
|
| 24 |
+
"light": "nord9"
|
| 25 |
+
},
|
| 26 |
+
"secondary": {
|
| 27 |
+
"dark": "nord9",
|
| 28 |
+
"light": "nord9"
|
| 29 |
+
},
|
| 30 |
+
"accent": {
|
| 31 |
+
"dark": "nord7",
|
| 32 |
+
"light": "nord7"
|
| 33 |
+
},
|
| 34 |
+
"error": {
|
| 35 |
+
"dark": "nord11",
|
| 36 |
+
"light": "nord11"
|
| 37 |
+
},
|
| 38 |
+
"warning": {
|
| 39 |
+
"dark": "nord12",
|
| 40 |
+
"light": "nord12"
|
| 41 |
+
},
|
| 42 |
+
"success": {
|
| 43 |
+
"dark": "nord14",
|
| 44 |
+
"light": "nord14"
|
| 45 |
+
},
|
| 46 |
+
"info": {
|
| 47 |
+
"dark": "nord8",
|
| 48 |
+
"light": "nord10"
|
| 49 |
+
},
|
| 50 |
+
"text": {
|
| 51 |
+
"dark": "nord6",
|
| 52 |
+
"light": "nord0"
|
| 53 |
+
},
|
| 54 |
+
"textMuted": {
|
| 55 |
+
"dark": "#8B95A7",
|
| 56 |
+
"light": "nord1"
|
| 57 |
+
},
|
| 58 |
+
"background": {
|
| 59 |
+
"dark": "nord0",
|
| 60 |
+
"light": "nord6"
|
| 61 |
+
},
|
| 62 |
+
"backgroundPanel": {
|
| 63 |
+
"dark": "nord1",
|
| 64 |
+
"light": "nord5"
|
| 65 |
+
},
|
| 66 |
+
"backgroundElement": {
|
| 67 |
+
"dark": "nord2",
|
| 68 |
+
"light": "nord4"
|
| 69 |
+
},
|
| 70 |
+
"border": {
|
| 71 |
+
"dark": "nord2",
|
| 72 |
+
"light": "nord3"
|
| 73 |
+
},
|
| 74 |
+
"borderActive": {
|
| 75 |
+
"dark": "nord3",
|
| 76 |
+
"light": "nord2"
|
| 77 |
+
},
|
| 78 |
+
"borderSubtle": {
|
| 79 |
+
"dark": "nord2",
|
| 80 |
+
"light": "nord3"
|
| 81 |
+
},
|
| 82 |
+
"diffAdded": {
|
| 83 |
+
"dark": "nord14",
|
| 84 |
+
"light": "nord14"
|
| 85 |
+
},
|
| 86 |
+
"diffRemoved": {
|
| 87 |
+
"dark": "nord11",
|
| 88 |
+
"light": "nord11"
|
| 89 |
+
},
|
| 90 |
+
"diffContext": {
|
| 91 |
+
"dark": "#8B95A7",
|
| 92 |
+
"light": "nord3"
|
| 93 |
+
},
|
| 94 |
+
"diffHunkHeader": {
|
| 95 |
+
"dark": "#8B95A7",
|
| 96 |
+
"light": "nord3"
|
| 97 |
+
},
|
| 98 |
+
"diffHighlightAdded": {
|
| 99 |
+
"dark": "nord14",
|
| 100 |
+
"light": "nord14"
|
| 101 |
+
},
|
| 102 |
+
"diffHighlightRemoved": {
|
| 103 |
+
"dark": "nord11",
|
| 104 |
+
"light": "nord11"
|
| 105 |
+
},
|
| 106 |
+
"diffAddedBg": {
|
| 107 |
+
"dark": "#36413C",
|
| 108 |
+
"light": "#E6EBE7"
|
| 109 |
+
},
|
| 110 |
+
"diffRemovedBg": {
|
| 111 |
+
"dark": "#43393D",
|
| 112 |
+
"light": "#ECE6E8"
|
| 113 |
+
},
|
| 114 |
+
"diffContextBg": {
|
| 115 |
+
"dark": "nord1",
|
| 116 |
+
"light": "nord5"
|
| 117 |
+
},
|
| 118 |
+
"diffLineNumber": {
|
| 119 |
+
"dark": "nord2",
|
| 120 |
+
"light": "nord4"
|
| 121 |
+
},
|
| 122 |
+
"diffAddedLineNumberBg": {
|
| 123 |
+
"dark": "#303A35",
|
| 124 |
+
"light": "#DDE4DF"
|
| 125 |
+
},
|
| 126 |
+
"diffRemovedLineNumberBg": {
|
| 127 |
+
"dark": "#3C3336",
|
| 128 |
+
"light": "#E4DDE0"
|
| 129 |
+
},
|
| 130 |
+
"markdownText": {
|
| 131 |
+
"dark": "nord4",
|
| 132 |
+
"light": "nord0"
|
| 133 |
+
},
|
| 134 |
+
"markdownHeading": {
|
| 135 |
+
"dark": "nord8",
|
| 136 |
+
"light": "nord10"
|
| 137 |
+
},
|
| 138 |
+
"markdownLink": {
|
| 139 |
+
"dark": "nord9",
|
| 140 |
+
"light": "nord9"
|
| 141 |
+
},
|
| 142 |
+
"markdownLinkText": {
|
| 143 |
+
"dark": "nord7",
|
| 144 |
+
"light": "nord7"
|
| 145 |
+
},
|
| 146 |
+
"markdownCode": {
|
| 147 |
+
"dark": "nord14",
|
| 148 |
+
"light": "nord14"
|
| 149 |
+
},
|
| 150 |
+
"markdownBlockQuote": {
|
| 151 |
+
"dark": "#8B95A7",
|
| 152 |
+
"light": "nord3"
|
| 153 |
+
},
|
| 154 |
+
"markdownEmph": {
|
| 155 |
+
"dark": "nord12",
|
| 156 |
+
"light": "nord12"
|
| 157 |
+
},
|
| 158 |
+
"markdownStrong": {
|
| 159 |
+
"dark": "nord13",
|
| 160 |
+
"light": "nord13"
|
| 161 |
+
},
|
| 162 |
+
"markdownHorizontalRule": {
|
| 163 |
+
"dark": "#8B95A7",
|
| 164 |
+
"light": "nord3"
|
| 165 |
+
},
|
| 166 |
+
"markdownListItem": {
|
| 167 |
+
"dark": "nord8",
|
| 168 |
+
"light": "nord10"
|
| 169 |
+
},
|
| 170 |
+
"markdownListEnumeration": {
|
| 171 |
+
"dark": "nord7",
|
| 172 |
+
"light": "nord7"
|
| 173 |
+
},
|
| 174 |
+
"markdownImage": {
|
| 175 |
+
"dark": "nord9",
|
| 176 |
+
"light": "nord9"
|
| 177 |
+
},
|
| 178 |
+
"markdownImageText": {
|
| 179 |
+
"dark": "nord7",
|
| 180 |
+
"light": "nord7"
|
| 181 |
+
},
|
| 182 |
+
"markdownCodeBlock": {
|
| 183 |
+
"dark": "nord4",
|
| 184 |
+
"light": "nord0"
|
| 185 |
+
},
|
| 186 |
+
"syntaxComment": {
|
| 187 |
+
"dark": "#8B95A7",
|
| 188 |
+
"light": "nord3"
|
| 189 |
+
},
|
| 190 |
+
"syntaxKeyword": {
|
| 191 |
+
"dark": "nord9",
|
| 192 |
+
"light": "nord9"
|
| 193 |
+
},
|
| 194 |
+
"syntaxFunction": {
|
| 195 |
+
"dark": "nord8",
|
| 196 |
+
"light": "nord8"
|
| 197 |
+
},
|
| 198 |
+
"syntaxVariable": {
|
| 199 |
+
"dark": "nord7",
|
| 200 |
+
"light": "nord7"
|
| 201 |
+
},
|
| 202 |
+
"syntaxString": {
|
| 203 |
+
"dark": "nord14",
|
| 204 |
+
"light": "nord14"
|
| 205 |
+
},
|
| 206 |
+
"syntaxNumber": {
|
| 207 |
+
"dark": "nord15",
|
| 208 |
+
"light": "nord15"
|
| 209 |
+
},
|
| 210 |
+
"syntaxType": {
|
| 211 |
+
"dark": "nord7",
|
| 212 |
+
"light": "nord7"
|
| 213 |
+
},
|
| 214 |
+
"syntaxOperator": {
|
| 215 |
+
"dark": "nord9",
|
| 216 |
+
"light": "nord9"
|
| 217 |
+
},
|
| 218 |
+
"syntaxPunctuation": {
|
| 219 |
+
"dark": "nord4",
|
| 220 |
+
"light": "nord0"
|
| 221 |
+
}
|
| 222 |
+
}
|
| 223 |
+
}
|
.opencode/plugins/tui-smoke.tsx
ADDED
|
@@ -0,0 +1,1019 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** @jsxImportSource @opentui/solid */
|
| 2 |
+
import { useTerminalDimensions, type JSX } from "@opentui/solid"
|
| 3 |
+
import { useBindings, useKeymapSelector } from "@opentui/keymap/solid"
|
| 4 |
+
import { RGBA, VignetteEffect, type KeyEvent, type Renderable } from "@opentui/core"
|
| 5 |
+
import { createBindingLookup, type BindingConfig } from "@opentui/keymap/extras"
|
| 6 |
+
import type { TuiPlugin, TuiPluginApi, TuiPluginMeta, TuiPluginModule, TuiSlotPlugin } from "@opencode-ai/plugin/tui"
|
| 7 |
+
|
| 8 |
+
const tabs = ["overview", "counter", "help"]
|
| 9 |
+
const command = {
|
| 10 |
+
modal: "smoke_modal",
|
| 11 |
+
screen: "smoke_screen",
|
| 12 |
+
alert: "smoke_alert",
|
| 13 |
+
confirm: "smoke_confirm",
|
| 14 |
+
prompt: "smoke_prompt",
|
| 15 |
+
select: "smoke_select",
|
| 16 |
+
host: "smoke_host",
|
| 17 |
+
home: "smoke_home",
|
| 18 |
+
toast: "smoke_toast",
|
| 19 |
+
dialog_close: "smoke_dialog_close",
|
| 20 |
+
local_push: "smoke_local_push",
|
| 21 |
+
local_pop: "smoke_local_pop",
|
| 22 |
+
screen_home: "smoke_screen_home",
|
| 23 |
+
screen_left: "smoke_screen_left",
|
| 24 |
+
screen_right: "smoke_screen_right",
|
| 25 |
+
screen_up: "smoke_screen_up",
|
| 26 |
+
screen_down: "smoke_screen_down",
|
| 27 |
+
screen_modal: "smoke_screen_modal",
|
| 28 |
+
screen_local: "smoke_screen_local",
|
| 29 |
+
screen_host: "smoke_screen_host",
|
| 30 |
+
screen_alert: "smoke_screen_alert",
|
| 31 |
+
screen_confirm: "smoke_screen_confirm",
|
| 32 |
+
screen_prompt: "smoke_screen_prompt",
|
| 33 |
+
screen_select: "smoke_screen_select",
|
| 34 |
+
modal_accept: "smoke_modal_accept",
|
| 35 |
+
modal_close: "smoke_modal_close",
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
type SmokeBindings = BindingConfig<Renderable, KeyEvent>
|
| 39 |
+
|
| 40 |
+
const defaultKeymap = {
|
| 41 |
+
[command.modal]: "ctrl+shift+m",
|
| 42 |
+
[command.screen]: "ctrl+shift+o",
|
| 43 |
+
[command.dialog_close]: "escape",
|
| 44 |
+
[command.local_push]: "enter,return",
|
| 45 |
+
[command.local_pop]: "escape,q,backspace",
|
| 46 |
+
[command.screen_home]: "escape,ctrl+h",
|
| 47 |
+
[command.screen_left]: "left,h",
|
| 48 |
+
[command.screen_right]: "right,l",
|
| 49 |
+
[command.screen_up]: "up,k",
|
| 50 |
+
[command.screen_down]: "down,j",
|
| 51 |
+
[command.screen_modal]: "ctrl+shift+m",
|
| 52 |
+
[command.screen_local]: "x",
|
| 53 |
+
[command.screen_host]: "z",
|
| 54 |
+
[command.screen_alert]: "a",
|
| 55 |
+
[command.screen_confirm]: "c",
|
| 56 |
+
[command.screen_prompt]: "p",
|
| 57 |
+
[command.screen_select]: "s",
|
| 58 |
+
[command.modal_accept]: "enter,return",
|
| 59 |
+
[command.modal_close]: "escape",
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
const pick = (value: unknown, fallback: string) => {
|
| 63 |
+
if (typeof value !== "string") return fallback
|
| 64 |
+
if (!value.trim()) return fallback
|
| 65 |
+
return value
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
const num = (value: unknown, fallback: number) => {
|
| 69 |
+
if (typeof value !== "number") return fallback
|
| 70 |
+
return value
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
const record = (value: unknown): value is Record<string, unknown> =>
|
| 74 |
+
!!value && typeof value === "object" && !Array.isArray(value)
|
| 75 |
+
|
| 76 |
+
type Cfg = {
|
| 77 |
+
label: string
|
| 78 |
+
route: string
|
| 79 |
+
vignette: number
|
| 80 |
+
keybinds: SmokeBindings | undefined
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
type Route = {
|
| 84 |
+
modal: string
|
| 85 |
+
screen: string
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
type State = {
|
| 89 |
+
tab: number
|
| 90 |
+
count: number
|
| 91 |
+
source: string
|
| 92 |
+
note: string
|
| 93 |
+
selected: string
|
| 94 |
+
local: number
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
const cfg = (options: Record<string, unknown> | undefined) => {
|
| 98 |
+
return {
|
| 99 |
+
label: pick(options?.label, "smoke"),
|
| 100 |
+
route: pick(options?.route, "workspace-smoke"),
|
| 101 |
+
vignette: Math.max(0, num(options?.vignette, 0.35)),
|
| 102 |
+
keybinds: record(options?.keybinds) ? (options.keybinds as SmokeBindings) : undefined,
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
const names = (input: Cfg) => {
|
| 107 |
+
return {
|
| 108 |
+
modal: `${input.route}.modal`,
|
| 109 |
+
screen: `${input.route}.screen`,
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
function createKeys(input: SmokeBindings | undefined) {
|
| 114 |
+
return createBindingLookup({ ...defaultKeymap, ...input })
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
type Keys = ReturnType<typeof createKeys>
|
| 118 |
+
|
| 119 |
+
const ui = {
|
| 120 |
+
panel: "#1d1d1d",
|
| 121 |
+
border: "#4a4a4a",
|
| 122 |
+
text: "#f0f0f0",
|
| 123 |
+
muted: "#a5a5a5",
|
| 124 |
+
accent: "#5f87ff",
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
type Color = RGBA | string
|
| 128 |
+
|
| 129 |
+
const ink = (map: Record<string, unknown>, name: string, fallback: string): Color => {
|
| 130 |
+
const value = map[name]
|
| 131 |
+
if (typeof value === "string") return value
|
| 132 |
+
if (value instanceof RGBA) return value
|
| 133 |
+
return fallback
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
const look = (map: Record<string, unknown>) => {
|
| 137 |
+
return {
|
| 138 |
+
panel: ink(map, "backgroundPanel", ui.panel),
|
| 139 |
+
border: ink(map, "border", ui.border),
|
| 140 |
+
text: ink(map, "text", ui.text),
|
| 141 |
+
muted: ink(map, "textMuted", ui.muted),
|
| 142 |
+
accent: ink(map, "primary", ui.accent),
|
| 143 |
+
selected: ink(map, "selectedListItemText", ui.text),
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
const tone = (api: TuiPluginApi) => {
|
| 148 |
+
return look(api.theme.current)
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
type Skin = {
|
| 152 |
+
panel: Color
|
| 153 |
+
border: Color
|
| 154 |
+
text: Color
|
| 155 |
+
muted: Color
|
| 156 |
+
accent: Color
|
| 157 |
+
selected: Color
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
const Btn = (props: { txt: string; run: () => void; skin: Skin; on?: boolean }) => {
|
| 161 |
+
return (
|
| 162 |
+
<box
|
| 163 |
+
onMouseUp={() => {
|
| 164 |
+
props.run()
|
| 165 |
+
}}
|
| 166 |
+
backgroundColor={props.on ? props.skin.accent : props.skin.border}
|
| 167 |
+
paddingLeft={1}
|
| 168 |
+
paddingRight={1}
|
| 169 |
+
>
|
| 170 |
+
<text fg={props.on ? props.skin.selected : props.skin.text}>{props.txt}</text>
|
| 171 |
+
</box>
|
| 172 |
+
)
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
const parse = (params: Record<string, unknown> | undefined) => {
|
| 176 |
+
const tab = typeof params?.tab === "number" ? params.tab : 0
|
| 177 |
+
const count = typeof params?.count === "number" ? params.count : 0
|
| 178 |
+
const source = typeof params?.source === "string" ? params.source : "unknown"
|
| 179 |
+
const note = typeof params?.note === "string" ? params.note : ""
|
| 180 |
+
const selected = typeof params?.selected === "string" ? params.selected : ""
|
| 181 |
+
const local = typeof params?.local === "number" ? params.local : 0
|
| 182 |
+
return {
|
| 183 |
+
tab: Math.max(0, Math.min(tab, tabs.length - 1)),
|
| 184 |
+
count,
|
| 185 |
+
source,
|
| 186 |
+
note,
|
| 187 |
+
selected,
|
| 188 |
+
local: Math.max(0, local),
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
const current = (api: TuiPluginApi, route: Route) => {
|
| 193 |
+
const value = api.route.current
|
| 194 |
+
const ok = Object.values(route).includes(value.name)
|
| 195 |
+
if (!ok) return parse(undefined)
|
| 196 |
+
if (!("params" in value)) return parse(undefined)
|
| 197 |
+
return parse(value.params)
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
const opts = [
|
| 201 |
+
{
|
| 202 |
+
title: "Overview",
|
| 203 |
+
value: 0,
|
| 204 |
+
description: "Switch to overview tab",
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
title: "Counter",
|
| 208 |
+
value: 1,
|
| 209 |
+
description: "Switch to counter tab",
|
| 210 |
+
},
|
| 211 |
+
{
|
| 212 |
+
title: "Help",
|
| 213 |
+
value: 2,
|
| 214 |
+
description: "Switch to help tab",
|
| 215 |
+
},
|
| 216 |
+
]
|
| 217 |
+
|
| 218 |
+
const host = (api: TuiPluginApi, input: Cfg, skin: Skin) => {
|
| 219 |
+
api.ui.dialog.setSize("medium")
|
| 220 |
+
api.ui.dialog.replace(() => (
|
| 221 |
+
<box paddingBottom={1} paddingLeft={2} paddingRight={2} gap={1} flexDirection="column">
|
| 222 |
+
<text fg={skin.text}>
|
| 223 |
+
<b>{input.label} host overlay</b>
|
| 224 |
+
</text>
|
| 225 |
+
<text fg={skin.muted}>Using api.ui.dialog stack with built-in backdrop</text>
|
| 226 |
+
<text fg={skin.muted}>esc closes · depth {api.ui.dialog.depth}</text>
|
| 227 |
+
<box flexDirection="row" gap={1}>
|
| 228 |
+
<Btn txt="close" run={() => api.ui.dialog.clear()} skin={skin} on />
|
| 229 |
+
</box>
|
| 230 |
+
</box>
|
| 231 |
+
))
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
const warn = (api: TuiPluginApi, route: Route, value: State) => {
|
| 235 |
+
const DialogAlert = api.ui.DialogAlert
|
| 236 |
+
api.ui.dialog.setSize("medium")
|
| 237 |
+
api.ui.dialog.replace(() => (
|
| 238 |
+
<DialogAlert
|
| 239 |
+
title="Smoke alert"
|
| 240 |
+
message="Testing built-in alert dialog"
|
| 241 |
+
onConfirm={() => api.route.navigate(route.screen, { ...value, source: "alert" })}
|
| 242 |
+
/>
|
| 243 |
+
))
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
const check = (api: TuiPluginApi, route: Route, value: State) => {
|
| 247 |
+
const DialogConfirm = api.ui.DialogConfirm
|
| 248 |
+
api.ui.dialog.setSize("medium")
|
| 249 |
+
api.ui.dialog.replace(() => (
|
| 250 |
+
<DialogConfirm
|
| 251 |
+
title="Smoke confirm"
|
| 252 |
+
message="Apply +1 to counter?"
|
| 253 |
+
onConfirm={() => api.route.navigate(route.screen, { ...value, count: value.count + 1, source: "confirm" })}
|
| 254 |
+
onCancel={() => api.route.navigate(route.screen, { ...value, source: "confirm-cancel" })}
|
| 255 |
+
/>
|
| 256 |
+
))
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
const entry = (api: TuiPluginApi, route: Route, value: State) => {
|
| 260 |
+
const DialogPrompt = api.ui.DialogPrompt
|
| 261 |
+
api.ui.dialog.setSize("medium")
|
| 262 |
+
api.ui.dialog.replace(() => (
|
| 263 |
+
<DialogPrompt
|
| 264 |
+
title="Smoke prompt"
|
| 265 |
+
value={value.note}
|
| 266 |
+
onConfirm={(note) => {
|
| 267 |
+
api.ui.dialog.clear()
|
| 268 |
+
api.route.navigate(route.screen, { ...value, note, source: "prompt" })
|
| 269 |
+
}}
|
| 270 |
+
onCancel={() => {
|
| 271 |
+
api.ui.dialog.clear()
|
| 272 |
+
api.route.navigate(route.screen, value)
|
| 273 |
+
}}
|
| 274 |
+
/>
|
| 275 |
+
))
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
const picker = (api: TuiPluginApi, route: Route, value: State) => {
|
| 279 |
+
const DialogSelect = api.ui.DialogSelect
|
| 280 |
+
api.ui.dialog.setSize("medium")
|
| 281 |
+
api.ui.dialog.replace(() => (
|
| 282 |
+
<DialogSelect
|
| 283 |
+
title="Smoke select"
|
| 284 |
+
options={opts}
|
| 285 |
+
current={value.tab}
|
| 286 |
+
onSelect={(item) => {
|
| 287 |
+
api.ui.dialog.clear()
|
| 288 |
+
api.route.navigate(route.screen, {
|
| 289 |
+
...value,
|
| 290 |
+
tab: typeof item.value === "number" ? item.value : value.tab,
|
| 291 |
+
selected: item.title,
|
| 292 |
+
source: "select",
|
| 293 |
+
})
|
| 294 |
+
}}
|
| 295 |
+
/>
|
| 296 |
+
))
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
const Screen = (props: {
|
| 300 |
+
api: TuiPluginApi
|
| 301 |
+
input: Cfg
|
| 302 |
+
route: Route
|
| 303 |
+
keys: Keys
|
| 304 |
+
meta: TuiPluginMeta
|
| 305 |
+
params?: Record<string, unknown>
|
| 306 |
+
}) => {
|
| 307 |
+
const dim = useTerminalDimensions()
|
| 308 |
+
const value = parse(props.params)
|
| 309 |
+
const skin = tone(props.api)
|
| 310 |
+
const set = (local: number, base?: State) => {
|
| 311 |
+
const next = base ?? current(props.api, props.route)
|
| 312 |
+
props.api.route.navigate(props.route.screen, { ...next, local: Math.max(0, local), source: "local" })
|
| 313 |
+
}
|
| 314 |
+
const push = (base?: State) => {
|
| 315 |
+
const next = base ?? current(props.api, props.route)
|
| 316 |
+
set(next.local + 1, next)
|
| 317 |
+
}
|
| 318 |
+
const open = () => {
|
| 319 |
+
const next = current(props.api, props.route)
|
| 320 |
+
if (next.local > 0) return
|
| 321 |
+
set(1, next)
|
| 322 |
+
}
|
| 323 |
+
const pop = (base?: State) => {
|
| 324 |
+
const next = base ?? current(props.api, props.route)
|
| 325 |
+
set(Math.max(0, next.local - 1), next)
|
| 326 |
+
}
|
| 327 |
+
const show = () => {
|
| 328 |
+
setTimeout(() => {
|
| 329 |
+
open()
|
| 330 |
+
}, 0)
|
| 331 |
+
}
|
| 332 |
+
const screenActive = () => props.api.route.current.name === props.route.screen
|
| 333 |
+
|
| 334 |
+
useBindings(() => ({
|
| 335 |
+
enabled: () => screenActive() && props.api.ui.dialog.open,
|
| 336 |
+
commands: [
|
| 337 |
+
{
|
| 338 |
+
name: command.dialog_close,
|
| 339 |
+
run() {
|
| 340 |
+
props.api.ui.dialog.clear()
|
| 341 |
+
},
|
| 342 |
+
},
|
| 343 |
+
],
|
| 344 |
+
bindings: props.keys.gather("smoke.dialog", [command.dialog_close]),
|
| 345 |
+
}))
|
| 346 |
+
|
| 347 |
+
useBindings(() => ({
|
| 348 |
+
enabled: () => screenActive() && !props.api.ui.dialog.open && current(props.api, props.route).local > 0,
|
| 349 |
+
commands: [
|
| 350 |
+
{
|
| 351 |
+
name: command.local_push,
|
| 352 |
+
run() {
|
| 353 |
+
push(current(props.api, props.route))
|
| 354 |
+
},
|
| 355 |
+
},
|
| 356 |
+
{
|
| 357 |
+
name: command.local_pop,
|
| 358 |
+
run() {
|
| 359 |
+
pop(current(props.api, props.route))
|
| 360 |
+
},
|
| 361 |
+
},
|
| 362 |
+
],
|
| 363 |
+
bindings: props.keys.gather("smoke.local", [command.local_push, command.local_pop]),
|
| 364 |
+
}))
|
| 365 |
+
|
| 366 |
+
useBindings(() => ({
|
| 367 |
+
enabled: () => screenActive() && !props.api.ui.dialog.open && current(props.api, props.route).local === 0,
|
| 368 |
+
commands: [
|
| 369 |
+
{
|
| 370 |
+
name: command.screen_home,
|
| 371 |
+
run() {
|
| 372 |
+
props.api.route.navigate("home")
|
| 373 |
+
},
|
| 374 |
+
},
|
| 375 |
+
{
|
| 376 |
+
name: command.screen_left,
|
| 377 |
+
run() {
|
| 378 |
+
const next = current(props.api, props.route)
|
| 379 |
+
props.api.route.navigate(props.route.screen, { ...next, tab: (next.tab - 1 + tabs.length) % tabs.length })
|
| 380 |
+
},
|
| 381 |
+
},
|
| 382 |
+
{
|
| 383 |
+
name: command.screen_right,
|
| 384 |
+
run() {
|
| 385 |
+
const next = current(props.api, props.route)
|
| 386 |
+
props.api.route.navigate(props.route.screen, { ...next, tab: (next.tab + 1) % tabs.length })
|
| 387 |
+
},
|
| 388 |
+
},
|
| 389 |
+
{
|
| 390 |
+
name: command.screen_up,
|
| 391 |
+
run() {
|
| 392 |
+
const next = current(props.api, props.route)
|
| 393 |
+
props.api.route.navigate(props.route.screen, { ...next, count: next.count + 1 })
|
| 394 |
+
},
|
| 395 |
+
},
|
| 396 |
+
{
|
| 397 |
+
name: command.screen_down,
|
| 398 |
+
run() {
|
| 399 |
+
const next = current(props.api, props.route)
|
| 400 |
+
props.api.route.navigate(props.route.screen, { ...next, count: next.count - 1 })
|
| 401 |
+
},
|
| 402 |
+
},
|
| 403 |
+
{
|
| 404 |
+
name: command.screen_modal,
|
| 405 |
+
run() {
|
| 406 |
+
props.api.route.navigate(props.route.modal, current(props.api, props.route))
|
| 407 |
+
},
|
| 408 |
+
},
|
| 409 |
+
{
|
| 410 |
+
name: command.screen_local,
|
| 411 |
+
run() {
|
| 412 |
+
open()
|
| 413 |
+
},
|
| 414 |
+
},
|
| 415 |
+
{
|
| 416 |
+
name: command.screen_host,
|
| 417 |
+
run() {
|
| 418 |
+
host(props.api, props.input, skin)
|
| 419 |
+
},
|
| 420 |
+
},
|
| 421 |
+
{
|
| 422 |
+
name: command.screen_alert,
|
| 423 |
+
run() {
|
| 424 |
+
warn(props.api, props.route, current(props.api, props.route))
|
| 425 |
+
},
|
| 426 |
+
},
|
| 427 |
+
{
|
| 428 |
+
name: command.screen_confirm,
|
| 429 |
+
run() {
|
| 430 |
+
check(props.api, props.route, current(props.api, props.route))
|
| 431 |
+
},
|
| 432 |
+
},
|
| 433 |
+
{
|
| 434 |
+
name: command.screen_prompt,
|
| 435 |
+
run() {
|
| 436 |
+
entry(props.api, props.route, current(props.api, props.route))
|
| 437 |
+
},
|
| 438 |
+
},
|
| 439 |
+
{
|
| 440 |
+
name: command.screen_select,
|
| 441 |
+
run() {
|
| 442 |
+
picker(props.api, props.route, current(props.api, props.route))
|
| 443 |
+
},
|
| 444 |
+
},
|
| 445 |
+
],
|
| 446 |
+
bindings: props.keys.gather("smoke.screen", [
|
| 447 |
+
command.screen_home,
|
| 448 |
+
command.screen_left,
|
| 449 |
+
command.screen_right,
|
| 450 |
+
command.screen_up,
|
| 451 |
+
command.screen_down,
|
| 452 |
+
command.screen_modal,
|
| 453 |
+
command.screen_local,
|
| 454 |
+
command.screen_host,
|
| 455 |
+
command.screen_alert,
|
| 456 |
+
command.screen_confirm,
|
| 457 |
+
command.screen_prompt,
|
| 458 |
+
command.screen_select,
|
| 459 |
+
]),
|
| 460 |
+
}))
|
| 461 |
+
const shortcuts = useKeymapSelector((keymap) => {
|
| 462 |
+
const bindings = keymap.getCommandBindings({
|
| 463 |
+
visibility: "registered",
|
| 464 |
+
commands: [
|
| 465 |
+
command.screen_home,
|
| 466 |
+
command.screen_up,
|
| 467 |
+
command.screen_down,
|
| 468 |
+
command.screen_modal,
|
| 469 |
+
command.screen_alert,
|
| 470 |
+
command.screen_confirm,
|
| 471 |
+
command.screen_prompt,
|
| 472 |
+
command.screen_select,
|
| 473 |
+
command.screen_local,
|
| 474 |
+
command.screen_host,
|
| 475 |
+
command.local_push,
|
| 476 |
+
command.local_pop,
|
| 477 |
+
],
|
| 478 |
+
})
|
| 479 |
+
|
| 480 |
+
return {
|
| 481 |
+
screen_home: props.api.keys.formatBindings(bindings.get(command.screen_home)) ?? "",
|
| 482 |
+
screen_up: props.api.keys.formatBindings(bindings.get(command.screen_up)) ?? "",
|
| 483 |
+
screen_down: props.api.keys.formatBindings(bindings.get(command.screen_down)) ?? "",
|
| 484 |
+
screen_modal: props.api.keys.formatBindings(bindings.get(command.screen_modal)) ?? "",
|
| 485 |
+
screen_alert: props.api.keys.formatBindings(bindings.get(command.screen_alert)) ?? "",
|
| 486 |
+
screen_confirm: props.api.keys.formatBindings(bindings.get(command.screen_confirm)) ?? "",
|
| 487 |
+
screen_prompt: props.api.keys.formatBindings(bindings.get(command.screen_prompt)) ?? "",
|
| 488 |
+
screen_select: props.api.keys.formatBindings(bindings.get(command.screen_select)) ?? "",
|
| 489 |
+
screen_local: props.api.keys.formatBindings(bindings.get(command.screen_local)) ?? "",
|
| 490 |
+
screen_host: props.api.keys.formatBindings(bindings.get(command.screen_host)) ?? "",
|
| 491 |
+
local_push: props.api.keys.formatBindings(bindings.get(command.local_push)) ?? "",
|
| 492 |
+
local_pop: props.api.keys.formatBindings(bindings.get(command.local_pop)) ?? "",
|
| 493 |
+
}
|
| 494 |
+
})
|
| 495 |
+
|
| 496 |
+
return (
|
| 497 |
+
<box width={dim().width} height={dim().height} backgroundColor={skin.panel} position="relative">
|
| 498 |
+
<box
|
| 499 |
+
flexDirection="column"
|
| 500 |
+
width="100%"
|
| 501 |
+
height="100%"
|
| 502 |
+
paddingTop={1}
|
| 503 |
+
paddingBottom={1}
|
| 504 |
+
paddingLeft={2}
|
| 505 |
+
paddingRight={2}
|
| 506 |
+
>
|
| 507 |
+
<box flexDirection="row" justifyContent="space-between" paddingBottom={1}>
|
| 508 |
+
<text fg={skin.text}>
|
| 509 |
+
<b>{props.input.label} screen</b>
|
| 510 |
+
<span style={{ fg: skin.muted }}> plugin route</span>
|
| 511 |
+
</text>
|
| 512 |
+
<text fg={skin.muted}>{shortcuts().screen_home} home</text>
|
| 513 |
+
</box>
|
| 514 |
+
|
| 515 |
+
<box flexDirection="row" gap={1} paddingBottom={1}>
|
| 516 |
+
{tabs.map((item, i) => {
|
| 517 |
+
const on = value.tab === i
|
| 518 |
+
return (
|
| 519 |
+
<Btn
|
| 520 |
+
txt={item}
|
| 521 |
+
run={() => props.api.route.navigate(props.route.screen, { ...value, tab: i })}
|
| 522 |
+
skin={skin}
|
| 523 |
+
on={on}
|
| 524 |
+
/>
|
| 525 |
+
)
|
| 526 |
+
})}
|
| 527 |
+
</box>
|
| 528 |
+
|
| 529 |
+
<box
|
| 530 |
+
border
|
| 531 |
+
borderColor={skin.border}
|
| 532 |
+
paddingTop={1}
|
| 533 |
+
paddingBottom={1}
|
| 534 |
+
paddingLeft={2}
|
| 535 |
+
paddingRight={2}
|
| 536 |
+
flexGrow={1}
|
| 537 |
+
>
|
| 538 |
+
{value.tab === 0 ? (
|
| 539 |
+
<box flexDirection="column" gap={1}>
|
| 540 |
+
<text fg={skin.text}>Route: {props.route.screen}</text>
|
| 541 |
+
<text fg={skin.muted}>plugin state: {props.meta.state}</text>
|
| 542 |
+
<text fg={skin.muted}>
|
| 543 |
+
first: {props.meta.state === "first" ? "yes" : "no"} · updated:{" "}
|
| 544 |
+
{props.meta.state === "updated" ? "yes" : "no"} · loads: {props.meta.load_count}
|
| 545 |
+
</text>
|
| 546 |
+
<text fg={skin.muted}>plugin source: {props.meta.source}</text>
|
| 547 |
+
<text fg={skin.muted}>source: {value.source}</text>
|
| 548 |
+
<text fg={skin.muted}>note: {value.note || "(none)"}</text>
|
| 549 |
+
<text fg={skin.muted}>selected: {value.selected || "(none)"}</text>
|
| 550 |
+
<text fg={skin.muted}>local stack depth: {value.local}</text>
|
| 551 |
+
<text fg={skin.muted}>host stack open: {props.api.ui.dialog.open ? "yes" : "no"}</text>
|
| 552 |
+
</box>
|
| 553 |
+
) : null}
|
| 554 |
+
|
| 555 |
+
{value.tab === 1 ? (
|
| 556 |
+
<box flexDirection="column" gap={1}>
|
| 557 |
+
<text fg={skin.text}>Counter: {value.count}</text>
|
| 558 |
+
<text fg={skin.muted}>
|
| 559 |
+
{shortcuts().screen_up} / {shortcuts().screen_down} change value
|
| 560 |
+
</text>
|
| 561 |
+
</box>
|
| 562 |
+
) : null}
|
| 563 |
+
|
| 564 |
+
{value.tab === 2 ? (
|
| 565 |
+
<box flexDirection="column" gap={1}>
|
| 566 |
+
<text fg={skin.muted}>
|
| 567 |
+
{shortcuts().screen_modal} modal | {shortcuts().screen_alert} alert | {shortcuts().screen_confirm}{" "}
|
| 568 |
+
confirm | {shortcuts().screen_prompt} prompt | {shortcuts().screen_select} select
|
| 569 |
+
</text>
|
| 570 |
+
<text fg={skin.muted}>
|
| 571 |
+
{shortcuts().screen_local} local stack | {shortcuts().screen_host} host stack
|
| 572 |
+
</text>
|
| 573 |
+
<text fg={skin.muted}>
|
| 574 |
+
local open: {shortcuts().local_push} push nested · {shortcuts().local_pop} close
|
| 575 |
+
</text>
|
| 576 |
+
<text fg={skin.muted}>{shortcuts().screen_home} returns home</text>
|
| 577 |
+
</box>
|
| 578 |
+
) : null}
|
| 579 |
+
</box>
|
| 580 |
+
|
| 581 |
+
<box flexDirection="row" gap={1} paddingTop={1}>
|
| 582 |
+
<Btn txt="go home" run={() => props.api.route.navigate("home")} skin={skin} />
|
| 583 |
+
<Btn txt="modal" run={() => props.api.route.navigate(props.route.modal, value)} skin={skin} on />
|
| 584 |
+
<Btn txt="local overlay" run={show} skin={skin} />
|
| 585 |
+
<Btn txt="host overlay" run={() => host(props.api, props.input, skin)} skin={skin} />
|
| 586 |
+
<Btn txt="alert" run={() => warn(props.api, props.route, value)} skin={skin} />
|
| 587 |
+
<Btn txt="confirm" run={() => check(props.api, props.route, value)} skin={skin} />
|
| 588 |
+
<Btn txt="prompt" run={() => entry(props.api, props.route, value)} skin={skin} />
|
| 589 |
+
<Btn txt="select" run={() => picker(props.api, props.route, value)} skin={skin} />
|
| 590 |
+
</box>
|
| 591 |
+
</box>
|
| 592 |
+
|
| 593 |
+
<box
|
| 594 |
+
visible={value.local > 0}
|
| 595 |
+
width={dim().width}
|
| 596 |
+
height={dim().height}
|
| 597 |
+
alignItems="center"
|
| 598 |
+
position="absolute"
|
| 599 |
+
zIndex={3000}
|
| 600 |
+
paddingTop={dim().height / 4}
|
| 601 |
+
left={0}
|
| 602 |
+
top={0}
|
| 603 |
+
backgroundColor={RGBA.fromInts(0, 0, 0, 160)}
|
| 604 |
+
onMouseUp={() => {
|
| 605 |
+
pop()
|
| 606 |
+
}}
|
| 607 |
+
>
|
| 608 |
+
<box
|
| 609 |
+
onMouseUp={(evt) => {
|
| 610 |
+
evt.stopPropagation()
|
| 611 |
+
}}
|
| 612 |
+
width={60}
|
| 613 |
+
maxWidth={dim().width - 2}
|
| 614 |
+
backgroundColor={skin.panel}
|
| 615 |
+
border
|
| 616 |
+
borderColor={skin.border}
|
| 617 |
+
paddingTop={1}
|
| 618 |
+
paddingBottom={1}
|
| 619 |
+
paddingLeft={2}
|
| 620 |
+
paddingRight={2}
|
| 621 |
+
gap={1}
|
| 622 |
+
flexDirection="column"
|
| 623 |
+
>
|
| 624 |
+
<text fg={skin.text}>
|
| 625 |
+
<b>{props.input.label} local overlay</b>
|
| 626 |
+
</text>
|
| 627 |
+
<text fg={skin.muted}>Plugin-owned stack depth: {value.local}</text>
|
| 628 |
+
<text fg={skin.muted}>
|
| 629 |
+
{shortcuts().local_push} push nested · {shortcuts().local_pop} pop/close
|
| 630 |
+
</text>
|
| 631 |
+
<box flexDirection="row" gap={1}>
|
| 632 |
+
<Btn txt="push" run={push} skin={skin} on />
|
| 633 |
+
<Btn txt="pop" run={pop} skin={skin} />
|
| 634 |
+
</box>
|
| 635 |
+
</box>
|
| 636 |
+
</box>
|
| 637 |
+
</box>
|
| 638 |
+
)
|
| 639 |
+
}
|
| 640 |
+
|
| 641 |
+
const Modal = (props: {
|
| 642 |
+
api: TuiPluginApi
|
| 643 |
+
input: Cfg
|
| 644 |
+
route: Route
|
| 645 |
+
keys: Keys
|
| 646 |
+
params?: Record<string, unknown>
|
| 647 |
+
}) => {
|
| 648 |
+
const Dialog = props.api.ui.Dialog
|
| 649 |
+
const value = parse(props.params)
|
| 650 |
+
const skin = tone(props.api)
|
| 651 |
+
|
| 652 |
+
useBindings(() => ({
|
| 653 |
+
enabled: () => props.api.route.current.name === props.route.modal,
|
| 654 |
+
commands: [
|
| 655 |
+
{
|
| 656 |
+
name: command.modal_accept,
|
| 657 |
+
run() {
|
| 658 |
+
props.api.route.navigate(props.route.screen, { ...parse(props.params), source: "modal" })
|
| 659 |
+
},
|
| 660 |
+
},
|
| 661 |
+
{
|
| 662 |
+
name: command.modal_close,
|
| 663 |
+
run() {
|
| 664 |
+
props.api.route.navigate("home")
|
| 665 |
+
},
|
| 666 |
+
},
|
| 667 |
+
],
|
| 668 |
+
bindings: props.keys.gather("smoke.modal", [command.modal_accept, command.modal_close]),
|
| 669 |
+
}))
|
| 670 |
+
const shortcuts = useKeymapSelector((keymap) => {
|
| 671 |
+
const bindings = keymap.getCommandBindings({
|
| 672 |
+
visibility: "registered",
|
| 673 |
+
commands: [command.modal, command.screen, command.modal_accept, command.modal_close],
|
| 674 |
+
})
|
| 675 |
+
|
| 676 |
+
return {
|
| 677 |
+
modal: props.api.keys.formatBindings(bindings.get(command.modal)) ?? "",
|
| 678 |
+
screen: props.api.keys.formatBindings(bindings.get(command.screen)) ?? "",
|
| 679 |
+
modal_accept: props.api.keys.formatBindings(bindings.get(command.modal_accept)) ?? "",
|
| 680 |
+
modal_close: props.api.keys.formatBindings(bindings.get(command.modal_close)) ?? "",
|
| 681 |
+
}
|
| 682 |
+
})
|
| 683 |
+
|
| 684 |
+
return (
|
| 685 |
+
<box width="100%" height="100%" backgroundColor={skin.panel}>
|
| 686 |
+
<Dialog onClose={() => props.api.route.navigate("home")}>
|
| 687 |
+
<box paddingBottom={1} paddingLeft={2} paddingRight={2} gap={1} flexDirection="column">
|
| 688 |
+
<text fg={skin.text}>
|
| 689 |
+
<b>{props.input.label} modal</b>
|
| 690 |
+
</text>
|
| 691 |
+
<text fg={skin.muted}>{shortcuts().modal} modal command</text>
|
| 692 |
+
<text fg={skin.muted}>{shortcuts().screen} screen command</text>
|
| 693 |
+
<text fg={skin.muted}>
|
| 694 |
+
{shortcuts().modal_accept} opens screen · {shortcuts().modal_close} closes
|
| 695 |
+
</text>
|
| 696 |
+
<box flexDirection="row" gap={1}>
|
| 697 |
+
<Btn
|
| 698 |
+
txt="open screen"
|
| 699 |
+
run={() => props.api.route.navigate(props.route.screen, { ...value, source: "modal" })}
|
| 700 |
+
skin={skin}
|
| 701 |
+
on
|
| 702 |
+
/>
|
| 703 |
+
<Btn txt="cancel" run={() => props.api.route.navigate("home")} skin={skin} />
|
| 704 |
+
</box>
|
| 705 |
+
</box>
|
| 706 |
+
</Dialog>
|
| 707 |
+
</box>
|
| 708 |
+
)
|
| 709 |
+
}
|
| 710 |
+
|
| 711 |
+
const home = (api: TuiPluginApi, input: Cfg) => ({
|
| 712 |
+
slots: {
|
| 713 |
+
home_logo(ctx) {
|
| 714 |
+
const map = ctx.theme.current
|
| 715 |
+
const skin = look(map)
|
| 716 |
+
const art = [
|
| 717 |
+
" $$\\",
|
| 718 |
+
" $$ |",
|
| 719 |
+
" $$$$$$$\\ $$$$$$\\$$$$\\ $$$$$$\\ $$ | $$\\ $$$$$$\\",
|
| 720 |
+
"$$ _____|$$ _$$ _$$\\ $$ __$$\\ $$ | $$ |$$ __$$\\",
|
| 721 |
+
"\\$$$$$$\\ $$ / $$ / $$ |$$ / $$ |$$$$$$ / $$$$$$$$ |",
|
| 722 |
+
" \\____$$\\ $$ | $$ | $$ |$$ | $$ |$$ _$$< $$ ____|",
|
| 723 |
+
"$$$$$$$ |$$ | $$ | $$ |\\$$$$$$ |$$ | \\$$\\ \\$$$$$$$\\",
|
| 724 |
+
"\\_______/ \\__| \\__| \\__| \\______/ \\__| \\__| \\_______|",
|
| 725 |
+
]
|
| 726 |
+
const fill = [
|
| 727 |
+
skin.accent,
|
| 728 |
+
skin.muted,
|
| 729 |
+
ink(map, "info", ui.accent),
|
| 730 |
+
skin.text,
|
| 731 |
+
ink(map, "success", ui.accent),
|
| 732 |
+
ink(map, "warning", ui.accent),
|
| 733 |
+
ink(map, "secondary", ui.accent),
|
| 734 |
+
ink(map, "error", ui.accent),
|
| 735 |
+
]
|
| 736 |
+
|
| 737 |
+
return (
|
| 738 |
+
<box flexDirection="column">
|
| 739 |
+
{art.map((line, i) => (
|
| 740 |
+
<text fg={fill[i]}>{line}</text>
|
| 741 |
+
))}
|
| 742 |
+
</box>
|
| 743 |
+
)
|
| 744 |
+
},
|
| 745 |
+
home_prompt(ctx, value) {
|
| 746 |
+
const skin = look(ctx.theme.current)
|
| 747 |
+
const Prompt = api.ui.Prompt
|
| 748 |
+
const Slot = api.ui.Slot
|
| 749 |
+
const normal = [
|
| 750 |
+
`[SMOKE] route check for ${input.label}`,
|
| 751 |
+
"[SMOKE] confirm home_prompt slot override",
|
| 752 |
+
"[SMOKE] verify prompt-right slot passthrough",
|
| 753 |
+
]
|
| 754 |
+
const shell = ["printf '[SMOKE] home prompt\n'", "git status --short", "bun --version"]
|
| 755 |
+
const hint = (
|
| 756 |
+
<box flexShrink={0} flexDirection="row" gap={1}>
|
| 757 |
+
<text fg={skin.muted}>
|
| 758 |
+
<span style={{ fg: skin.accent }}>•</span> smoke home prompt
|
| 759 |
+
</text>
|
| 760 |
+
</box>
|
| 761 |
+
)
|
| 762 |
+
|
| 763 |
+
return (
|
| 764 |
+
<Prompt
|
| 765 |
+
workspaceID={value.workspace_id}
|
| 766 |
+
hint={hint}
|
| 767 |
+
right={
|
| 768 |
+
<box flexDirection="row" gap={1}>
|
| 769 |
+
<Slot name="home_prompt_right" workspace_id={value.workspace_id} />
|
| 770 |
+
<Slot name="smoke_prompt_right" workspace_id={value.workspace_id} label={input.label} />
|
| 771 |
+
</box>
|
| 772 |
+
}
|
| 773 |
+
placeholders={{ normal, shell }}
|
| 774 |
+
/>
|
| 775 |
+
)
|
| 776 |
+
},
|
| 777 |
+
home_prompt_right(ctx, value) {
|
| 778 |
+
const skin = look(ctx.theme.current)
|
| 779 |
+
const id = value.workspace_id?.slice(0, 8) ?? "none"
|
| 780 |
+
return (
|
| 781 |
+
<text fg={skin.muted}>
|
| 782 |
+
<span style={{ fg: skin.accent }}>{input.label}</span> home:{id}
|
| 783 |
+
</text>
|
| 784 |
+
)
|
| 785 |
+
},
|
| 786 |
+
session_prompt_right(ctx, value) {
|
| 787 |
+
const skin = look(ctx.theme.current)
|
| 788 |
+
return (
|
| 789 |
+
<text fg={skin.muted}>
|
| 790 |
+
<span style={{ fg: skin.accent }}>{input.label}</span> session:{value.session_id.slice(0, 8)}
|
| 791 |
+
</text>
|
| 792 |
+
)
|
| 793 |
+
},
|
| 794 |
+
smoke_prompt_right(ctx, value) {
|
| 795 |
+
const skin = look(ctx.theme.current)
|
| 796 |
+
const id = typeof value.workspace_id === "string" ? value.workspace_id.slice(0, 8) : "none"
|
| 797 |
+
const label = typeof value.label === "string" ? value.label : input.label
|
| 798 |
+
return (
|
| 799 |
+
<text fg={skin.muted}>
|
| 800 |
+
<span style={{ fg: skin.accent }}>{label}</span> custom:{id}
|
| 801 |
+
</text>
|
| 802 |
+
)
|
| 803 |
+
},
|
| 804 |
+
home_bottom(ctx) {
|
| 805 |
+
const skin = look(ctx.theme.current)
|
| 806 |
+
const text = "extra content in the unified home bottom slot"
|
| 807 |
+
|
| 808 |
+
return (
|
| 809 |
+
<box width="100%" maxWidth={75} alignItems="center" paddingTop={1} flexShrink={0} gap={1}>
|
| 810 |
+
<box
|
| 811 |
+
border
|
| 812 |
+
borderColor={skin.border}
|
| 813 |
+
backgroundColor={skin.panel}
|
| 814 |
+
paddingTop={1}
|
| 815 |
+
paddingBottom={1}
|
| 816 |
+
paddingLeft={2}
|
| 817 |
+
paddingRight={2}
|
| 818 |
+
width="100%"
|
| 819 |
+
>
|
| 820 |
+
<text fg={skin.muted}>
|
| 821 |
+
<span style={{ fg: skin.accent }}>{input.label}</span> {text}
|
| 822 |
+
</text>
|
| 823 |
+
</box>
|
| 824 |
+
</box>
|
| 825 |
+
)
|
| 826 |
+
},
|
| 827 |
+
},
|
| 828 |
+
})
|
| 829 |
+
|
| 830 |
+
const block = (input: Cfg, order: number, title: string, text: string): TuiSlotPlugin => ({
|
| 831 |
+
order,
|
| 832 |
+
slots: {
|
| 833 |
+
sidebar_content(ctx, value) {
|
| 834 |
+
const skin = look(ctx.theme.current)
|
| 835 |
+
|
| 836 |
+
return (
|
| 837 |
+
<box
|
| 838 |
+
border
|
| 839 |
+
borderColor={skin.border}
|
| 840 |
+
backgroundColor={skin.panel}
|
| 841 |
+
paddingTop={1}
|
| 842 |
+
paddingBottom={1}
|
| 843 |
+
paddingLeft={2}
|
| 844 |
+
paddingRight={2}
|
| 845 |
+
flexDirection="column"
|
| 846 |
+
gap={1}
|
| 847 |
+
>
|
| 848 |
+
<text fg={skin.accent}>
|
| 849 |
+
<b>{title}</b>
|
| 850 |
+
</text>
|
| 851 |
+
<text fg={skin.text}>{text}</text>
|
| 852 |
+
<text fg={skin.muted}>
|
| 853 |
+
{input.label} order {order} · session {value.session_id.slice(0, 8)}
|
| 854 |
+
</text>
|
| 855 |
+
</box>
|
| 856 |
+
)
|
| 857 |
+
},
|
| 858 |
+
},
|
| 859 |
+
})
|
| 860 |
+
|
| 861 |
+
const slot = (api: TuiPluginApi, input: Cfg): TuiSlotPlugin[] => [
|
| 862 |
+
home(api, input),
|
| 863 |
+
block(input, 50, "Smoke above", "renders above internal sidebar blocks"),
|
| 864 |
+
block(input, 250, "Smoke between", "renders between internal sidebar blocks"),
|
| 865 |
+
block(input, 650, "Smoke below", "renders below internal sidebar blocks"),
|
| 866 |
+
]
|
| 867 |
+
|
| 868 |
+
const reg = (api: TuiPluginApi, input: Cfg, keys: Keys) => {
|
| 869 |
+
const route = names(input)
|
| 870 |
+
api.keymap.registerLayer({
|
| 871 |
+
commands: [
|
| 872 |
+
{
|
| 873 |
+
name: command.modal,
|
| 874 |
+
title: `${input.label} modal`,
|
| 875 |
+
category: "Plugin",
|
| 876 |
+
namespace: "palette",
|
| 877 |
+
slashName: "smoke",
|
| 878 |
+
run() {
|
| 879 |
+
api.route.navigate(route.modal, { source: "command" })
|
| 880 |
+
},
|
| 881 |
+
},
|
| 882 |
+
{
|
| 883 |
+
name: command.screen,
|
| 884 |
+
title: `${input.label} screen`,
|
| 885 |
+
category: "Plugin",
|
| 886 |
+
namespace: "palette",
|
| 887 |
+
slashName: "smoke-screen",
|
| 888 |
+
run() {
|
| 889 |
+
api.route.navigate(route.screen, { source: "command", tab: 0, count: 0 })
|
| 890 |
+
},
|
| 891 |
+
},
|
| 892 |
+
{
|
| 893 |
+
name: command.alert,
|
| 894 |
+
title: `${input.label} alert dialog`,
|
| 895 |
+
category: "Plugin",
|
| 896 |
+
namespace: "palette",
|
| 897 |
+
slashName: "smoke-alert",
|
| 898 |
+
run() {
|
| 899 |
+
warn(api, route, current(api, route))
|
| 900 |
+
},
|
| 901 |
+
},
|
| 902 |
+
{
|
| 903 |
+
name: command.confirm,
|
| 904 |
+
title: `${input.label} confirm dialog`,
|
| 905 |
+
category: "Plugin",
|
| 906 |
+
namespace: "palette",
|
| 907 |
+
slashName: "smoke-confirm",
|
| 908 |
+
run() {
|
| 909 |
+
check(api, route, current(api, route))
|
| 910 |
+
},
|
| 911 |
+
},
|
| 912 |
+
{
|
| 913 |
+
name: command.prompt,
|
| 914 |
+
title: `${input.label} prompt dialog`,
|
| 915 |
+
category: "Plugin",
|
| 916 |
+
namespace: "palette",
|
| 917 |
+
slashName: "smoke-prompt",
|
| 918 |
+
run() {
|
| 919 |
+
entry(api, route, current(api, route))
|
| 920 |
+
},
|
| 921 |
+
},
|
| 922 |
+
{
|
| 923 |
+
name: command.select,
|
| 924 |
+
title: `${input.label} select dialog`,
|
| 925 |
+
category: "Plugin",
|
| 926 |
+
namespace: "palette",
|
| 927 |
+
slashName: "smoke-select",
|
| 928 |
+
run() {
|
| 929 |
+
picker(api, route, current(api, route))
|
| 930 |
+
},
|
| 931 |
+
},
|
| 932 |
+
{
|
| 933 |
+
name: command.host,
|
| 934 |
+
title: `${input.label} host overlay`,
|
| 935 |
+
category: "Plugin",
|
| 936 |
+
namespace: "palette",
|
| 937 |
+
slashName: "smoke-host",
|
| 938 |
+
run() {
|
| 939 |
+
host(api, input, tone(api))
|
| 940 |
+
},
|
| 941 |
+
},
|
| 942 |
+
{
|
| 943 |
+
name: command.home,
|
| 944 |
+
title: `${input.label} go home`,
|
| 945 |
+
category: "Plugin",
|
| 946 |
+
namespace: "palette",
|
| 947 |
+
enabled: () => api.route.current.name !== "home",
|
| 948 |
+
run() {
|
| 949 |
+
api.route.navigate("home")
|
| 950 |
+
},
|
| 951 |
+
},
|
| 952 |
+
{
|
| 953 |
+
name: command.toast,
|
| 954 |
+
title: `${input.label} toast`,
|
| 955 |
+
category: "Plugin",
|
| 956 |
+
namespace: "palette",
|
| 957 |
+
run() {
|
| 958 |
+
api.ui.toast({
|
| 959 |
+
variant: "info",
|
| 960 |
+
title: "Smoke",
|
| 961 |
+
message: "Plugin toast works",
|
| 962 |
+
duration: 2000,
|
| 963 |
+
})
|
| 964 |
+
},
|
| 965 |
+
},
|
| 966 |
+
],
|
| 967 |
+
bindings: keys.gather("smoke.global", [
|
| 968 |
+
command.modal,
|
| 969 |
+
command.screen,
|
| 970 |
+
command.alert,
|
| 971 |
+
command.confirm,
|
| 972 |
+
command.prompt,
|
| 973 |
+
command.select,
|
| 974 |
+
command.host,
|
| 975 |
+
command.home,
|
| 976 |
+
command.toast,
|
| 977 |
+
]),
|
| 978 |
+
})
|
| 979 |
+
}
|
| 980 |
+
|
| 981 |
+
const tui: TuiPlugin = async (api, options, meta) => {
|
| 982 |
+
if (options?.enabled === false) return
|
| 983 |
+
|
| 984 |
+
await api.theme.install("./smoke-theme.json")
|
| 985 |
+
api.theme.set("smoke-theme")
|
| 986 |
+
|
| 987 |
+
const value = cfg(options)
|
| 988 |
+
const route = names(value)
|
| 989 |
+
const keys = createKeys(value.keybinds)
|
| 990 |
+
const fx = new VignetteEffect(value.vignette)
|
| 991 |
+
const post = fx.apply.bind(fx)
|
| 992 |
+
api.renderer.addPostProcessFn(post)
|
| 993 |
+
api.lifecycle.onDispose(() => {
|
| 994 |
+
api.renderer.removePostProcessFn(post)
|
| 995 |
+
})
|
| 996 |
+
|
| 997 |
+
api.route.register([
|
| 998 |
+
{
|
| 999 |
+
name: route.screen,
|
| 1000 |
+
render: ({ params }) => <Screen api={api} input={value} route={route} keys={keys} meta={meta} params={params} />,
|
| 1001 |
+
},
|
| 1002 |
+
{
|
| 1003 |
+
name: route.modal,
|
| 1004 |
+
render: ({ params }) => <Modal api={api} input={value} route={route} keys={keys} params={params} />,
|
| 1005 |
+
},
|
| 1006 |
+
])
|
| 1007 |
+
|
| 1008 |
+
reg(api, value, keys)
|
| 1009 |
+
for (const item of slot(api, value)) {
|
| 1010 |
+
api.slots.register(item)
|
| 1011 |
+
}
|
| 1012 |
+
}
|
| 1013 |
+
|
| 1014 |
+
const plugin: TuiPluginModule & { id: string } = {
|
| 1015 |
+
id: "tui-smoke",
|
| 1016 |
+
tui,
|
| 1017 |
+
}
|
| 1018 |
+
|
| 1019 |
+
export default plugin
|
.opencode/skills/effect/SKILL.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: effect
|
| 3 |
+
description: Work with Effect v4 / effect-smol TypeScript code in this repo
|
| 4 |
+
---
|
| 5 |
+
|
| 6 |
+
# Effect
|
| 7 |
+
|
| 8 |
+
This codebase uses Effect for typed, composable TypeScript services, schemas, and workflows.
|
| 9 |
+
|
| 10 |
+
## Source Of Truth
|
| 11 |
+
|
| 12 |
+
Use the current Effect v4 / effect-smol source, not memory or older Effect v2/v3 examples.
|
| 13 |
+
|
| 14 |
+
1. If `.opencode/references/effect-smol` is missing, clone `https://github.com/Effect-TS/effect-smol` there. Do this in the project, not in the skill folder.
|
| 15 |
+
2. Search `.opencode/references/effect-smol` for exact APIs, examples, tests, and naming patterns before answering or implementing Effect-specific code.
|
| 16 |
+
3. Also inspect existing repo code for local house style before introducing new patterns.
|
| 17 |
+
4. Prefer answers and implementations backed by specific source files or nearby repo examples.
|
| 18 |
+
|
| 19 |
+
## Guidelines
|
| 20 |
+
|
| 21 |
+
- Prefer current Effect v4 APIs and project-local patterns over old blog posts, examples, or package-memory guesses.
|
| 22 |
+
- Use `Effect.gen(function* () { ... })` for multi-step workflows.
|
| 23 |
+
- Use `Effect.fn("Name")` or `Effect.fnUntraced(...)` for named effects when adding reusable service methods or important workflows.
|
| 24 |
+
- Prefer Effect `Schema` for API and domain data shapes. Use branded schemas for IDs and `Schema.TaggedErrorClass` for typed domain errors when modeling new error surfaces.
|
| 25 |
+
- Keep HTTP handlers thin: decode input, read request context, call services, and map transport errors. Put business rules in services.
|
| 26 |
+
- In Effect service code, prefer Effect-aware platform abstractions and dependencies over ad hoc promises where the surrounding code already does so.
|
| 27 |
+
- Keep layer composition explicit. Avoid broad hidden provisioning that makes missing dependencies hard to see.
|
| 28 |
+
- In tests, prefer the repo's existing Effect test helpers and live tests for filesystem, git, child process, locks, or timing behavior.
|
| 29 |
+
- Do not introduce `any`, non-null assertions, unchecked casts, or older Effect APIs just to satisfy types.
|
| 30 |
+
- Do not answer from memory. Verify against `.opencode/references/effect-smol` or nearby code first.
|
| 31 |
+
|
| 32 |
+
## Testing Patterns
|
| 33 |
+
|
| 34 |
+
- Use `testEffect(...)` from `packages/opencode/test/lib/effect.ts` for tests that exercise Effect services, layers, runtime context, scoped resources, or platform integrations.
|
| 35 |
+
- Use `it.live(...)` for filesystem, git repositories, HTTP servers, sockets, child processes, locks, real time, and other live platform behavior.
|
| 36 |
+
- Run tests from package directories such as `packages/opencode`; never run package tests from the repo root.
|
| 37 |
+
- Prefer explicit test layers over ad hoc managed runtimes. Keep dependency provisioning visible in the test file.
|
| 38 |
+
- Use scoped fixtures and finalizers for resources that must be cleaned up, including temporary directories, flags, databases, fibers, servers, and global state.
|
.opencode/skills/rtl-aware-development/SKILL.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: rtl-aware-development
|
| 3 |
+
description: OpenCode Desktop should be RTL-aware. Use when implementing or reviewing RTL/LTR behavior in the web app, desktop app, CSS, menus, scrolling, resizing, icons, mixed-direction text, or Electron title bars.
|
| 4 |
+
---
|
| 5 |
+
|
| 6 |
+
# RTL-Aware Development
|
| 7 |
+
|
| 8 |
+
Treat direction as independent from language. Test English in both directions as well as real RTL and mixed-script content.
|
| 9 |
+
|
| 10 |
+
## Guidelines
|
| 11 |
+
|
| 12 |
+
- Set `lang` and `dir` on the document, and propagate direction through component providers used by portaled menus and popovers. Do not change the selected locale merely to force RTL.
|
| 13 |
+
- Keep DOM and focus order semantic. Flexbox and Grid already follow `dir`; do not add `row-reverse`, CSS `order`, or reversed markup just to mirror a layout.
|
| 14 |
+
- Prefer logical CSS for semantic layout. Reserve physical coordinates for pointer positions, canvas geometry, native window controls, and other genuinely physical placement.
|
| 15 |
+
|
| 16 |
+
```css
|
| 17 |
+
/* Avoid */
|
| 18 |
+
padding-left: 12px;
|
| 19 |
+
right: 0;
|
| 20 |
+
border-right: 1px solid;
|
| 21 |
+
text-align: left;
|
| 22 |
+
|
| 23 |
+
/* Prefer */
|
| 24 |
+
padding-inline-start: 12px;
|
| 25 |
+
inset-inline-end: 0;
|
| 26 |
+
border-inline-end: 1px solid;
|
| 27 |
+
text-align: start;
|
| 28 |
+
```
|
| 29 |
+
|
| 30 |
+
- Isolate mixed-direction text. Use `dir="auto"` or `<bdi>` for unknown text; keep code, URLs, IDs, and filesystem paths LTR without forcing the surrounding component LTR.
|
| 31 |
+
|
| 32 |
+
```html
|
| 33 |
+
<span class="file-row"><bdi dir="auto">README.md</bdi></span> <bdi dir="ltr"><code>C:\src\app.ts</code></bdi>
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
- Mirror directional meaning, not every image. Back/forward, previous/next, disclosure, indentation, and directional progress may need mirroring. Do not mirror brands, clocks, media controls, charts, or text. Reverse physical gradients, `translateX`, SVG transforms, and animation deltas explicitly.
|
| 37 |
+
- Map interactions through direction. `clientX` remains physical; resizing a logical edge needs an RTL-aware delta. Logical previous/next keyboard controls may swap ArrowLeft/ArrowRight. Follow the relevant WAI-ARIA widget pattern.
|
| 38 |
+
- Do not assume LTR scrolling. RTL `scrollLeft` can start at `0` and become negative. Prefer `scrollIntoView({ inline: "nearest" })` or a tested direction-normalizing helper.
|
| 39 |
+
- For Electron title bars, prefer native caption controls and use `titleBarOverlay` plus `env(titlebar-area-*)` for the safe content rectangle. Keep Windows/macOS native-control avoidance and `trafficLightPosition` physical; keep app navigation inside that rectangle logical. Mark interactive titlebar children `app-region: no-drag`.
|
| 40 |
+
- Verify behavior, not screenshots alone. Check computed styles, pseudo-element geometry, hit zones, focus order, keyboard behavior, submenu direction, zoom/scaling, and both LTR and RTL scroll endpoints.
|
| 41 |
+
|
| 42 |
+
## Test Matrix
|
| 43 |
+
|
| 44 |
+
- English + LTR
|
| 45 |
+
- English + forced RTL
|
| 46 |
+
- A real RTL locale + RTL
|
| 47 |
+
- Mixed RTL/LTR content, long labels, numbers, code, and paths
|
| 48 |
+
- Keyboard, pointer resize, scrolling, menus/submenus, and Electron titlebar controls in both directions
|
| 49 |
+
|
| 50 |
+
## References
|
| 51 |
+
|
| 52 |
+
- [RTL Styling 101, Ahmad Shadeed](https://rtlstyling.com/posts/rtl-styling/)
|
| 53 |
+
- [CSS-Tricks: RTL Styling 101](https://css-tricks.com/rtl-styling-101/)
|
| 54 |
+
- [CSS-Tricks: CSS Logical Properties and Values](https://css-tricks.com/css-logical-properties-and-values/)
|
| 55 |
+
- [W3C: Structural markup and right-to-left text](https://www.w3.org/International/questions/qa-html-dir)
|
| 56 |
+
- [W3C: Inline bidirectional markup](https://www.w3.org/International/articles/inline-bidi-markup/)
|
| 57 |
+
- [MDN: CSS logical properties and values](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Logical_properties_and_values)
|
| 58 |
+
- [MDN: `dir`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/dir)
|
| 59 |
+
- [MDN: `scrollLeft`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft)
|
| 60 |
+
- [web.dev: Logical properties](https://web.dev/learn/css/logical-properties/)
|
| 61 |
+
- [Electron: Custom title bar](https://www.electronjs.org/docs/latest/tutorial/custom-title-bar)
|
| 62 |
+
- [WAI-ARIA: Window splitter pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/)
|
| 63 |
+
- [Kobalte: I18n Provider](https://kobalte.dev/docs/core/components/i18n-provider/)
|
.opencode/themes/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
smoke-theme.json
|
.opencode/themes/mytheme.json
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://opencode.ai/theme.json",
|
| 3 |
+
"defs": {
|
| 4 |
+
"nord0": "#2E3440",
|
| 5 |
+
"nord1": "#3B4252",
|
| 6 |
+
"nord2": "#434C5E",
|
| 7 |
+
"nord3": "#4C566A",
|
| 8 |
+
"nord4": "#D8DEE9",
|
| 9 |
+
"nord5": "#E5E9F0",
|
| 10 |
+
"nord6": "#ECEFF4",
|
| 11 |
+
"nord7": "#8FBCBB",
|
| 12 |
+
"nord8": "#88C0D0",
|
| 13 |
+
"nord9": "#81A1C1",
|
| 14 |
+
"nord10": "#5E81AC",
|
| 15 |
+
"nord11": "#BF616A",
|
| 16 |
+
"nord12": "#D08770",
|
| 17 |
+
"nord13": "#EBCB8B",
|
| 18 |
+
"nord14": "#A3BE8C",
|
| 19 |
+
"nord15": "#B48EAD"
|
| 20 |
+
},
|
| 21 |
+
"theme": {
|
| 22 |
+
"primary": {
|
| 23 |
+
"dark": "nord8",
|
| 24 |
+
"light": "nord10"
|
| 25 |
+
},
|
| 26 |
+
"secondary": {
|
| 27 |
+
"dark": "nord9",
|
| 28 |
+
"light": "nord9"
|
| 29 |
+
},
|
| 30 |
+
"accent": {
|
| 31 |
+
"dark": "nord7",
|
| 32 |
+
"light": "nord7"
|
| 33 |
+
},
|
| 34 |
+
"error": {
|
| 35 |
+
"dark": "nord11",
|
| 36 |
+
"light": "nord11"
|
| 37 |
+
},
|
| 38 |
+
"warning": {
|
| 39 |
+
"dark": "nord12",
|
| 40 |
+
"light": "nord12"
|
| 41 |
+
},
|
| 42 |
+
"success": {
|
| 43 |
+
"dark": "nord14",
|
| 44 |
+
"light": "nord14"
|
| 45 |
+
},
|
| 46 |
+
"info": {
|
| 47 |
+
"dark": "nord8",
|
| 48 |
+
"light": "nord10"
|
| 49 |
+
},
|
| 50 |
+
"text": {
|
| 51 |
+
"dark": "nord4",
|
| 52 |
+
"light": "nord0"
|
| 53 |
+
},
|
| 54 |
+
"textMuted": {
|
| 55 |
+
"dark": "nord3",
|
| 56 |
+
"light": "nord1"
|
| 57 |
+
},
|
| 58 |
+
"background": {
|
| 59 |
+
"dark": "nord0",
|
| 60 |
+
"light": "nord6"
|
| 61 |
+
},
|
| 62 |
+
"backgroundPanel": {
|
| 63 |
+
"dark": "nord1",
|
| 64 |
+
"light": "nord5"
|
| 65 |
+
},
|
| 66 |
+
"backgroundElement": {
|
| 67 |
+
"dark": "nord1",
|
| 68 |
+
"light": "nord4"
|
| 69 |
+
},
|
| 70 |
+
"border": {
|
| 71 |
+
"dark": "nord2",
|
| 72 |
+
"light": "nord3"
|
| 73 |
+
},
|
| 74 |
+
"borderActive": {
|
| 75 |
+
"dark": "nord3",
|
| 76 |
+
"light": "nord2"
|
| 77 |
+
},
|
| 78 |
+
"borderSubtle": {
|
| 79 |
+
"dark": "nord2",
|
| 80 |
+
"light": "nord3"
|
| 81 |
+
},
|
| 82 |
+
"diffAdded": {
|
| 83 |
+
"dark": "nord14",
|
| 84 |
+
"light": "nord14"
|
| 85 |
+
},
|
| 86 |
+
"diffRemoved": {
|
| 87 |
+
"dark": "nord11",
|
| 88 |
+
"light": "nord11"
|
| 89 |
+
},
|
| 90 |
+
"diffContext": {
|
| 91 |
+
"dark": "nord3",
|
| 92 |
+
"light": "nord3"
|
| 93 |
+
},
|
| 94 |
+
"diffHunkHeader": {
|
| 95 |
+
"dark": "nord3",
|
| 96 |
+
"light": "nord3"
|
| 97 |
+
},
|
| 98 |
+
"diffHighlightAdded": {
|
| 99 |
+
"dark": "nord14",
|
| 100 |
+
"light": "nord14"
|
| 101 |
+
},
|
| 102 |
+
"diffHighlightRemoved": {
|
| 103 |
+
"dark": "nord11",
|
| 104 |
+
"light": "nord11"
|
| 105 |
+
},
|
| 106 |
+
"diffAddedBg": {
|
| 107 |
+
"dark": "#3B4252",
|
| 108 |
+
"light": "#E5E9F0"
|
| 109 |
+
},
|
| 110 |
+
"diffRemovedBg": {
|
| 111 |
+
"dark": "#3B4252",
|
| 112 |
+
"light": "#E5E9F0"
|
| 113 |
+
},
|
| 114 |
+
"diffContextBg": {
|
| 115 |
+
"dark": "nord1",
|
| 116 |
+
"light": "nord5"
|
| 117 |
+
},
|
| 118 |
+
"diffLineNumber": {
|
| 119 |
+
"dark": "#abafb7",
|
| 120 |
+
"light": "textMuted"
|
| 121 |
+
},
|
| 122 |
+
"diffAddedLineNumberBg": {
|
| 123 |
+
"dark": "#3B4252",
|
| 124 |
+
"light": "#E5E9F0"
|
| 125 |
+
},
|
| 126 |
+
"diffRemovedLineNumberBg": {
|
| 127 |
+
"dark": "#3B4252",
|
| 128 |
+
"light": "#E5E9F0"
|
| 129 |
+
},
|
| 130 |
+
"markdownText": {
|
| 131 |
+
"dark": "nord4",
|
| 132 |
+
"light": "nord0"
|
| 133 |
+
},
|
| 134 |
+
"markdownHeading": {
|
| 135 |
+
"dark": "nord8",
|
| 136 |
+
"light": "nord10"
|
| 137 |
+
},
|
| 138 |
+
"markdownLink": {
|
| 139 |
+
"dark": "nord9",
|
| 140 |
+
"light": "nord9"
|
| 141 |
+
},
|
| 142 |
+
"markdownLinkText": {
|
| 143 |
+
"dark": "nord7",
|
| 144 |
+
"light": "nord7"
|
| 145 |
+
},
|
| 146 |
+
"markdownCode": {
|
| 147 |
+
"dark": "nord14",
|
| 148 |
+
"light": "nord14"
|
| 149 |
+
},
|
| 150 |
+
"markdownBlockQuote": {
|
| 151 |
+
"dark": "nord3",
|
| 152 |
+
"light": "nord3"
|
| 153 |
+
},
|
| 154 |
+
"markdownEmph": {
|
| 155 |
+
"dark": "nord12",
|
| 156 |
+
"light": "nord12"
|
| 157 |
+
},
|
| 158 |
+
"markdownStrong": {
|
| 159 |
+
"dark": "nord13",
|
| 160 |
+
"light": "nord13"
|
| 161 |
+
},
|
| 162 |
+
"markdownHorizontalRule": {
|
| 163 |
+
"dark": "nord3",
|
| 164 |
+
"light": "nord3"
|
| 165 |
+
},
|
| 166 |
+
"markdownListItem": {
|
| 167 |
+
"dark": "nord8",
|
| 168 |
+
"light": "nord10"
|
| 169 |
+
},
|
| 170 |
+
"markdownListEnumeration": {
|
| 171 |
+
"dark": "nord7",
|
| 172 |
+
"light": "nord7"
|
| 173 |
+
},
|
| 174 |
+
"markdownImage": {
|
| 175 |
+
"dark": "nord9",
|
| 176 |
+
"light": "nord9"
|
| 177 |
+
},
|
| 178 |
+
"markdownImageText": {
|
| 179 |
+
"dark": "nord7",
|
| 180 |
+
"light": "nord7"
|
| 181 |
+
},
|
| 182 |
+
"markdownCodeBlock": {
|
| 183 |
+
"dark": "nord4",
|
| 184 |
+
"light": "nord0"
|
| 185 |
+
},
|
| 186 |
+
"syntaxComment": {
|
| 187 |
+
"dark": "nord3",
|
| 188 |
+
"light": "nord3"
|
| 189 |
+
},
|
| 190 |
+
"syntaxKeyword": {
|
| 191 |
+
"dark": "nord9",
|
| 192 |
+
"light": "nord9"
|
| 193 |
+
},
|
| 194 |
+
"syntaxFunction": {
|
| 195 |
+
"dark": "nord8",
|
| 196 |
+
"light": "nord8"
|
| 197 |
+
},
|
| 198 |
+
"syntaxVariable": {
|
| 199 |
+
"dark": "nord7",
|
| 200 |
+
"light": "nord7"
|
| 201 |
+
},
|
| 202 |
+
"syntaxString": {
|
| 203 |
+
"dark": "nord14",
|
| 204 |
+
"light": "nord14"
|
| 205 |
+
},
|
| 206 |
+
"syntaxNumber": {
|
| 207 |
+
"dark": "nord15",
|
| 208 |
+
"light": "nord15"
|
| 209 |
+
},
|
| 210 |
+
"syntaxType": {
|
| 211 |
+
"dark": "nord7",
|
| 212 |
+
"light": "nord7"
|
| 213 |
+
},
|
| 214 |
+
"syntaxOperator": {
|
| 215 |
+
"dark": "nord9",
|
| 216 |
+
"light": "nord9"
|
| 217 |
+
},
|
| 218 |
+
"syntaxPunctuation": {
|
| 219 |
+
"dark": "nord4",
|
| 220 |
+
"light": "nord0"
|
| 221 |
+
}
|
| 222 |
+
}
|
| 223 |
+
}
|
.opencode/tool/github-pr-search.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// <reference path="../env.d.ts" />
|
| 2 |
+
import { tool } from "@opencode-ai/plugin"
|
| 3 |
+
async function githubFetch(endpoint: string, options: RequestInit = {}) {
|
| 4 |
+
const response = await fetch(`https://api.github.com${endpoint}`, {
|
| 5 |
+
...options,
|
| 6 |
+
headers: {
|
| 7 |
+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
|
| 8 |
+
Accept: "application/vnd.github+json",
|
| 9 |
+
"Content-Type": "application/json",
|
| 10 |
+
...(options.headers instanceof Headers ? Object.fromEntries(options.headers.entries()) : options.headers),
|
| 11 |
+
},
|
| 12 |
+
})
|
| 13 |
+
if (!response.ok) {
|
| 14 |
+
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`)
|
| 15 |
+
}
|
| 16 |
+
return response.json()
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
interface PR {
|
| 20 |
+
title: string
|
| 21 |
+
html_url: string
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
export default tool({
|
| 25 |
+
description: `Use this tool to search GitHub pull requests by title and description.
|
| 26 |
+
|
| 27 |
+
This tool searches PRs in the anomalyco/opencode repository and returns LLM-friendly results including:
|
| 28 |
+
- PR number and title
|
| 29 |
+
- Author
|
| 30 |
+
- State (open/closed/merged)
|
| 31 |
+
- Labels
|
| 32 |
+
- Description snippet
|
| 33 |
+
|
| 34 |
+
Use the query parameter to search for keywords that might appear in PR titles or descriptions.`,
|
| 35 |
+
args: {
|
| 36 |
+
query: tool.schema.string().describe("Search query for PR titles and descriptions"),
|
| 37 |
+
limit: tool.schema.number().describe("Maximum number of results to return").default(10),
|
| 38 |
+
offset: tool.schema.number().describe("Number of results to skip for pagination").default(0),
|
| 39 |
+
},
|
| 40 |
+
async execute(args) {
|
| 41 |
+
const owner = "anomalyco"
|
| 42 |
+
const repo = "opencode"
|
| 43 |
+
|
| 44 |
+
const page = Math.floor(args.offset / args.limit) + 1
|
| 45 |
+
const searchQuery = encodeURIComponent(`${args.query} repo:${owner}/${repo} type:pr state:open`)
|
| 46 |
+
const result = await githubFetch(
|
| 47 |
+
`/search/issues?q=${searchQuery}&per_page=${args.limit}&page=${page}&sort=updated&order=desc`,
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
if (result.total_count === 0) {
|
| 51 |
+
return `No PRs found matching "${args.query}"`
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
const prs = result.items as PR[]
|
| 55 |
+
|
| 56 |
+
if (prs.length === 0) {
|
| 57 |
+
return `No other PRs found matching "${args.query}"`
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
const formatted = prs.map((pr) => `${pr.title}\n${pr.html_url}`).join("\n\n")
|
| 61 |
+
|
| 62 |
+
return `Found ${result.total_count} PRs (showing ${prs.length}):\n\n${formatted}`
|
| 63 |
+
},
|
| 64 |
+
})
|
.opencode/tool/github-triage.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// <reference path="../env.d.ts" />
|
| 2 |
+
import { tool } from "@opencode-ai/plugin"
|
| 3 |
+
|
| 4 |
+
const TEAM = {
|
| 5 |
+
tui: ["kommander", "simonklee"],
|
| 6 |
+
desktop_web: ["Hona", "Brendonovich"],
|
| 7 |
+
core: ["jlongster", "rekram1-node", "neriousy", "nexxeln", "kitlangton"],
|
| 8 |
+
inference: ["fwang", "MrMushrooooom", "starptech"],
|
| 9 |
+
windows: ["Hona"],
|
| 10 |
+
} as const
|
| 11 |
+
|
| 12 |
+
function pick<T>(items: readonly T[]) {
|
| 13 |
+
return items[Math.floor(Math.random() * items.length)]!
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
function getIssueNumber(): number {
|
| 17 |
+
const issue = parseInt(process.env.ISSUE_NUMBER ?? "", 10)
|
| 18 |
+
if (!issue) throw new Error("ISSUE_NUMBER env var not set")
|
| 19 |
+
return issue
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
async function githubFetch(endpoint: string, options: RequestInit = {}) {
|
| 23 |
+
const response = await fetch(`https://api.github.com${endpoint}`, {
|
| 24 |
+
...options,
|
| 25 |
+
headers: {
|
| 26 |
+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
|
| 27 |
+
Accept: "application/vnd.github+json",
|
| 28 |
+
"Content-Type": "application/json",
|
| 29 |
+
...(options.headers instanceof Headers ? Object.fromEntries(options.headers.entries()) : options.headers),
|
| 30 |
+
},
|
| 31 |
+
})
|
| 32 |
+
if (!response.ok) {
|
| 33 |
+
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`)
|
| 34 |
+
}
|
| 35 |
+
return response.json()
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
export default tool({
|
| 39 |
+
description: `Use this tool to assign a GitHub issue.
|
| 40 |
+
|
| 41 |
+
Provide the team that should own the issue. This tool picks a random assignee from that team and does not apply labels.`,
|
| 42 |
+
args: {
|
| 43 |
+
team: tool.schema
|
| 44 |
+
.enum(Object.keys(TEAM) as [keyof typeof TEAM, ...(keyof typeof TEAM)[]])
|
| 45 |
+
.describe("The owning team"),
|
| 46 |
+
},
|
| 47 |
+
async execute(args) {
|
| 48 |
+
const issue = getIssueNumber()
|
| 49 |
+
const owner = "anomalyco"
|
| 50 |
+
const repo = "opencode"
|
| 51 |
+
const assignee = pick(TEAM[args.team])
|
| 52 |
+
|
| 53 |
+
await githubFetch(`/repos/${owner}/${repo}/issues/${issue}/assignees`, {
|
| 54 |
+
method: "POST",
|
| 55 |
+
body: JSON.stringify({ assignees: [assignee] }),
|
| 56 |
+
})
|
| 57 |
+
|
| 58 |
+
return `Assigned @${assignee} from ${args.team} to issue #${issue}`
|
| 59 |
+
},
|
| 60 |
+
})
|
artifacts/glm52-rise-video/.gitignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules
|
| 2 |
+
.remotion
|
| 3 |
+
out/frame-*.png
|
artifacts/glm52-rise-video/bun.lock
ADDED
|
@@ -0,0 +1,483 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"lockfileVersion": 1,
|
| 3 |
+
"configVersion": 1,
|
| 4 |
+
"workspaces": {
|
| 5 |
+
"": {
|
| 6 |
+
"name": "glm52-rise-video",
|
| 7 |
+
"dependencies": {
|
| 8 |
+
"@remotion/cli": "^4.0.384",
|
| 9 |
+
"react": "^19.2.3",
|
| 10 |
+
"react-dom": "^19.2.3",
|
| 11 |
+
"remotion": "^4.0.384",
|
| 12 |
+
},
|
| 13 |
+
"devDependencies": {
|
| 14 |
+
"@types/react": "^19.2.8",
|
| 15 |
+
"@types/react-dom": "^19.2.3",
|
| 16 |
+
"typescript": "^5.8.2",
|
| 17 |
+
},
|
| 18 |
+
},
|
| 19 |
+
},
|
| 20 |
+
"packages": {
|
| 21 |
+
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="],
|
| 22 |
+
|
| 23 |
+
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="],
|
| 24 |
+
|
| 25 |
+
"@babel/parser": ["@babel/parser@7.24.1", "", { "bin": "./bin/babel-parser.js" }, "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg=="],
|
| 26 |
+
|
| 27 |
+
"@babel/types": ["@babel/types@7.24.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w=="],
|
| 28 |
+
|
| 29 |
+
"@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="],
|
| 30 |
+
|
| 31 |
+
"@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="],
|
| 32 |
+
|
| 33 |
+
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="],
|
| 34 |
+
|
| 35 |
+
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="],
|
| 36 |
+
|
| 37 |
+
"@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="],
|
| 38 |
+
|
| 39 |
+
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="],
|
| 40 |
+
|
| 41 |
+
"@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="],
|
| 42 |
+
|
| 43 |
+
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="],
|
| 44 |
+
|
| 45 |
+
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="],
|
| 46 |
+
|
| 47 |
+
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="],
|
| 48 |
+
|
| 49 |
+
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="],
|
| 50 |
+
|
| 51 |
+
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="],
|
| 52 |
+
|
| 53 |
+
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="],
|
| 54 |
+
|
| 55 |
+
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="],
|
| 56 |
+
|
| 57 |
+
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="],
|
| 58 |
+
|
| 59 |
+
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="],
|
| 60 |
+
|
| 61 |
+
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="],
|
| 62 |
+
|
| 63 |
+
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="],
|
| 64 |
+
|
| 65 |
+
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="],
|
| 66 |
+
|
| 67 |
+
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="],
|
| 68 |
+
|
| 69 |
+
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="],
|
| 70 |
+
|
| 71 |
+
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="],
|
| 72 |
+
|
| 73 |
+
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="],
|
| 74 |
+
|
| 75 |
+
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="],
|
| 76 |
+
|
| 77 |
+
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="],
|
| 78 |
+
|
| 79 |
+
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="],
|
| 80 |
+
|
| 81 |
+
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="],
|
| 82 |
+
|
| 83 |
+
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="],
|
| 84 |
+
|
| 85 |
+
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="],
|
| 86 |
+
|
| 87 |
+
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
| 88 |
+
|
| 89 |
+
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
| 90 |
+
|
| 91 |
+
"@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="],
|
| 92 |
+
|
| 93 |
+
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
| 94 |
+
|
| 95 |
+
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
| 96 |
+
|
| 97 |
+
"@mediabunny/aac-encoder": ["@mediabunny/aac-encoder@1.47.0", "", { "peerDependencies": { "mediabunny": "^1.0.0" } }, "sha512-JNzgdJoHMFFnv5imi1+dmjZMudsJ1zNCUCEkKjBh90cqGhAFg8xu4V2gsyxE2i6oq/YpWx23P+OvoANLSMcDzA=="],
|
| 98 |
+
|
| 99 |
+
"@mediabunny/flac-encoder": ["@mediabunny/flac-encoder@1.47.0", "", { "peerDependencies": { "mediabunny": "^1.0.0" } }, "sha512-VpKmJO0xlYcFCRD6JvJlMbNQ6d/6YMHdO1gFIqWlZABHjSSL6BquNNEgWSCv5vdF8ELDBwIYBVZEslakIB/7GA=="],
|
| 100 |
+
|
| 101 |
+
"@mediabunny/mp3-encoder": ["@mediabunny/mp3-encoder@1.47.0", "", { "peerDependencies": { "mediabunny": "^1.0.0" } }, "sha512-JyzZyGeGRm2HVUQaGJ/VZT9OG+kG00mA8SLP/f3CO7+qWAmBncKc16WYXWHbZEo8Jn/ZGA6De32S5R2bTQbDqA=="],
|
| 102 |
+
|
| 103 |
+
"@module-federation/error-codes": ["@module-federation/error-codes@0.22.0", "", {}, "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug=="],
|
| 104 |
+
|
| 105 |
+
"@module-federation/runtime": ["@module-federation/runtime@0.22.0", "", { "dependencies": { "@module-federation/error-codes": "0.22.0", "@module-federation/runtime-core": "0.22.0", "@module-federation/sdk": "0.22.0" } }, "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA=="],
|
| 106 |
+
|
| 107 |
+
"@module-federation/runtime-core": ["@module-federation/runtime-core@0.22.0", "", { "dependencies": { "@module-federation/error-codes": "0.22.0", "@module-federation/sdk": "0.22.0" } }, "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA=="],
|
| 108 |
+
|
| 109 |
+
"@module-federation/runtime-tools": ["@module-federation/runtime-tools@0.22.0", "", { "dependencies": { "@module-federation/runtime": "0.22.0", "@module-federation/webpack-bundler-runtime": "0.22.0" } }, "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA=="],
|
| 110 |
+
|
| 111 |
+
"@module-federation/sdk": ["@module-federation/sdk@0.22.0", "", {}, "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g=="],
|
| 112 |
+
|
| 113 |
+
"@module-federation/webpack-bundler-runtime": ["@module-federation/webpack-bundler-runtime@0.22.0", "", { "dependencies": { "@module-federation/runtime": "0.22.0", "@module-federation/sdk": "0.22.0" } }, "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA=="],
|
| 114 |
+
|
| 115 |
+
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" } }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="],
|
| 116 |
+
|
| 117 |
+
"@remotion/bundler": ["@remotion/bundler@4.0.483", "", { "dependencies": { "@remotion/media-parser": "4.0.483", "@remotion/studio": "4.0.483", "@remotion/studio-shared": "4.0.483", "@remotion/timeline-utils": "4.0.483", "@rspack/core": "1.7.11", "@rspack/plugin-react-refresh": "1.6.1", "css-loader": "7.1.4", "esbuild": "0.28.1", "react-refresh": "0.18.0", "remotion": "4.0.483", "style-loader": "4.0.0", "webpack": "5.105.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-5fQRMYgr2sxZPBOThnIVuFwHBq/FhusJ+Ke6xopga8io8ecK/mj9GaRXC3tgfMa+YWuu8ZSXZ0U9EsMZjjP5YQ=="],
|
| 118 |
+
|
| 119 |
+
"@remotion/canvas-capture": ["@remotion/canvas-capture@4.0.483", "", { "dependencies": { "mediabunny": "1.47.0", "remotion": "4.0.483" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-JABgbfvXwjFp1E61tlDN9gVAH8OoeF4kUUELNwG9kcNOE4ex8+vCYEO6VKIaXZ4l8A1PEAQ5EK//NheTJ80gfw=="],
|
| 120 |
+
|
| 121 |
+
"@remotion/cli": ["@remotion/cli@4.0.483", "", { "dependencies": { "@remotion/bundler": "4.0.483", "@remotion/media-utils": "4.0.483", "@remotion/player": "4.0.483", "@remotion/renderer": "4.0.483", "@remotion/studio": "4.0.483", "@remotion/studio-server": "4.0.483", "@remotion/studio-shared": "4.0.483", "dotenv": "17.3.1", "minimist": "1.2.6", "prompts": "2.4.2", "remotion": "4.0.483" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" }, "bin": { "remotion": "remotion-cli.js", "remotionb": "remotionb-cli.js", "remotiond": "remotiond-cli.js" } }, "sha512-z4TQcgTfQbSIV4GQpCvIihDL77M+leQelbxv962PmfSKTT7z3XnNN732PcZ4sei2+Xg+d2SD95K4tI5XBYs5Gw=="],
|
| 122 |
+
|
| 123 |
+
"@remotion/compositor-darwin-arm64": ["@remotion/compositor-darwin-arm64@4.0.483", "", { "os": "darwin", "cpu": "arm64" }, "sha512-CkEJXouGEoCs5PX3KOufkXrlT/Kgn0ZF7SEQ4meCYGYMZD+QPVtsmS1MXH8pQ4RHlFO6Tk7g0CIHMT3Y4yzpuA=="],
|
| 124 |
+
|
| 125 |
+
"@remotion/compositor-darwin-x64": ["@remotion/compositor-darwin-x64@4.0.483", "", { "os": "darwin", "cpu": "x64" }, "sha512-vDZK5U8FYbHGMjFC2lUgJRBz8KXwbwFSvEQi8FATD0roNg75SoaEJWrqAOIVv8v5eBjPvo18znDc36NLRYn1Eg=="],
|
| 126 |
+
|
| 127 |
+
"@remotion/compositor-linux-arm64-gnu": ["@remotion/compositor-linux-arm64-gnu@4.0.483", "", { "os": "linux", "cpu": "arm64" }, "sha512-1LzfYDY/DQxy3MIc9pCbTn1ObcBDcyI6MzODOwe1bTZl8TZxdUUt1M3hDrQ60AB6iHwruBAnzT9dnogiMIdSew=="],
|
| 128 |
+
|
| 129 |
+
"@remotion/compositor-linux-arm64-musl": ["@remotion/compositor-linux-arm64-musl@4.0.483", "", { "os": "linux", "cpu": "arm64" }, "sha512-nG1btxg0HXuLzulIqAg9NnxWyewZNrA0iLe82HdniaJjeWLORreGo4cEEJz1SjbDpQuPEY562XGkTO2DLKK5mA=="],
|
| 130 |
+
|
| 131 |
+
"@remotion/compositor-linux-x64-gnu": ["@remotion/compositor-linux-x64-gnu@4.0.483", "", { "os": "linux", "cpu": "x64" }, "sha512-CV4h6r2rNYh4P8utUzP6RM2vW2vq43nA3IvVOwRSuh9LwJh/7rwG53Oco4HanY/sstaNuymGpT57wdXwONU5CQ=="],
|
| 132 |
+
|
| 133 |
+
"@remotion/compositor-linux-x64-musl": ["@remotion/compositor-linux-x64-musl@4.0.483", "", { "os": "linux", "cpu": "x64" }, "sha512-moKvavbkoz5nteJZA4K6LMgTTlewhwIbtO7DYARZ3LK3ClGUKnYfFcmaPS15hMun02JPTOMIWbrlaszdR75mxA=="],
|
| 134 |
+
|
| 135 |
+
"@remotion/compositor-win32-x64-msvc": ["@remotion/compositor-win32-x64-msvc@4.0.483", "", { "os": "win32", "cpu": "x64" }, "sha512-eDpWe6Vy7ySHugwxlgaeohqdBwR1etxiymXzT13cgbPw2+p6d55z1tJ7VPTXyfu0o+UdyRTauWqD4msoxN0wow=="],
|
| 136 |
+
|
| 137 |
+
"@remotion/licensing": ["@remotion/licensing@4.0.483", "", {}, "sha512-GRtjykrxMmB5Cjpq1oVqeYIRXI95vid6afX0LTLfp1shD6MR4lTZRoRuopxrrZp1E4XFGXoY64b6dlIudgTyBQ=="],
|
| 138 |
+
|
| 139 |
+
"@remotion/media-parser": ["@remotion/media-parser@4.0.483", "", {}, "sha512-iva9Eof7QQX+3hGxH/N8pGi80wgdGuzOr825Zn7IuEe7IWdtRYWlFpCEghmyfhrwgaWa7RY51wg77ycR3c3nRg=="],
|
| 140 |
+
|
| 141 |
+
"@remotion/media-utils": ["@remotion/media-utils@4.0.483", "", { "dependencies": { "mediabunny": "1.47.0", "remotion": "4.0.483" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-4T4WQh/U95kCBzgmz/EL/HL8Zeox/AKAL5ufsehrZFgwlcvH1EsKNJH/RWaAtNPRLF+pskEOgFzPYaczHeI8hg=="],
|
| 142 |
+
|
| 143 |
+
"@remotion/player": ["@remotion/player@4.0.483", "", { "dependencies": { "remotion": "4.0.483" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-yyIQ9vinUqqS0fQeL52bPCWQIr8qDXCqQ4iys8P7dSZncdu8V29p4W2a0/4eKV8bv5+mjnJQ/U6nl9NxBF1hdA=="],
|
| 144 |
+
|
| 145 |
+
"@remotion/renderer": ["@remotion/renderer@4.0.483", "", { "dependencies": { "@remotion/licensing": "4.0.483", "@remotion/streaming": "4.0.483", "execa": "5.1.1", "remotion": "4.0.483", "source-map": "0.8.0-beta.0", "ws": "8.21.0" }, "optionalDependencies": { "@remotion/compositor-darwin-arm64": "4.0.483", "@remotion/compositor-darwin-x64": "4.0.483", "@remotion/compositor-linux-arm64-gnu": "4.0.483", "@remotion/compositor-linux-arm64-musl": "4.0.483", "@remotion/compositor-linux-x64-gnu": "4.0.483", "@remotion/compositor-linux-x64-musl": "4.0.483", "@remotion/compositor-win32-x64-msvc": "4.0.483" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-eSKdQqm8rcl+GNyOhFsBgcPYWMcxTJWHL5xaNrd037piCaL3sdJ57OEO/AbfEvvOO14zwUvlsONKjlkLlEVyKg=="],
|
| 146 |
+
|
| 147 |
+
"@remotion/streaming": ["@remotion/streaming@4.0.483", "", {}, "sha512-96rqrk+l5AfriHOqmqxMn8rI6UJfFY7r5UMDZoSKqXWzTOwj+0VWHTRl9ilZQMXhYACaMSA/5yrL9jgQEK8Yuw=="],
|
| 148 |
+
|
| 149 |
+
"@remotion/studio": ["@remotion/studio@4.0.483", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.31", "@remotion/canvas-capture": "4.0.483", "@remotion/media-utils": "4.0.483", "@remotion/player": "4.0.483", "@remotion/renderer": "4.0.483", "@remotion/studio-shared": "4.0.483", "@remotion/timeline-utils": "4.0.483", "@remotion/web-renderer": "4.0.483", "@remotion/zod-types": "4.0.483", "mediabunny": "1.47.0", "memfs": "3.4.3", "open": "8.4.2", "remotion": "4.0.483", "semver": "7.5.3", "zod": "4.3.6" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-gNa1Lw8NmHl0jwFb5fk7rzA+WFTJQpGDT/49A38t9jpEwoF+h1mKTgY8gA202apzjBHrEECdFE450npnBOUpUw=="],
|
| 150 |
+
|
| 151 |
+
"@remotion/studio-server": ["@remotion/studio-server@4.0.483", "", { "dependencies": { "@babel/parser": "7.24.1", "@babel/types": "7.24.0", "@remotion/bundler": "4.0.483", "@remotion/renderer": "4.0.483", "@remotion/studio-shared": "4.0.483", "memfs": "3.4.3", "open": "8.4.2", "prettier": "3.8.1", "recast": "0.23.11", "remotion": "4.0.483", "semver": "7.5.3" } }, "sha512-2FSLbVN5N8bgtQPX+RQRbis557tJJnVTOZuEBZndfC9NOoPdARlSgEnwVer9tBNczUlc6B3KrPxyPSlS3UjL+Q=="],
|
| 152 |
+
|
| 153 |
+
"@remotion/studio-shared": ["@remotion/studio-shared@4.0.483", "", { "dependencies": { "remotion": "4.0.483" } }, "sha512-aXxBYUgsWgphHVq7T7bz+ICMGzfii7pcX1IxS5hbLMLJHqlDtk9g+qcxm4kJ2Fjj/Gb5gERKiNzYym8WZTIM2Q=="],
|
| 154 |
+
|
| 155 |
+
"@remotion/timeline-utils": ["@remotion/timeline-utils@4.0.483", "", { "dependencies": { "mediabunny": "1.47.0" } }, "sha512-KTTMdpNA5uRLX+iisAITO+V9cJBk17F8EWvuUnAEVmAFOQTbGIyPI9HNw5pZmL7SlzOJdFjAtksTjipeYGkEug=="],
|
| 156 |
+
|
| 157 |
+
"@remotion/web-renderer": ["@remotion/web-renderer@4.0.483", "", { "dependencies": { "@mediabunny/aac-encoder": "1.47.0", "@mediabunny/flac-encoder": "1.47.0", "@mediabunny/mp3-encoder": "1.47.0", "@remotion/licensing": "4.0.483", "mediabunny": "1.47.0", "remotion": "4.0.483" }, "peerDependencies": { "react": ">=18.0.0", "react-dom": ">=18.0.0" } }, "sha512-14iURfVWA/hcF/rJvkid1ZR5nmnVhkTIf071FabCFi6kdViOSVBugSglJ8tUPvWVbWmxlXGDGQD9CSU18IATww=="],
|
| 158 |
+
|
| 159 |
+
"@remotion/zod-types": ["@remotion/zod-types@4.0.483", "", { "dependencies": { "remotion": "4.0.483" }, "peerDependencies": { "zod": "4.3.6" } }, "sha512-KIVYIzFpZBDB0wxGGQu5tDBr4XOYRzvrPXjmo6O/FI5Xx7O8hgvJmBs9VDkEwonAOft86sg79hI19F1DTX1p4w=="],
|
| 160 |
+
|
| 161 |
+
"@rspack/binding": ["@rspack/binding@1.7.11", "", { "optionalDependencies": { "@rspack/binding-darwin-arm64": "1.7.11", "@rspack/binding-darwin-x64": "1.7.11", "@rspack/binding-linux-arm64-gnu": "1.7.11", "@rspack/binding-linux-arm64-musl": "1.7.11", "@rspack/binding-linux-x64-gnu": "1.7.11", "@rspack/binding-linux-x64-musl": "1.7.11", "@rspack/binding-wasm32-wasi": "1.7.11", "@rspack/binding-win32-arm64-msvc": "1.7.11", "@rspack/binding-win32-ia32-msvc": "1.7.11", "@rspack/binding-win32-x64-msvc": "1.7.11" } }, "sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q=="],
|
| 162 |
+
|
| 163 |
+
"@rspack/binding-darwin-arm64": ["@rspack/binding-darwin-arm64@1.7.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig=="],
|
| 164 |
+
|
| 165 |
+
"@rspack/binding-darwin-x64": ["@rspack/binding-darwin-x64@1.7.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-a1+TtTE9ap6RalgFi7FGIgkJP6O4Vy6ctv+9WGJy53E4kuqHR0RygzaiVxCI/GMc/vBT9vY23hyrpWb3d1vtXA=="],
|
| 166 |
+
|
| 167 |
+
"@rspack/binding-linux-arm64-gnu": ["@rspack/binding-linux-arm64-gnu@1.7.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-P0QrGRPbTWu6RKWfN0bDtbnEps3rXH0MWIMreZABoUrVmNQKtXR6e73J3ub6a+di5s2+K0M2LJ9Bh2/H4UsDUA=="],
|
| 168 |
+
|
| 169 |
+
"@rspack/binding-linux-arm64-musl": ["@rspack/binding-linux-arm64-musl@1.7.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-6ky7R43VMjWwmx3Yx7Jl7faLBBMAgMDt+/bN35RgwjiPgsIByz65EwytUVuW9rikB43BGHvA/eqlnjLrUzNBqw=="],
|
| 170 |
+
|
| 171 |
+
"@rspack/binding-linux-x64-gnu": ["@rspack/binding-linux-x64-gnu@1.7.11", "", { "os": "linux", "cpu": "x64" }, "sha512-cuOJMfCOvb2Wgsry5enXJ3iT1FGUjdPqtGUBVupQlEG4ntSYsQ2PtF4wIDVasR3wdxC5nQbipOrDiN/u6fYsdQ=="],
|
| 172 |
+
|
| 173 |
+
"@rspack/binding-linux-x64-musl": ["@rspack/binding-linux-x64-musl@1.7.11", "", { "os": "linux", "cpu": "x64" }, "sha512-CoK37hva4AmHGh3VCsQXmGr40L36m1/AdnN5LEjUX6kx5rEH7/1nEBN6Ii72pejqDVvk9anEROmPDiPw10tpFg=="],
|
| 174 |
+
|
| 175 |
+
"@rspack/binding-wasm32-wasi": ["@rspack/binding-wasm32-wasi@1.7.11", "", { "dependencies": { "@napi-rs/wasm-runtime": "1.0.7" }, "cpu": "none" }, "sha512-OtrmnPUVJMxjNa3eDMfHyPdtlLRmmp/aIm0fQHlAOATbZvlGm12q7rhPW5BXTu1yh+1rQ1/uqvz+SzKEZXuJaQ=="],
|
| 176 |
+
|
| 177 |
+
"@rspack/binding-win32-arm64-msvc": ["@rspack/binding-win32-arm64-msvc@1.7.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-lObFW6e5lCWNgTBNwT//yiEDbsxm9QG4BYUojqeXxothuzJ/L6ibXz6+gLMvbOvLGV3nKgkXmx8GvT9WDKR0mA=="],
|
| 178 |
+
|
| 179 |
+
"@rspack/binding-win32-ia32-msvc": ["@rspack/binding-win32-ia32-msvc@1.7.11", "", { "os": "win32", "cpu": "ia32" }, "sha512-0pYGnZd8PPqNR68zQ8skamqNAXEA1sUfXuAdYcknIIRq2wsbiwFzIc0Pov1cIfHYab37G7sSIPBiOUdOWF5Ivw=="],
|
| 180 |
+
|
| 181 |
+
"@rspack/binding-win32-x64-msvc": ["@rspack/binding-win32-x64-msvc@1.7.11", "", { "os": "win32", "cpu": "x64" }, "sha512-EeQXayoQk/uBkI3pdoXfQBXNIUrADq56L3s/DFyM2pJeUDrWmhfIw2UFIGkYPTMSCo8F2JcdcGM32FGJrSnU0Q=="],
|
| 182 |
+
|
| 183 |
+
"@rspack/core": ["@rspack/core@1.7.11", "", { "dependencies": { "@module-federation/runtime-tools": "0.22.0", "@rspack/binding": "1.7.11", "@rspack/lite-tapable": "1.1.0" }, "peerDependencies": { "@swc/helpers": ">=0.5.1" }, "optionalPeers": ["@swc/helpers"] }, "sha512-rsD9b+Khmot5DwCMiB3cqTQo53ioPG3M/A7BySu8+0+RS7GCxKm+Z+mtsjtG/vsu4Tn2tcqCdZtA3pgLoJB+ew=="],
|
| 184 |
+
|
| 185 |
+
"@rspack/lite-tapable": ["@rspack/lite-tapable@1.1.0", "", {}, "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw=="],
|
| 186 |
+
|
| 187 |
+
"@rspack/plugin-react-refresh": ["@rspack/plugin-react-refresh@1.6.1", "", { "dependencies": { "error-stack-parser": "^2.1.4", "html-entities": "^2.6.0" }, "peerDependencies": { "react-refresh": ">=0.10.0 <1.0.0", "webpack-hot-middleware": "2.x" }, "optionalPeers": ["webpack-hot-middleware"] }, "sha512-eqqW5645VG3CzGzFgNg5HqNdHVXY+567PGjtDhhrM8t67caxmsSzRmT5qfoEIfBcGgFkH9vEg7kzXwmCYQdQDw=="],
|
| 188 |
+
|
| 189 |
+
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="],
|
| 190 |
+
|
| 191 |
+
"@types/dom-mediacapture-transform": ["@types/dom-mediacapture-transform@0.1.11", "", { "dependencies": { "@types/dom-webcodecs": "*" } }, "sha512-Y2p+nGf1bF2XMttBnsVPHUWzRRZzqUoJAKmiP10b5umnO6DDrWI0BrGDJy1pOHoOULVmGSfFNkQrAlC5dcj6nQ=="],
|
| 192 |
+
|
| 193 |
+
"@types/dom-webcodecs": ["@types/dom-webcodecs@0.1.13", "", {}, "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ=="],
|
| 194 |
+
|
| 195 |
+
"@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="],
|
| 196 |
+
|
| 197 |
+
"@types/eslint-scope": ["@types/eslint-scope@3.7.7", "", { "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg=="],
|
| 198 |
+
|
| 199 |
+
"@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
|
| 200 |
+
|
| 201 |
+
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
| 202 |
+
|
| 203 |
+
"@types/node": ["@types/node@26.0.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw=="],
|
| 204 |
+
|
| 205 |
+
"@types/react": ["@types/react@19.2.17", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw=="],
|
| 206 |
+
|
| 207 |
+
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
| 208 |
+
|
| 209 |
+
"@webassemblyjs/ast": ["@webassemblyjs/ast@1.14.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ=="],
|
| 210 |
+
|
| 211 |
+
"@webassemblyjs/floating-point-hex-parser": ["@webassemblyjs/floating-point-hex-parser@1.13.2", "", {}, "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA=="],
|
| 212 |
+
|
| 213 |
+
"@webassemblyjs/helper-api-error": ["@webassemblyjs/helper-api-error@1.13.2", "", {}, "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ=="],
|
| 214 |
+
|
| 215 |
+
"@webassemblyjs/helper-buffer": ["@webassemblyjs/helper-buffer@1.14.1", "", {}, "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA=="],
|
| 216 |
+
|
| 217 |
+
"@webassemblyjs/helper-numbers": ["@webassemblyjs/helper-numbers@1.13.2", "", { "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA=="],
|
| 218 |
+
|
| 219 |
+
"@webassemblyjs/helper-wasm-bytecode": ["@webassemblyjs/helper-wasm-bytecode@1.13.2", "", {}, "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA=="],
|
| 220 |
+
|
| 221 |
+
"@webassemblyjs/helper-wasm-section": ["@webassemblyjs/helper-wasm-section@1.14.1", "", { "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", "@webassemblyjs/wasm-gen": "1.14.1" } }, "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw=="],
|
| 222 |
+
|
| 223 |
+
"@webassemblyjs/ieee754": ["@webassemblyjs/ieee754@1.13.2", "", { "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw=="],
|
| 224 |
+
|
| 225 |
+
"@webassemblyjs/leb128": ["@webassemblyjs/leb128@1.13.2", "", { "dependencies": { "@xtuc/long": "4.2.2" } }, "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw=="],
|
| 226 |
+
|
| 227 |
+
"@webassemblyjs/utf8": ["@webassemblyjs/utf8@1.13.2", "", {}, "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ=="],
|
| 228 |
+
|
| 229 |
+
"@webassemblyjs/wasm-edit": ["@webassemblyjs/wasm-edit@1.14.1", "", { "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", "@webassemblyjs/helper-wasm-section": "1.14.1", "@webassemblyjs/wasm-gen": "1.14.1", "@webassemblyjs/wasm-opt": "1.14.1", "@webassemblyjs/wasm-parser": "1.14.1", "@webassemblyjs/wast-printer": "1.14.1" } }, "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ=="],
|
| 230 |
+
|
| 231 |
+
"@webassemblyjs/wasm-gen": ["@webassemblyjs/wasm-gen@1.14.1", "", { "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", "@webassemblyjs/ieee754": "1.13.2", "@webassemblyjs/leb128": "1.13.2", "@webassemblyjs/utf8": "1.13.2" } }, "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg=="],
|
| 232 |
+
|
| 233 |
+
"@webassemblyjs/wasm-opt": ["@webassemblyjs/wasm-opt@1.14.1", "", { "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", "@webassemblyjs/wasm-gen": "1.14.1", "@webassemblyjs/wasm-parser": "1.14.1" } }, "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw=="],
|
| 234 |
+
|
| 235 |
+
"@webassemblyjs/wasm-parser": ["@webassemblyjs/wasm-parser@1.14.1", "", { "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-api-error": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", "@webassemblyjs/ieee754": "1.13.2", "@webassemblyjs/leb128": "1.13.2", "@webassemblyjs/utf8": "1.13.2" } }, "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ=="],
|
| 236 |
+
|
| 237 |
+
"@webassemblyjs/wast-printer": ["@webassemblyjs/wast-printer@1.14.1", "", { "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw=="],
|
| 238 |
+
|
| 239 |
+
"@xtuc/ieee754": ["@xtuc/ieee754@1.2.0", "", {}, "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="],
|
| 240 |
+
|
| 241 |
+
"@xtuc/long": ["@xtuc/long@4.2.2", "", {}, "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="],
|
| 242 |
+
|
| 243 |
+
"acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="],
|
| 244 |
+
|
| 245 |
+
"acorn-import-phases": ["acorn-import-phases@1.0.4", "", { "peerDependencies": { "acorn": "^8.14.0" } }, "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ=="],
|
| 246 |
+
|
| 247 |
+
"ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="],
|
| 248 |
+
|
| 249 |
+
"ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="],
|
| 250 |
+
|
| 251 |
+
"ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="],
|
| 252 |
+
|
| 253 |
+
"ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="],
|
| 254 |
+
|
| 255 |
+
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.40", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw=="],
|
| 256 |
+
|
| 257 |
+
"browserslist": ["browserslist@4.28.4", "", { "dependencies": { "baseline-browser-mapping": "^2.10.38", "caniuse-lite": "^1.0.30001799", "electron-to-chromium": "^1.5.376", "node-releases": "^2.0.48", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw=="],
|
| 258 |
+
|
| 259 |
+
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
|
| 260 |
+
|
| 261 |
+
"caniuse-lite": ["caniuse-lite@1.0.30001799", "", {}, "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw=="],
|
| 262 |
+
|
| 263 |
+
"chrome-trace-event": ["chrome-trace-event@1.0.4", "", {}, "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ=="],
|
| 264 |
+
|
| 265 |
+
"commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
|
| 266 |
+
|
| 267 |
+
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
| 268 |
+
|
| 269 |
+
"css-loader": ["css-loader@7.1.4", "", { "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.40", "postcss-modules-extract-imports": "^3.1.0", "postcss-modules-local-by-default": "^4.0.5", "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", "semver": "^7.6.3" }, "peerDependencies": { "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", "webpack": "^5.27.0" }, "optionalPeers": ["@rspack/core", "webpack"] }, "sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw=="],
|
| 270 |
+
|
| 271 |
+
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
|
| 272 |
+
|
| 273 |
+
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
| 274 |
+
|
| 275 |
+
"define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="],
|
| 276 |
+
|
| 277 |
+
"dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
|
| 278 |
+
|
| 279 |
+
"electron-to-chromium": ["electron-to-chromium@1.5.379", "", {}, "sha512-v/qV5aV5EUA2pGilzUCq5/eyOloZAqDZBu9UMBIzgPpLlprjSR6zswsWBTv0KpqxLGUAZEwhO95ZCt7srymNVA=="],
|
| 280 |
+
|
| 281 |
+
"enhanced-resolve": ["enhanced-resolve@5.24.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-7DdUaTjmNwMcH2gLr1qycesKII3BK4RLy/mdAb7x10Lq7bR4aNKHt1BR1ZALSv0rPM/hF5wYF0PhGop/rJm8vw=="],
|
| 282 |
+
|
| 283 |
+
"error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="],
|
| 284 |
+
|
| 285 |
+
"es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="],
|
| 286 |
+
|
| 287 |
+
"esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="],
|
| 288 |
+
|
| 289 |
+
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
| 290 |
+
|
| 291 |
+
"eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="],
|
| 292 |
+
|
| 293 |
+
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
|
| 294 |
+
|
| 295 |
+
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
| 296 |
+
|
| 297 |
+
"estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="],
|
| 298 |
+
|
| 299 |
+
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
|
| 300 |
+
|
| 301 |
+
"execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
|
| 302 |
+
|
| 303 |
+
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
| 304 |
+
|
| 305 |
+
"fast-uri": ["fast-uri@3.1.2", "", {}, "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ=="],
|
| 306 |
+
|
| 307 |
+
"fs-monkey": ["fs-monkey@1.0.3", "", {}, "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q=="],
|
| 308 |
+
|
| 309 |
+
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
|
| 310 |
+
|
| 311 |
+
"glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="],
|
| 312 |
+
|
| 313 |
+
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
| 314 |
+
|
| 315 |
+
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
| 316 |
+
|
| 317 |
+
"html-entities": ["html-entities@2.6.0", "", {}, "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="],
|
| 318 |
+
|
| 319 |
+
"human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
|
| 320 |
+
|
| 321 |
+
"icss-utils": ["icss-utils@5.1.0", "", { "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA=="],
|
| 322 |
+
|
| 323 |
+
"is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="],
|
| 324 |
+
|
| 325 |
+
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
| 326 |
+
|
| 327 |
+
"is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
|
| 328 |
+
|
| 329 |
+
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
| 330 |
+
|
| 331 |
+
"jest-worker": ["jest-worker@27.5.1", "", { "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg=="],
|
| 332 |
+
|
| 333 |
+
"json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="],
|
| 334 |
+
|
| 335 |
+
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
| 336 |
+
|
| 337 |
+
"kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
|
| 338 |
+
|
| 339 |
+
"loader-runner": ["loader-runner@4.3.2", "", {}, "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w=="],
|
| 340 |
+
|
| 341 |
+
"lodash.sortby": ["lodash.sortby@4.7.0", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="],
|
| 342 |
+
|
| 343 |
+
"lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
|
| 344 |
+
|
| 345 |
+
"mediabunny": ["mediabunny@1.47.0", "", { "dependencies": { "@types/dom-mediacapture-transform": "^0.1.11", "@types/dom-webcodecs": "0.1.13" } }, "sha512-XQMZAcaKPkJ7hQ/Q2fvBdl3ZazQl2WVxDysUbJWh4PuAnLoerdsQBdPTDWdUdK6hh26LQ8Ue94MLLnmpWvlUYg=="],
|
| 346 |
+
|
| 347 |
+
"memfs": ["memfs@3.4.3", "", { "dependencies": { "fs-monkey": "1.0.3" } }, "sha512-eivjfi7Ahr6eQTn44nvTnR60e4a1Fs1Via2kCR5lHo/kyNoiMWaXCNJ/GpSd0ilXas2JSOl9B5FTIhflXu0hlg=="],
|
| 348 |
+
|
| 349 |
+
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
|
| 350 |
+
|
| 351 |
+
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
| 352 |
+
|
| 353 |
+
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
| 354 |
+
|
| 355 |
+
"mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
|
| 356 |
+
|
| 357 |
+
"minimist": ["minimist@1.2.6", "", {}, "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="],
|
| 358 |
+
|
| 359 |
+
"nanoid": ["nanoid@3.3.15", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA=="],
|
| 360 |
+
|
| 361 |
+
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
|
| 362 |
+
|
| 363 |
+
"node-releases": ["node-releases@2.0.50", "", {}, "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg=="],
|
| 364 |
+
|
| 365 |
+
"npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
|
| 366 |
+
|
| 367 |
+
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
|
| 368 |
+
|
| 369 |
+
"open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
|
| 370 |
+
|
| 371 |
+
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
| 372 |
+
|
| 373 |
+
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
| 374 |
+
|
| 375 |
+
"postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="],
|
| 376 |
+
|
| 377 |
+
"postcss-modules-extract-imports": ["postcss-modules-extract-imports@3.1.0", "", { "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q=="],
|
| 378 |
+
|
| 379 |
+
"postcss-modules-local-by-default": ["postcss-modules-local-by-default@4.2.0", "", { "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw=="],
|
| 380 |
+
|
| 381 |
+
"postcss-modules-scope": ["postcss-modules-scope@3.2.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA=="],
|
| 382 |
+
|
| 383 |
+
"postcss-modules-values": ["postcss-modules-values@4.0.0", "", { "dependencies": { "icss-utils": "^5.0.0" }, "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ=="],
|
| 384 |
+
|
| 385 |
+
"postcss-selector-parser": ["postcss-selector-parser@7.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg=="],
|
| 386 |
+
|
| 387 |
+
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
| 388 |
+
|
| 389 |
+
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
|
| 390 |
+
|
| 391 |
+
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
|
| 392 |
+
|
| 393 |
+
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
| 394 |
+
|
| 395 |
+
"react": ["react@19.2.7", "", {}, "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ=="],
|
| 396 |
+
|
| 397 |
+
"react-dom": ["react-dom@19.2.7", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.7" } }, "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ=="],
|
| 398 |
+
|
| 399 |
+
"react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
|
| 400 |
+
|
| 401 |
+
"recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
|
| 402 |
+
|
| 403 |
+
"remotion": ["remotion@4.0.483", "", { "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-lf4xq4Twn75TQeTavFLrTE4zdck7EKBSx07ZrPv4om40Sist+3G0kq7NNzSjMeJ6G2Wx6vI+0oICD/vv4sGWtg=="],
|
| 404 |
+
|
| 405 |
+
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
| 406 |
+
|
| 407 |
+
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
| 408 |
+
|
| 409 |
+
"schema-utils": ["schema-utils@4.3.3", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA=="],
|
| 410 |
+
|
| 411 |
+
"semver": ["semver@7.5.3", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ=="],
|
| 412 |
+
|
| 413 |
+
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
| 414 |
+
|
| 415 |
+
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
| 416 |
+
|
| 417 |
+
"signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
| 418 |
+
|
| 419 |
+
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
|
| 420 |
+
|
| 421 |
+
"source-map": ["source-map@0.8.0-beta.0", "", { "dependencies": { "whatwg-url": "^7.0.0" } }, "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA=="],
|
| 422 |
+
|
| 423 |
+
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
| 424 |
+
|
| 425 |
+
"source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
|
| 426 |
+
|
| 427 |
+
"stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="],
|
| 428 |
+
|
| 429 |
+
"strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
|
| 430 |
+
|
| 431 |
+
"style-loader": ["style-loader@4.0.0", "", { "peerDependencies": { "webpack": "^5.27.0" } }, "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA=="],
|
| 432 |
+
|
| 433 |
+
"supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
|
| 434 |
+
|
| 435 |
+
"tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="],
|
| 436 |
+
|
| 437 |
+
"terser": ["terser@5.48.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q=="],
|
| 438 |
+
|
| 439 |
+
"terser-webpack-plugin": ["terser-webpack-plugin@5.6.1", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ=="],
|
| 440 |
+
|
| 441 |
+
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
|
| 442 |
+
|
| 443 |
+
"to-fast-properties": ["to-fast-properties@2.0.0", "", {}, "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="],
|
| 444 |
+
|
| 445 |
+
"tr46": ["tr46@1.0.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="],
|
| 446 |
+
|
| 447 |
+
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
| 448 |
+
|
| 449 |
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
| 450 |
+
|
| 451 |
+
"undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
|
| 452 |
+
|
| 453 |
+
"update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
| 454 |
+
|
| 455 |
+
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
| 456 |
+
|
| 457 |
+
"watchpack": ["watchpack@2.5.2", "", { "dependencies": { "graceful-fs": "^4.1.2" } }, "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg=="],
|
| 458 |
+
|
| 459 |
+
"webidl-conversions": ["webidl-conversions@4.0.2", "", {}, "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="],
|
| 460 |
+
|
| 461 |
+
"webpack": ["webpack@5.105.0", "", { "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.19.0", "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "terser-webpack-plugin": "^5.3.16", "watchpack": "^2.5.1", "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw=="],
|
| 462 |
+
|
| 463 |
+
"webpack-sources": ["webpack-sources@3.5.0", "", {}, "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ=="],
|
| 464 |
+
|
| 465 |
+
"whatwg-url": ["whatwg-url@7.1.0", "", { "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", "webidl-conversions": "^4.0.2" } }, "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg=="],
|
| 466 |
+
|
| 467 |
+
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
| 468 |
+
|
| 469 |
+
"ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="],
|
| 470 |
+
|
| 471 |
+
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
| 472 |
+
|
| 473 |
+
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
|
| 474 |
+
|
| 475 |
+
"css-loader/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
| 476 |
+
|
| 477 |
+
"esrecurse/estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
| 478 |
+
|
| 479 |
+
"recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
| 480 |
+
|
| 481 |
+
"source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
| 482 |
+
}
|
| 483 |
+
}
|
artifacts/glm52-rise-video/out/june-totals.png
ADDED
|
artifacts/glm52-rise-video/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "glm52-rise-video",
|
| 3 |
+
"private": true,
|
| 4 |
+
"type": "module",
|
| 5 |
+
"scripts": {
|
| 6 |
+
"render": "remotion render src/index.tsx GLM52Rise out/glm-52-broke-out.mp4 --codec h264 --pixel-format yuv420p",
|
| 7 |
+
"render:sheep": "remotion render src/index.tsx NZSheep out/nz-sheep.mp4 --codec h264 --pixel-format yuv420p",
|
| 8 |
+
"render:novel": "remotion render src/index.tsx NovelTokens out/novel-1984.mp4 --codec h264 --pixel-format yuv420p",
|
| 9 |
+
"render:flash": "remotion render src/index.tsx FlashShare out/flash-share.mp4 --codec h264 --pixel-format yuv420p",
|
| 10 |
+
"render:minimax": "remotion render src/index.tsx MiniMaxClimb out/minimax-climb.mp4 --codec h264 --pixel-format yuv420p",
|
| 11 |
+
"still:june": "remotion still src/index.tsx JuneTotals out/june-totals.png --frame=0"
|
| 12 |
+
},
|
| 13 |
+
"dependencies": {
|
| 14 |
+
"@remotion/cli": "^4.0.384",
|
| 15 |
+
"react": "^19.2.3",
|
| 16 |
+
"react-dom": "^19.2.3",
|
| 17 |
+
"remotion": "^4.0.384"
|
| 18 |
+
},
|
| 19 |
+
"devDependencies": {
|
| 20 |
+
"@types/react": "^19.2.8",
|
| 21 |
+
"@types/react-dom": "^19.2.3",
|
| 22 |
+
"typescript": "^5.8.2"
|
| 23 |
+
}
|
| 24 |
+
}
|
artifacts/glm52-rise-video/src/data.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Verified against the production opencode-stats PlanetScale DB.
|
| 2 |
+
// Scope: tier='Go' (OpenCode Go), dataset='zen', client='all', source='all', grain='day'.
|
| 3 |
+
// metric = total_tokens. Daily token volume per model; GLM-5.2 (zhipu) launched Jun 17.
|
| 4 |
+
// Segments per day (tokens): glm-5.2, deepseek-v4-flash, deepseek-v4-pro, minimax-m3, all others.
|
| 5 |
+
|
| 6 |
+
export type Day = {
|
| 7 |
+
date: string
|
| 8 |
+
total: number
|
| 9 |
+
glm: number
|
| 10 |
+
dsf: number
|
| 11 |
+
dsp: number
|
| 12 |
+
mm: number
|
| 13 |
+
others: number
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
export const days: Day[] = [
|
| 17 |
+
{
|
| 18 |
+
date: "Jun 12",
|
| 19 |
+
total: 2_283_799_449_383,
|
| 20 |
+
glm: 0,
|
| 21 |
+
dsf: 1_176_701_653_509,
|
| 22 |
+
dsp: 569_527_034_307,
|
| 23 |
+
mm: 159_016_250_684,
|
| 24 |
+
others: 378_554_510_883,
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
date: "Jun 13",
|
| 28 |
+
total: 2_008_462_388_420,
|
| 29 |
+
glm: 0,
|
| 30 |
+
dsf: 995_338_131_997,
|
| 31 |
+
dsp: 445_817_536_548,
|
| 32 |
+
mm: 211_743_241_967,
|
| 33 |
+
others: 355_563_477_908,
|
| 34 |
+
},
|
| 35 |
+
{
|
| 36 |
+
date: "Jun 14",
|
| 37 |
+
total: 2_007_785_405_251,
|
| 38 |
+
glm: 0,
|
| 39 |
+
dsf: 983_954_176_228,
|
| 40 |
+
dsp: 428_151_999_341,
|
| 41 |
+
mm: 262_476_527_930,
|
| 42 |
+
others: 333_202_701_752,
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
date: "Jun 15",
|
| 46 |
+
total: 2_694_736_103_062,
|
| 47 |
+
glm: 0,
|
| 48 |
+
dsf: 1_255_893_953_859,
|
| 49 |
+
dsp: 632_223_338_376,
|
| 50 |
+
mm: 352_507_442_991,
|
| 51 |
+
others: 454_111_367_836,
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
date: "Jun 16",
|
| 55 |
+
total: 2_838_153_758_908,
|
| 56 |
+
glm: 0,
|
| 57 |
+
dsf: 1_336_625_283_800,
|
| 58 |
+
dsp: 676_480_415_730,
|
| 59 |
+
mm: 305_268_829_013,
|
| 60 |
+
others: 519_779_230_365,
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
date: "Jun 17",
|
| 64 |
+
total: 2_778_964_711_109,
|
| 65 |
+
glm: 70_095_977_043,
|
| 66 |
+
dsf: 1_339_831_523_555,
|
| 67 |
+
dsp: 660_414_395_220,
|
| 68 |
+
mm: 251_302_096_157,
|
| 69 |
+
others: 457_320_719_134,
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
date: "Jun 18",
|
| 73 |
+
total: 2_806_992_430_656,
|
| 74 |
+
glm: 201_130_231_172,
|
| 75 |
+
dsf: 1_295_599_996_869,
|
| 76 |
+
dsp: 595_665_008_776,
|
| 77 |
+
mm: 322_205_104_324,
|
| 78 |
+
others: 392_392_089_515,
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
date: "Jun 19",
|
| 82 |
+
total: 2_419_611_630_232,
|
| 83 |
+
glm: 199_086_413_910,
|
| 84 |
+
dsf: 1_115_750_468_802,
|
| 85 |
+
dsp: 475_965_869_304,
|
| 86 |
+
mm: 303_586_698_735,
|
| 87 |
+
others: 325_222_179_481,
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
date: "Jun 20",
|
| 91 |
+
total: 2_188_278_916_865,
|
| 92 |
+
glm: 193_931_516_396,
|
| 93 |
+
dsf: 1_050_194_681_012,
|
| 94 |
+
dsp: 395_303_435_278,
|
| 95 |
+
mm: 281_998_000_337,
|
| 96 |
+
others: 266_851_283_842,
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
date: "Jun 21",
|
| 100 |
+
total: 2_042_309_961_344,
|
| 101 |
+
glm: 181_894_043_118,
|
| 102 |
+
dsf: 985_164_570_580,
|
| 103 |
+
dsp: 368_194_079_542,
|
| 104 |
+
mm: 259_812_551_324,
|
| 105 |
+
others: 247_244_716_780,
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
date: "Jun 22",
|
| 109 |
+
total: 2_893_934_325_663,
|
| 110 |
+
glm: 301_759_048_475,
|
| 111 |
+
dsf: 1_298_124_282_989,
|
| 112 |
+
dsp: 581_012_596_194,
|
| 113 |
+
mm: 371_581_117_839,
|
| 114 |
+
others: 341_457_280_166,
|
| 115 |
+
},
|
| 116 |
+
{
|
| 117 |
+
date: "Jun 23",
|
| 118 |
+
total: 3_109_009_321_480,
|
| 119 |
+
glm: 282_277_235_158,
|
| 120 |
+
dsf: 1_423_571_678_821,
|
| 121 |
+
dsp: 627_374_654_587,
|
| 122 |
+
mm: 429_416_300_508,
|
| 123 |
+
others: 346_369_452_406,
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
date: "Jun 24",
|
| 127 |
+
total: 2_939_149_971_595,
|
| 128 |
+
glm: 256_497_442_533,
|
| 129 |
+
dsf: 1_373_583_023_234,
|
| 130 |
+
dsp: 601_270_997_775,
|
| 131 |
+
mm: 391_586_493_231,
|
| 132 |
+
others: 316_212_014_822,
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
date: "Jun 25",
|
| 136 |
+
total: 3_029_641_552_948,
|
| 137 |
+
glm: 256_279_657_734,
|
| 138 |
+
dsf: 1_481_084_002_776,
|
| 139 |
+
dsp: 602_077_167_287,
|
| 140 |
+
mm: 375_985_302_874,
|
| 141 |
+
others: 314_215_422_277,
|
| 142 |
+
},
|
| 143 |
+
]
|
| 144 |
+
|
| 145 |
+
export const launchIndex = 5 // Jun 17, first day of GLM-5.2 usage
|
| 146 |
+
// GLM-5.2 weekly token volume, Jun 19-25 (sum of glm): 1,671,725,357,324 = 1.67T
|
| 147 |
+
export const glmWeekTokensT = 1.672
|
| 148 |
+
|
| 149 |
+
// stacked segments, bottom -> top. GLM-5.2 is the hero (blue); the rest are the field it cut into.
|
| 150 |
+
export const segments = [
|
| 151 |
+
{ key: "glm", label: "GLM-5.2", color: "#3b5cf6", hero: true },
|
| 152 |
+
{ key: "dsf", label: "deepseek-v4-flash", color: "#9ca3ad" },
|
| 153 |
+
{ key: "dsp", label: "deepseek-v4-pro", color: "#b3b9c1" },
|
| 154 |
+
{ key: "mm", label: "minimax-m3", color: "#c8cdd3" },
|
| 155 |
+
{ key: "others", label: "other models", color: "#dde0e4" },
|
| 156 |
+
] as const
|
artifacts/glm52-rise-video/src/flash.tsx
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react"
|
| 2 |
+
import { AbsoluteFill, Easing, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion"
|
| 3 |
+
|
| 4 |
+
// stats.opencode.ai design tokens (light theme)
|
| 5 |
+
const c = {
|
| 6 |
+
bg: "#ffffff",
|
| 7 |
+
ink: "#161616",
|
| 8 |
+
muted: "#5c5c5c",
|
| 9 |
+
faint: "#808080",
|
| 10 |
+
line: "#e6e6e6",
|
| 11 |
+
dot: "#e4e4e4",
|
| 12 |
+
gray: "#aab0b8",
|
| 13 |
+
accent: "#3b5cf6",
|
| 14 |
+
accentHi: "#5b78ff",
|
| 15 |
+
}
|
| 16 |
+
const MONO = '"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
|
| 17 |
+
|
| 18 |
+
const DOT_MASK =
|
| 19 |
+
"url(\"data:image/svg+xml,%3Csvg viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0H2V2H0V0Z' fill='black'/%3E%3C/svg%3E\")"
|
| 20 |
+
|
| 21 |
+
// verified: OpenCode Go, week of Jun 22-28, 2026 (2026-W26). share = % of 19.64T total Go tokens.
|
| 22 |
+
const bars = [
|
| 23 |
+
{ label: "deepseek-v4-flash", share: 48.3, hero: true },
|
| 24 |
+
{ label: "deepseek-v4-pro", share: 19.4 },
|
| 25 |
+
{ label: "minimax-m3", share: 13.0 },
|
| 26 |
+
{ label: "glm-5.2", share: 8.3 },
|
| 27 |
+
{ label: "mimo-v2.5", share: 4.3 },
|
| 28 |
+
{ label: "kimi-k2.7-code", share: 2.6 },
|
| 29 |
+
{ label: "other models", share: 4.1 },
|
| 30 |
+
]
|
| 31 |
+
|
| 32 |
+
function DataWordmark({ height = 30 }: { height?: number }) {
|
| 33 |
+
return (
|
| 34 |
+
<svg width={(height * 66) / 20} height={height} viewBox="0 0 66 20" fill="none" style={{ color: c.ink }}>
|
| 35 |
+
<path opacity="0.2" d="M12 16H4V8H12V16Z" fill="currentColor" />
|
| 36 |
+
<path d="M12 4H4V16H12V4ZM16 20H0V0H16V20Z" fill="currentColor" />
|
| 37 |
+
<path
|
| 38 |
+
d="M63.3543 16L62.5119 12.8711H58.6437L57.8013 16H55.7383L59.2454 4H61.9618L65.4689 16H63.3543ZM61.0678 7.851L60.6896 5.94269H60.4489L60.0707 7.851L59.1595 11.1347H61.9962L61.0678 7.851Z"
|
| 39 |
+
fill="currentColor"
|
| 40 |
+
/>
|
| 41 |
+
<path d="M52.5951 5.87392V16H50.4461V5.87392H47.4375V4H55.6209V5.87392H52.5951Z" fill="currentColor" />
|
| 42 |
+
<path
|
| 43 |
+
d="M45.2059 16L44.3635 12.8711H40.4953L39.6529 16H37.5898L41.097 4H43.8133L47.3205 16H45.2059ZM42.9194 7.851L42.5411 5.94269H42.3004L41.9222 7.851L41.011 11.1347H43.8477L42.9194 7.851Z"
|
| 44 |
+
fill="currentColor"
|
| 45 |
+
/>
|
| 46 |
+
<path
|
| 47 |
+
d="M28 4H32.0917C32.8138 4 33.4556 4.11461 34.0172 4.34384C34.5903 4.5616 35.0716 4.9169 35.4613 5.40974C35.8625 5.89112 36.1662 6.51003 36.3725 7.26648C36.5788 8.02292 36.6819 8.9341 36.6819 10C36.6819 11.0659 36.5788 11.9771 36.3725 12.7335C36.1662 13.49 35.8625 14.1146 35.4613 14.6075C35.0716 15.0888 34.5903 15.4441 34.0172 15.6734C33.4556 15.8911 32.8138 16 32.0917 16H28V4ZM32.0917 14.1261C32.8252 14.1261 33.3926 13.9026 33.7937 13.4556C34.1948 12.9971 34.3954 12.3152 34.3954 11.4097V8.59026C34.3954 7.68481 34.1948 7.0086 33.7937 6.5616C33.3926 6.10315 32.8252 5.87392 32.0917 5.87392H30.149V14.1261H32.0917Z"
|
| 48 |
+
fill="currentColor"
|
| 49 |
+
/>
|
| 50 |
+
</svg>
|
| 51 |
+
)
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
export function FlashShare() {
|
| 55 |
+
const frame = useCurrentFrame()
|
| 56 |
+
const { fps } = useVideoConfig()
|
| 57 |
+
|
| 58 |
+
const grow = (i: number) =>
|
| 59 |
+
Math.min(
|
| 60 |
+
1,
|
| 61 |
+
Math.max(0, spring({ frame: frame - 18 - i * 7, fps, config: { damping: 18, stiffness: 120, mass: 0.6 } })),
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
return (
|
| 65 |
+
<AbsoluteFill style={{ background: c.bg, color: c.ink, fontFamily: MONO, padding: 72, boxSizing: "border-box" }}>
|
| 66 |
+
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
| 67 |
+
{/* header */}
|
| 68 |
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
| 69 |
+
<DataWordmark height={30} />
|
| 70 |
+
<div style={{ fontSize: 20, fontWeight: 500, color: c.faint, letterSpacing: 1 }}>JUN 22–28, 2026</div>
|
| 71 |
+
</div>
|
| 72 |
+
|
| 73 |
+
{/* headline (static) */}
|
| 74 |
+
<div style={{ marginTop: 50 }}>
|
| 75 |
+
<div style={{ fontSize: 23, fontWeight: 600, color: c.muted, letterSpacing: 2 }}>
|
| 76 |
+
OPENCODE GO · SHARE OF TOKENS
|
| 77 |
+
</div>
|
| 78 |
+
<div
|
| 79 |
+
style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 24, marginTop: 14 }}
|
| 80 |
+
>
|
| 81 |
+
<div style={{ fontSize: 62, fontWeight: 600, letterSpacing: -2, lineHeight: 1 }}>DeepSeek V4 Flash</div>
|
| 82 |
+
<div
|
| 83 |
+
style={{
|
| 84 |
+
fontSize: 88,
|
| 85 |
+
fontWeight: 600,
|
| 86 |
+
letterSpacing: -2,
|
| 87 |
+
lineHeight: 1,
|
| 88 |
+
color: c.accent,
|
| 89 |
+
fontVariantNumeric: "tabular-nums",
|
| 90 |
+
}}
|
| 91 |
+
>
|
| 92 |
+
48%
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
</div>
|
| 96 |
+
|
| 97 |
+
{/* bar chart */}
|
| 98 |
+
<div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "center", gap: 16 }}>
|
| 99 |
+
{bars.map((b, i) => {
|
| 100 |
+
const g = grow(i)
|
| 101 |
+
const pct = b.share * g
|
| 102 |
+
return (
|
| 103 |
+
<div key={b.label} style={{ display: "flex", alignItems: "center", gap: 18 }}>
|
| 104 |
+
<div
|
| 105 |
+
style={{
|
| 106 |
+
width: 268,
|
| 107 |
+
fontSize: 23,
|
| 108 |
+
fontWeight: b.hero ? 600 : 500,
|
| 109 |
+
color: b.hero ? c.ink : c.muted,
|
| 110 |
+
textAlign: "right",
|
| 111 |
+
whiteSpace: "nowrap",
|
| 112 |
+
}}
|
| 113 |
+
>
|
| 114 |
+
{b.label}
|
| 115 |
+
</div>
|
| 116 |
+
<div style={{ position: "relative", flex: 1, height: 48 }}>
|
| 117 |
+
{/* dotted 100% track — height is a multiple of the 12px tile, anchored bottom, so dots never clip */}
|
| 118 |
+
<div
|
| 119 |
+
style={{
|
| 120 |
+
position: "absolute",
|
| 121 |
+
inset: 0,
|
| 122 |
+
background: c.dot,
|
| 123 |
+
WebkitMaskImage: DOT_MASK,
|
| 124 |
+
maskImage: DOT_MASK,
|
| 125 |
+
WebkitMaskSize: "12px 12px",
|
| 126 |
+
maskSize: "12px 12px",
|
| 127 |
+
WebkitMaskRepeat: "repeat",
|
| 128 |
+
maskRepeat: "repeat",
|
| 129 |
+
WebkitMaskPosition: "left bottom",
|
| 130 |
+
maskPosition: "left bottom",
|
| 131 |
+
}}
|
| 132 |
+
/>
|
| 133 |
+
{/* fill */}
|
| 134 |
+
<div
|
| 135 |
+
style={{
|
| 136 |
+
position: "absolute",
|
| 137 |
+
left: 0,
|
| 138 |
+
top: 0,
|
| 139 |
+
bottom: 0,
|
| 140 |
+
width: `${pct}%`,
|
| 141 |
+
background: b.hero ? c.accent : c.gray,
|
| 142 |
+
borderRight: b.hero ? `2px solid ${c.accentHi}` : "none",
|
| 143 |
+
}}
|
| 144 |
+
/>
|
| 145 |
+
</div>
|
| 146 |
+
<div
|
| 147 |
+
style={{
|
| 148 |
+
width: 84,
|
| 149 |
+
fontSize: 24,
|
| 150 |
+
fontWeight: b.hero ? 600 : 500,
|
| 151 |
+
color: b.hero ? c.accent : c.muted,
|
| 152 |
+
textAlign: "right",
|
| 153 |
+
fontVariantNumeric: "tabular-nums",
|
| 154 |
+
}}
|
| 155 |
+
>
|
| 156 |
+
{Math.round(pct)}%
|
| 157 |
+
</div>
|
| 158 |
+
</div>
|
| 159 |
+
)
|
| 160 |
+
})}
|
| 161 |
+
</div>
|
| 162 |
+
|
| 163 |
+
{/* footer */}
|
| 164 |
+
<div
|
| 165 |
+
style={{
|
| 166 |
+
display: "flex",
|
| 167 |
+
justifyContent: "space-between",
|
| 168 |
+
alignItems: "center",
|
| 169 |
+
marginTop: 24,
|
| 170 |
+
paddingTop: 22,
|
| 171 |
+
borderTop: `1px solid ${c.line}`,
|
| 172 |
+
fontSize: 20,
|
| 173 |
+
fontWeight: 500,
|
| 174 |
+
}}
|
| 175 |
+
>
|
| 176 |
+
<div style={{ display: "inline-flex", alignItems: "center", gap: 9, color: c.muted }}>
|
| 177 |
+
<span style={{ width: 13, height: 13, background: c.accent, display: "inline-block" }} />
|
| 178 |
+
DeepSeek V4 Flash · 9.48T tokens · 83.6M requests
|
| 179 |
+
</div>
|
| 180 |
+
<div style={{ color: c.ink }}>opencode.ai/data</div>
|
| 181 |
+
</div>
|
| 182 |
+
</div>
|
| 183 |
+
</AbsoluteFill>
|
| 184 |
+
)
|
| 185 |
+
}
|
artifacts/glm52-rise-video/src/index.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Composition, registerRoot } from "remotion"
|
| 2 |
+
import { GLM52Rise } from "./video"
|
| 3 |
+
import { NZSheep } from "./sheep"
|
| 4 |
+
import { NovelTokens } from "./novel"
|
| 5 |
+
import { FlashShare } from "./flash"
|
| 6 |
+
import { MiniMaxClimb } from "./minimax"
|
| 7 |
+
import { JuneTotals } from "./june"
|
| 8 |
+
|
| 9 |
+
function Root() {
|
| 10 |
+
return (
|
| 11 |
+
<>
|
| 12 |
+
<Composition id="GLM52Rise" component={GLM52Rise} durationInFrames={240} fps={30} width={1080} height={1080} />
|
| 13 |
+
<Composition id="NZSheep" component={NZSheep} durationInFrames={150} fps={30} width={1080} height={1080} />
|
| 14 |
+
<Composition
|
| 15 |
+
id="NovelTokens"
|
| 16 |
+
component={NovelTokens}
|
| 17 |
+
durationInFrames={150}
|
| 18 |
+
fps={30}
|
| 19 |
+
width={1080}
|
| 20 |
+
height={1080}
|
| 21 |
+
/>
|
| 22 |
+
<Composition id="FlashShare" component={FlashShare} durationInFrames={165} fps={30} width={1080} height={1080} />
|
| 23 |
+
<Composition
|
| 24 |
+
id="MiniMaxClimb"
|
| 25 |
+
component={MiniMaxClimb}
|
| 26 |
+
durationInFrames={165}
|
| 27 |
+
fps={30}
|
| 28 |
+
width={1080}
|
| 29 |
+
height={1080}
|
| 30 |
+
/>
|
| 31 |
+
<Composition id="JuneTotals" component={JuneTotals} durationInFrames={1} fps={30} width={1080} height={1080} />
|
| 32 |
+
</>
|
| 33 |
+
)
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
registerRoot(Root)
|
artifacts/glm52-rise-video/src/june.tsx
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react"
|
| 2 |
+
import { AbsoluteFill } from "remotion"
|
| 3 |
+
|
| 4 |
+
const c = {
|
| 5 |
+
bg: "#ffffff",
|
| 6 |
+
ink: "#161616",
|
| 7 |
+
muted: "#5c5c5c",
|
| 8 |
+
faint: "#808080",
|
| 9 |
+
line: "#e6e6e6",
|
| 10 |
+
dot: "#dcdcdc",
|
| 11 |
+
accent: "#3b5cf6",
|
| 12 |
+
}
|
| 13 |
+
const MONO = '"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
|
| 14 |
+
|
| 15 |
+
const DOT_MASK =
|
| 16 |
+
"url(\"data:image/svg+xml,%3Csvg viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0H2V2H0V0Z' fill='black'/%3E%3C/svg%3E\")"
|
| 17 |
+
|
| 18 |
+
// verified: OpenCode Go (tier=Go, dataset=zen), June 1-30, 2026.
|
| 19 |
+
// 72.78T tokens · 651.4M requests · 11.42M sessions -> rounded headline figures.
|
| 20 |
+
|
| 21 |
+
function DataWordmark({ height = 30 }: { height?: number }) {
|
| 22 |
+
return (
|
| 23 |
+
<svg width={(height * 66) / 20} height={height} viewBox="0 0 66 20" fill="none" style={{ color: c.ink }}>
|
| 24 |
+
<path opacity="0.2" d="M12 16H4V8H12V16Z" fill="currentColor" />
|
| 25 |
+
<path d="M12 4H4V16H12V4ZM16 20H0V0H16V20Z" fill="currentColor" />
|
| 26 |
+
<path
|
| 27 |
+
d="M63.3543 16L62.5119 12.8711H58.6437L57.8013 16H55.7383L59.2454 4H61.9618L65.4689 16H63.3543ZM61.0678 7.851L60.6896 5.94269H60.4489L60.0707 7.851L59.1595 11.1347H61.9962L61.0678 7.851Z"
|
| 28 |
+
fill="currentColor"
|
| 29 |
+
/>
|
| 30 |
+
<path d="M52.5951 5.87392V16H50.4461V5.87392H47.4375V4H55.6209V5.87392H52.5951Z" fill="currentColor" />
|
| 31 |
+
<path
|
| 32 |
+
d="M45.2059 16L44.3635 12.8711H40.4953L39.6529 16H37.5898L41.097 4H43.8133L47.3205 16H45.2059ZM42.9194 7.851L42.5411 5.94269H42.3004L41.9222 7.851L41.011 11.1347H43.8477L42.9194 7.851Z"
|
| 33 |
+
fill="currentColor"
|
| 34 |
+
/>
|
| 35 |
+
<path
|
| 36 |
+
d="M28 4H32.0917C32.8138 4 33.4556 4.11461 34.0172 4.34384C34.5903 4.5616 35.0716 4.9169 35.4613 5.40974C35.8625 5.89112 36.1662 6.51003 36.3725 7.26648C36.5788 8.02292 36.6819 8.9341 36.6819 10C36.6819 11.0659 36.5788 11.9771 36.3725 12.7335C36.1662 13.49 35.8625 14.1146 35.4613 14.6075C35.0716 15.0888 34.5903 15.4441 34.0172 15.6734C33.4556 15.8911 32.8138 16 32.0917 16H28V4ZM32.0917 14.1261C32.8252 14.1261 33.3926 13.9026 33.7937 13.4556C34.1948 12.9971 34.3954 12.3152 34.3954 11.4097V8.59026C34.3954 7.68481 34.1948 7.0086 33.7937 6.5616C33.3926 6.10315 32.8252 5.87392 32.0917 5.87392H30.149V14.1261H32.0917Z"
|
| 37 |
+
fill="currentColor"
|
| 38 |
+
/>
|
| 39 |
+
</svg>
|
| 40 |
+
)
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
function DotBand() {
|
| 44 |
+
return (
|
| 45 |
+
<div
|
| 46 |
+
style={{
|
| 47 |
+
height: 12,
|
| 48 |
+
background: c.dot,
|
| 49 |
+
WebkitMaskImage: DOT_MASK,
|
| 50 |
+
maskImage: DOT_MASK,
|
| 51 |
+
WebkitMaskSize: "12px 12px",
|
| 52 |
+
maskSize: "12px 12px",
|
| 53 |
+
WebkitMaskRepeat: "repeat",
|
| 54 |
+
maskRepeat: "repeat",
|
| 55 |
+
WebkitMaskPosition: "left top",
|
| 56 |
+
maskPosition: "left top",
|
| 57 |
+
}}
|
| 58 |
+
/>
|
| 59 |
+
)
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
function Metric({ value, label }: { value: string; label: string }) {
|
| 63 |
+
return (
|
| 64 |
+
<div>
|
| 65 |
+
<div
|
| 66 |
+
style={{
|
| 67 |
+
fontSize: 92,
|
| 68 |
+
fontWeight: 600,
|
| 69 |
+
letterSpacing: -3,
|
| 70 |
+
lineHeight: 1,
|
| 71 |
+
fontVariantNumeric: "tabular-nums",
|
| 72 |
+
marginLeft: -8, // align the glyph's visual left edge to the column
|
| 73 |
+
}}
|
| 74 |
+
>
|
| 75 |
+
{value}
|
| 76 |
+
</div>
|
| 77 |
+
<div style={{ marginTop: 16, fontSize: 24, fontWeight: 500, color: c.muted, letterSpacing: 1 }}>{label}</div>
|
| 78 |
+
</div>
|
| 79 |
+
)
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
export function JuneTotals() {
|
| 83 |
+
return (
|
| 84 |
+
<AbsoluteFill style={{ background: c.bg, color: c.ink, fontFamily: MONO, padding: 72, boxSizing: "border-box" }}>
|
| 85 |
+
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
| 86 |
+
{/* header */}
|
| 87 |
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 22 }}>
|
| 88 |
+
<DataWordmark height={30} />
|
| 89 |
+
<div style={{ fontSize: 20, fontWeight: 500, color: c.faint, letterSpacing: 1 }}>MONTHLY RECAP</div>
|
| 90 |
+
</div>
|
| 91 |
+
<DotBand />
|
| 92 |
+
|
| 93 |
+
{/* hero */}
|
| 94 |
+
<div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "center" }}>
|
| 95 |
+
<div style={{ fontSize: 25, fontWeight: 600, color: c.muted, letterSpacing: 3 }}>OPENCODE GO · JUNE 2026</div>
|
| 96 |
+
<div style={{ marginTop: 14 }}>
|
| 97 |
+
<div
|
| 98 |
+
style={{
|
| 99 |
+
fontSize: 300,
|
| 100 |
+
fontWeight: 600,
|
| 101 |
+
letterSpacing: -10,
|
| 102 |
+
lineHeight: 0.82,
|
| 103 |
+
color: c.accent,
|
| 104 |
+
marginLeft: -22,
|
| 105 |
+
}}
|
| 106 |
+
>
|
| 107 |
+
73T
|
| 108 |
+
</div>
|
| 109 |
+
<div style={{ fontSize: 50, fontWeight: 600, color: c.ink, marginTop: 10 }}>tokens processed</div>
|
| 110 |
+
</div>
|
| 111 |
+
|
| 112 |
+
{/* supporting metrics */}
|
| 113 |
+
<div
|
| 114 |
+
style={{
|
| 115 |
+
display: "grid",
|
| 116 |
+
gridTemplateColumns: "1fr 1fr",
|
| 117 |
+
marginTop: 60,
|
| 118 |
+
paddingTop: 40,
|
| 119 |
+
borderTop: `1px solid ${c.line}`,
|
| 120 |
+
}}
|
| 121 |
+
>
|
| 122 |
+
<Metric value="650M" label="requests" />
|
| 123 |
+
<Metric value="11M" label="sessions" />
|
| 124 |
+
</div>
|
| 125 |
+
</div>
|
| 126 |
+
|
| 127 |
+
{/* footer */}
|
| 128 |
+
<DotBand />
|
| 129 |
+
<div
|
| 130 |
+
style={{
|
| 131 |
+
display: "flex",
|
| 132 |
+
justifyContent: "flex-end",
|
| 133 |
+
alignItems: "center",
|
| 134 |
+
marginTop: 22,
|
| 135 |
+
fontSize: 20,
|
| 136 |
+
fontWeight: 500,
|
| 137 |
+
}}
|
| 138 |
+
>
|
| 139 |
+
<div style={{ color: c.ink }}>opencode.ai/data</div>
|
| 140 |
+
</div>
|
| 141 |
+
</div>
|
| 142 |
+
</AbsoluteFill>
|
| 143 |
+
)
|
| 144 |
+
}
|
artifacts/glm52-rise-video/src/minimax.tsx
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react"
|
| 2 |
+
import { AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion"
|
| 3 |
+
|
| 4 |
+
const c = {
|
| 5 |
+
bg: "#ffffff",
|
| 6 |
+
ink: "#161616",
|
| 7 |
+
muted: "#5c5c5c",
|
| 8 |
+
faint: "#808080",
|
| 9 |
+
line: "#e6e6e6",
|
| 10 |
+
dot: "#e4e4e4",
|
| 11 |
+
accent: "#3b5cf6",
|
| 12 |
+
accentHi: "#5b78ff",
|
| 13 |
+
accentDim: "#aebcf3",
|
| 14 |
+
}
|
| 15 |
+
const MONO = '"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
|
| 16 |
+
|
| 17 |
+
const DOT_MASK =
|
| 18 |
+
"url(\"data:image/svg+xml,%3Csvg viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0H2V2H0V0Z' fill='black'/%3E%3C/svg%3E\")"
|
| 19 |
+
|
| 20 |
+
// verified: minimax-m3, OpenCode Go (tier=Go, dataset=zen), weekly total_tokens.
|
| 21 |
+
// W26 2.559T is +23.2% / +482.3B vs W25 2.077T.
|
| 22 |
+
const weeks = [
|
| 23 |
+
{ label: "May 25", t: 0.008 },
|
| 24 |
+
{ label: "Jun 1", t: 0.429 },
|
| 25 |
+
{ label: "Jun 8", t: 1.192 },
|
| 26 |
+
{ label: "Jun 15", t: 2.077 },
|
| 27 |
+
{ label: "Jun 22", t: 2.559, latest: true },
|
| 28 |
+
]
|
| 29 |
+
const AXIS_MAX = 3.0
|
| 30 |
+
|
| 31 |
+
function DataWordmark({ height = 30 }: { height?: number }) {
|
| 32 |
+
return (
|
| 33 |
+
<svg width={(height * 66) / 20} height={height} viewBox="0 0 66 20" fill="none" style={{ color: c.ink }}>
|
| 34 |
+
<path opacity="0.2" d="M12 16H4V8H12V16Z" fill="currentColor" />
|
| 35 |
+
<path d="M12 4H4V16H12V4ZM16 20H0V0H16V20Z" fill="currentColor" />
|
| 36 |
+
<path
|
| 37 |
+
d="M63.3543 16L62.5119 12.8711H58.6437L57.8013 16H55.7383L59.2454 4H61.9618L65.4689 16H63.3543ZM61.0678 7.851L60.6896 5.94269H60.4489L60.0707 7.851L59.1595 11.1347H61.9962L61.0678 7.851Z"
|
| 38 |
+
fill="currentColor"
|
| 39 |
+
/>
|
| 40 |
+
<path d="M52.5951 5.87392V16H50.4461V5.87392H47.4375V4H55.6209V5.87392H52.5951Z" fill="currentColor" />
|
| 41 |
+
<path
|
| 42 |
+
d="M45.2059 16L44.3635 12.8711H40.4953L39.6529 16H37.5898L41.097 4H43.8133L47.3205 16H45.2059ZM42.9194 7.851L42.5411 5.94269H42.3004L41.9222 7.851L41.011 11.1347H43.8477L42.9194 7.851Z"
|
| 43 |
+
fill="currentColor"
|
| 44 |
+
/>
|
| 45 |
+
<path
|
| 46 |
+
d="M28 4H32.0917C32.8138 4 33.4556 4.11461 34.0172 4.34384C34.5903 4.5616 35.0716 4.9169 35.4613 5.40974C35.8625 5.89112 36.1662 6.51003 36.3725 7.26648C36.5788 8.02292 36.6819 8.9341 36.6819 10C36.6819 11.0659 36.5788 11.9771 36.3725 12.7335C36.1662 13.49 35.8625 14.1146 35.4613 14.6075C35.0716 15.0888 34.5903 15.4441 34.0172 15.6734C33.4556 15.8911 32.8138 16 32.0917 16H28V4ZM32.0917 14.1261C32.8252 14.1261 33.3926 13.9026 33.7937 13.4556C34.1948 12.9971 34.3954 12.3152 34.3954 11.4097V8.59026C34.3954 7.68481 34.1948 7.0086 33.7937 6.5616C33.3926 6.10315 32.8252 5.87392 32.0917 5.87392H30.149V14.1261H32.0917Z"
|
| 47 |
+
fill="currentColor"
|
| 48 |
+
/>
|
| 49 |
+
</svg>
|
| 50 |
+
)
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
const CHART_H = 420 // multiple of 12 so the dotted tracks never clip
|
| 54 |
+
|
| 55 |
+
export function MiniMaxClimb() {
|
| 56 |
+
const frame = useCurrentFrame()
|
| 57 |
+
const { fps } = useVideoConfig()
|
| 58 |
+
|
| 59 |
+
const grow = (i: number) =>
|
| 60 |
+
Math.min(
|
| 61 |
+
1,
|
| 62 |
+
Math.max(0, spring({ frame: frame - 22 - i * 9, fps, config: { damping: 18, stiffness: 110, mass: 0.6 } })),
|
| 63 |
+
)
|
| 64 |
+
|
| 65 |
+
return (
|
| 66 |
+
<AbsoluteFill style={{ background: c.bg, color: c.ink, fontFamily: MONO, padding: 72, boxSizing: "border-box" }}>
|
| 67 |
+
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
| 68 |
+
{/* header */}
|
| 69 |
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
| 70 |
+
<DataWordmark height={30} />
|
| 71 |
+
<div style={{ fontSize: 20, fontWeight: 500, color: c.faint, letterSpacing: 1 }}>JUN 22–28, 2026</div>
|
| 72 |
+
</div>
|
| 73 |
+
|
| 74 |
+
{/* headline (static) */}
|
| 75 |
+
<div style={{ marginTop: 50 }}>
|
| 76 |
+
<div style={{ fontSize: 23, fontWeight: 600, color: c.muted, letterSpacing: 2 }}>
|
| 77 |
+
OPENCODE GO · WEEKLY TOKENS
|
| 78 |
+
</div>
|
| 79 |
+
<div
|
| 80 |
+
style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 24, marginTop: 14 }}
|
| 81 |
+
>
|
| 82 |
+
<div style={{ fontSize: 62, fontWeight: 600, letterSpacing: -2, lineHeight: 1 }}>MiniMax M3</div>
|
| 83 |
+
<div style={{ textAlign: "right", flexShrink: 0 }}>
|
| 84 |
+
<div
|
| 85 |
+
style={{
|
| 86 |
+
fontSize: 84,
|
| 87 |
+
fontWeight: 600,
|
| 88 |
+
letterSpacing: -2,
|
| 89 |
+
lineHeight: 1,
|
| 90 |
+
color: c.accent,
|
| 91 |
+
fontVariantNumeric: "tabular-nums",
|
| 92 |
+
}}
|
| 93 |
+
>
|
| 94 |
+
+23.2%
|
| 95 |
+
</div>
|
| 96 |
+
<div style={{ fontSize: 19, fontWeight: 500, color: c.muted, letterSpacing: 1, marginTop: 6 }}>
|
| 97 |
+
WEEK OVER WEEK
|
| 98 |
+
</div>
|
| 99 |
+
</div>
|
| 100 |
+
</div>
|
| 101 |
+
</div>
|
| 102 |
+
|
| 103 |
+
{/* column chart */}
|
| 104 |
+
<div style={{ flex: 1, display: "flex", alignItems: "flex-end", marginTop: 30 }}>
|
| 105 |
+
<div style={{ width: "100%", display: "flex", alignItems: "flex-end", gap: 30 }}>
|
| 106 |
+
{weeks.map((w, i) => {
|
| 107 |
+
const g = grow(i)
|
| 108 |
+
const h = Math.round((w.t / AXIS_MAX) * CHART_H * g)
|
| 109 |
+
return (
|
| 110 |
+
<div key={w.label} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center" }}>
|
| 111 |
+
{/* value + bar */}
|
| 112 |
+
<div style={{ position: "relative", width: "100%", height: CHART_H }}>
|
| 113 |
+
{/* dotted track */}
|
| 114 |
+
<div
|
| 115 |
+
style={{
|
| 116 |
+
position: "absolute",
|
| 117 |
+
inset: 0,
|
| 118 |
+
background: c.dot,
|
| 119 |
+
WebkitMaskImage: DOT_MASK,
|
| 120 |
+
maskImage: DOT_MASK,
|
| 121 |
+
WebkitMaskSize: "12px 12px",
|
| 122 |
+
maskSize: "12px 12px",
|
| 123 |
+
WebkitMaskRepeat: "repeat",
|
| 124 |
+
maskRepeat: "repeat",
|
| 125 |
+
WebkitMaskPosition: "left bottom",
|
| 126 |
+
maskPosition: "left bottom",
|
| 127 |
+
}}
|
| 128 |
+
/>
|
| 129 |
+
{/* fill */}
|
| 130 |
+
<div
|
| 131 |
+
style={{
|
| 132 |
+
position: "absolute",
|
| 133 |
+
left: 0,
|
| 134 |
+
right: 0,
|
| 135 |
+
bottom: 0,
|
| 136 |
+
height: h,
|
| 137 |
+
background: w.latest ? c.accent : c.accentDim,
|
| 138 |
+
borderTop: w.latest ? `3px solid ${c.accentHi}` : "none",
|
| 139 |
+
}}
|
| 140 |
+
/>
|
| 141 |
+
{/* value label */}
|
| 142 |
+
<div
|
| 143 |
+
style={{
|
| 144 |
+
position: "absolute",
|
| 145 |
+
left: 0,
|
| 146 |
+
right: 0,
|
| 147 |
+
bottom: h + 10,
|
| 148 |
+
textAlign: "center",
|
| 149 |
+
fontSize: 26,
|
| 150 |
+
fontWeight: w.latest ? 600 : 500,
|
| 151 |
+
color: w.latest ? c.accent : c.muted,
|
| 152 |
+
fontVariantNumeric: "tabular-nums",
|
| 153 |
+
opacity: interpolate(g, [0.5, 1], [0, 1], {
|
| 154 |
+
extrapolateLeft: "clamp",
|
| 155 |
+
extrapolateRight: "clamp",
|
| 156 |
+
}),
|
| 157 |
+
}}
|
| 158 |
+
>
|
| 159 |
+
{w.t.toFixed(2)}T
|
| 160 |
+
</div>
|
| 161 |
+
</div>
|
| 162 |
+
{/* week label */}
|
| 163 |
+
<div
|
| 164 |
+
style={{
|
| 165 |
+
marginTop: 14,
|
| 166 |
+
fontSize: 18,
|
| 167 |
+
fontWeight: 500,
|
| 168 |
+
color: w.latest ? c.ink : c.faint,
|
| 169 |
+
}}
|
| 170 |
+
>
|
| 171 |
+
{w.label}
|
| 172 |
+
</div>
|
| 173 |
+
</div>
|
| 174 |
+
)
|
| 175 |
+
})}
|
| 176 |
+
</div>
|
| 177 |
+
</div>
|
| 178 |
+
|
| 179 |
+
{/* footer */}
|
| 180 |
+
<div
|
| 181 |
+
style={{
|
| 182 |
+
display: "flex",
|
| 183 |
+
justifyContent: "space-between",
|
| 184 |
+
alignItems: "center",
|
| 185 |
+
marginTop: 22,
|
| 186 |
+
paddingTop: 22,
|
| 187 |
+
borderTop: `1px solid ${c.line}`,
|
| 188 |
+
fontSize: 20,
|
| 189 |
+
fontWeight: 500,
|
| 190 |
+
}}
|
| 191 |
+
>
|
| 192 |
+
<div style={{ display: "inline-flex", alignItems: "center", gap: 9, color: c.muted }}>
|
| 193 |
+
<span style={{ width: 13, height: 13, background: c.accent, display: "inline-block" }} />
|
| 194 |
+
2.56T tokens last week · +482.3B added
|
| 195 |
+
</div>
|
| 196 |
+
<div style={{ color: c.ink }}>opencode.ai/data</div>
|
| 197 |
+
</div>
|
| 198 |
+
</div>
|
| 199 |
+
</AbsoluteFill>
|
| 200 |
+
)
|
| 201 |
+
}
|
artifacts/glm52-rise-video/src/novel.tsx
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react"
|
| 2 |
+
import { AbsoluteFill, Easing, Img, interpolate, staticFile, useCurrentFrame } from "remotion"
|
| 3 |
+
|
| 4 |
+
const c = {
|
| 5 |
+
white: "#ffffff",
|
| 6 |
+
dim: "rgba(255,255,255,0.74)",
|
| 7 |
+
}
|
| 8 |
+
const MONO = '"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
|
| 9 |
+
|
| 10 |
+
// verified: OpenCode Go, week of Jun 22-28, 2026 (2026-W26)
|
| 11 |
+
// 19,642,742,937,105 tokens / 173,651,197 requests = 113,116 tokens/request
|
| 12 |
+
const AVG = 113116
|
| 13 |
+
const K = Math.round(AVG / 1000) // 113
|
| 14 |
+
|
| 15 |
+
const nf = new Intl.NumberFormat("en-US")
|
| 16 |
+
|
| 17 |
+
function DataWordmark({ height = 30 }: { height?: number }) {
|
| 18 |
+
return (
|
| 19 |
+
<svg width={(height * 66) / 20} height={height} viewBox="0 0 66 20" fill="none" style={{ color: c.white }}>
|
| 20 |
+
<path opacity="0.35" d="M12 16H4V8H12V16Z" fill="currentColor" />
|
| 21 |
+
<path d="M12 4H4V16H12V4ZM16 20H0V0H16V20Z" fill="currentColor" />
|
| 22 |
+
<path
|
| 23 |
+
d="M63.3543 16L62.5119 12.8711H58.6437L57.8013 16H55.7383L59.2454 4H61.9618L65.4689 16H63.3543ZM61.0678 7.851L60.6896 5.94269H60.4489L60.0707 7.851L59.1595 11.1347H61.9962L61.0678 7.851Z"
|
| 24 |
+
fill="currentColor"
|
| 25 |
+
/>
|
| 26 |
+
<path d="M52.5951 5.87392V16H50.4461V5.87392H47.4375V4H55.6209V5.87392H52.5951Z" fill="currentColor" />
|
| 27 |
+
<path
|
| 28 |
+
d="M45.2059 16L44.3635 12.8711H40.4953L39.6529 16H37.5898L41.097 4H43.8133L47.3205 16H45.2059ZM42.9194 7.851L42.5411 5.94269H42.3004L41.9222 7.851L41.011 11.1347H43.8477L42.9194 7.851Z"
|
| 29 |
+
fill="currentColor"
|
| 30 |
+
/>
|
| 31 |
+
<path
|
| 32 |
+
d="M28 4H32.0917C32.8138 4 33.4556 4.11461 34.0172 4.34384C34.5903 4.5616 35.0716 4.9169 35.4613 5.40974C35.8625 5.89112 36.1662 6.51003 36.3725 7.26648C36.5788 8.02292 36.6819 8.9341 36.6819 10C36.6819 11.0659 36.5788 11.9771 36.3725 12.7335C36.1662 13.49 35.8625 14.1146 35.4613 14.6075C35.0716 15.0888 34.5903 15.4441 34.0172 15.6734C33.4556 15.8911 32.8138 16 32.0917 16H28V4ZM32.0917 14.1261C32.8252 14.1261 33.3926 13.9026 33.7937 13.4556C34.1948 12.9971 34.3954 12.3152 34.3954 11.4097V8.59026C34.3954 7.68481 34.1948 7.0086 33.7937 6.5616C33.3926 6.10315 32.8252 5.87392 32.0917 5.87392H30.149V14.1261H32.0917Z"
|
| 33 |
+
fill="currentColor"
|
| 34 |
+
/>
|
| 35 |
+
</svg>
|
| 36 |
+
)
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
export function NovelTokens() {
|
| 40 |
+
const frame = useCurrentFrame()
|
| 41 |
+
|
| 42 |
+
const k = Math.round(
|
| 43 |
+
K *
|
| 44 |
+
interpolate(frame, [18, 92], [0, 1], {
|
| 45 |
+
extrapolateLeft: "clamp",
|
| 46 |
+
extrapolateRight: "clamp",
|
| 47 |
+
easing: Easing.out(Easing.cubic),
|
| 48 |
+
}),
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
const zoom = interpolate(frame, [0, 150], [1.06, 1.12], {
|
| 52 |
+
extrapolateRight: "clamp",
|
| 53 |
+
easing: Easing.inOut(Easing.quad),
|
| 54 |
+
})
|
| 55 |
+
|
| 56 |
+
return (
|
| 57 |
+
<AbsoluteFill style={{ background: "#0c0c0c", overflow: "hidden" }}>
|
| 58 |
+
<Img
|
| 59 |
+
src={staticFile("book.jpg")}
|
| 60 |
+
style={{
|
| 61 |
+
position: "absolute",
|
| 62 |
+
width: "100%",
|
| 63 |
+
height: "100%",
|
| 64 |
+
objectFit: "cover",
|
| 65 |
+
objectPosition: "center 34%",
|
| 66 |
+
transform: `scale(${zoom})`,
|
| 67 |
+
transformOrigin: "center 30%",
|
| 68 |
+
}}
|
| 69 |
+
/>
|
| 70 |
+
|
| 71 |
+
{/* legibility scrims */}
|
| 72 |
+
<div
|
| 73 |
+
style={{
|
| 74 |
+
position: "absolute",
|
| 75 |
+
inset: 0,
|
| 76 |
+
background:
|
| 77 |
+
"linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0.1) 44%, rgba(0,0,0,0.86) 100%)",
|
| 78 |
+
}}
|
| 79 |
+
/>
|
| 80 |
+
|
| 81 |
+
<div
|
| 82 |
+
style={{
|
| 83 |
+
position: "absolute",
|
| 84 |
+
inset: 0,
|
| 85 |
+
boxSizing: "border-box",
|
| 86 |
+
padding: 64,
|
| 87 |
+
color: c.white,
|
| 88 |
+
fontFamily: MONO,
|
| 89 |
+
display: "flex",
|
| 90 |
+
flexDirection: "column",
|
| 91 |
+
justifyContent: "space-between",
|
| 92 |
+
}}
|
| 93 |
+
>
|
| 94 |
+
{/* header */}
|
| 95 |
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
| 96 |
+
<DataWordmark height={30} />
|
| 97 |
+
<div style={{ fontSize: 20, fontWeight: 500, color: c.dim, letterSpacing: 1 }}>JUN 22–28, 2026</div>
|
| 98 |
+
</div>
|
| 99 |
+
|
| 100 |
+
{/* bottom block */}
|
| 101 |
+
<div>
|
| 102 |
+
<div style={{ fontSize: 23, fontWeight: 600, color: c.dim, letterSpacing: 2, marginBottom: 8 }}>
|
| 103 |
+
OPENCODE GO · LAST WEEK
|
| 104 |
+
</div>
|
| 105 |
+
<div
|
| 106 |
+
style={{
|
| 107 |
+
fontSize: 168,
|
| 108 |
+
fontWeight: 600,
|
| 109 |
+
lineHeight: 0.92,
|
| 110 |
+
letterSpacing: -5,
|
| 111 |
+
fontVariantNumeric: "tabular-nums",
|
| 112 |
+
}}
|
| 113 |
+
>
|
| 114 |
+
{k}K
|
| 115 |
+
</div>
|
| 116 |
+
<div style={{ fontSize: 50, fontWeight: 600, letterSpacing: -1, marginTop: 4 }}>tokens per request</div>
|
| 117 |
+
|
| 118 |
+
<div
|
| 119 |
+
style={{
|
| 120 |
+
display: "flex",
|
| 121 |
+
justifyContent: "space-between",
|
| 122 |
+
alignItems: "center",
|
| 123 |
+
marginTop: 30,
|
| 124 |
+
fontSize: 20,
|
| 125 |
+
fontWeight: 500,
|
| 126 |
+
}}
|
| 127 |
+
>
|
| 128 |
+
<div style={{ color: c.dim }}>{nf.format(AVG)} tokens / request · last week</div>
|
| 129 |
+
<div style={{ color: c.white }}>opencode.ai/data</div>
|
| 130 |
+
</div>
|
| 131 |
+
</div>
|
| 132 |
+
</div>
|
| 133 |
+
</AbsoluteFill>
|
| 134 |
+
)
|
| 135 |
+
}
|
artifacts/glm52-rise-video/src/sheep.tsx
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react"
|
| 2 |
+
import { AbsoluteFill, Easing, Img, interpolate, staticFile, useCurrentFrame } from "remotion"
|
| 3 |
+
|
| 4 |
+
const c = {
|
| 5 |
+
white: "#ffffff",
|
| 6 |
+
dim: "rgba(255,255,255,0.72)",
|
| 7 |
+
faint: "rgba(255,255,255,0.55)",
|
| 8 |
+
}
|
| 9 |
+
const MONO = '"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
|
| 10 |
+
|
| 11 |
+
// verified: NZ OpenCode Go, week of Jun 22-28, 2026 (2026-W26)
|
| 12 |
+
const TOKENS = 40_915_594_381 // 40.9B
|
| 13 |
+
const SHEEP = 23_600_000 // 23.6M
|
| 14 |
+
const PER_SHEEP = Math.round(TOKENS / SHEEP) // 1,734
|
| 15 |
+
const nf = new Intl.NumberFormat("en-US")
|
| 16 |
+
|
| 17 |
+
// the correct opencode "DATA" wordmark (white, over photo)
|
| 18 |
+
function DataWordmark({ height = 30 }: { height?: number }) {
|
| 19 |
+
return (
|
| 20 |
+
<svg width={(height * 66) / 20} height={height} viewBox="0 0 66 20" fill="none" style={{ color: c.white }}>
|
| 21 |
+
<path opacity="0.35" d="M12 16H4V8H12V16Z" fill="currentColor" />
|
| 22 |
+
<path d="M12 4H4V16H12V4ZM16 20H0V0H16V20Z" fill="currentColor" />
|
| 23 |
+
<path
|
| 24 |
+
d="M63.3543 16L62.5119 12.8711H58.6437L57.8013 16H55.7383L59.2454 4H61.9618L65.4689 16H63.3543ZM61.0678 7.851L60.6896 5.94269H60.4489L60.0707 7.851L59.1595 11.1347H61.9962L61.0678 7.851Z"
|
| 25 |
+
fill="currentColor"
|
| 26 |
+
/>
|
| 27 |
+
<path d="M52.5951 5.87392V16H50.4461V5.87392H47.4375V4H55.6209V5.87392H52.5951Z" fill="currentColor" />
|
| 28 |
+
<path
|
| 29 |
+
d="M45.2059 16L44.3635 12.8711H40.4953L39.6529 16H37.5898L41.097 4H43.8133L47.3205 16H45.2059ZM42.9194 7.851L42.5411 5.94269H42.3004L41.9222 7.851L41.011 11.1347H43.8477L42.9194 7.851Z"
|
| 30 |
+
fill="currentColor"
|
| 31 |
+
/>
|
| 32 |
+
<path
|
| 33 |
+
d="M28 4H32.0917C32.8138 4 33.4556 4.11461 34.0172 4.34384C34.5903 4.5616 35.0716 4.9169 35.4613 5.40974C35.8625 5.89112 36.1662 6.51003 36.3725 7.26648C36.5788 8.02292 36.6819 8.9341 36.6819 10C36.6819 11.0659 36.5788 11.9771 36.3725 12.7335C36.1662 13.49 35.8625 14.1146 35.4613 14.6075C35.0716 15.0888 34.5903 15.4441 34.0172 15.6734C33.4556 15.8911 32.8138 16 32.0917 16H28V4ZM32.0917 14.1261C32.8252 14.1261 33.3926 13.9026 33.7937 13.4556C34.1948 12.9971 34.3954 12.3152 34.3954 11.4097V8.59026C34.3954 7.68481 34.1948 7.0086 33.7937 6.5616C33.3926 6.10315 32.8252 5.87392 32.0917 5.87392H30.149V14.1261H32.0917Z"
|
| 34 |
+
fill="currentColor"
|
| 35 |
+
/>
|
| 36 |
+
</svg>
|
| 37 |
+
)
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
export function NZSheep() {
|
| 41 |
+
const frame = useCurrentFrame()
|
| 42 |
+
|
| 43 |
+
const count = Math.round(
|
| 44 |
+
PER_SHEEP *
|
| 45 |
+
interpolate(frame, [18, 90], [0, 1], {
|
| 46 |
+
extrapolateLeft: "clamp",
|
| 47 |
+
extrapolateRight: "clamp",
|
| 48 |
+
easing: Easing.out(Easing.cubic),
|
| 49 |
+
}),
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
// slow Ken Burns push-in (scale up only — never reveals an edge)
|
| 53 |
+
const zoom = interpolate(frame, [0, 150], [1.06, 1.12], {
|
| 54 |
+
extrapolateRight: "clamp",
|
| 55 |
+
easing: Easing.inOut(Easing.quad),
|
| 56 |
+
})
|
| 57 |
+
|
| 58 |
+
return (
|
| 59 |
+
<AbsoluteFill style={{ background: "#0c0c0c", overflow: "hidden" }}>
|
| 60 |
+
{/* the sheep, staring */}
|
| 61 |
+
<Img
|
| 62 |
+
src={staticFile("sheep.jpg")}
|
| 63 |
+
style={{
|
| 64 |
+
position: "absolute",
|
| 65 |
+
width: "100%",
|
| 66 |
+
height: "100%",
|
| 67 |
+
objectFit: "cover",
|
| 68 |
+
objectPosition: "center 38%",
|
| 69 |
+
transform: `scale(${zoom})`,
|
| 70 |
+
transformOrigin: "center 35%",
|
| 71 |
+
}}
|
| 72 |
+
/>
|
| 73 |
+
|
| 74 |
+
{/* legibility scrims */}
|
| 75 |
+
<div
|
| 76 |
+
style={{
|
| 77 |
+
position: "absolute",
|
| 78 |
+
inset: 0,
|
| 79 |
+
background:
|
| 80 |
+
"linear-gradient(to bottom, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0) 22%, rgba(0,0,0,0) 48%, rgba(0,0,0,0.78) 100%)",
|
| 81 |
+
}}
|
| 82 |
+
/>
|
| 83 |
+
|
| 84 |
+
{/* content */}
|
| 85 |
+
<div
|
| 86 |
+
style={{
|
| 87 |
+
position: "absolute",
|
| 88 |
+
inset: 0,
|
| 89 |
+
boxSizing: "border-box",
|
| 90 |
+
padding: 64,
|
| 91 |
+
color: c.white,
|
| 92 |
+
fontFamily: MONO,
|
| 93 |
+
display: "flex",
|
| 94 |
+
flexDirection: "column",
|
| 95 |
+
justifyContent: "space-between",
|
| 96 |
+
}}
|
| 97 |
+
>
|
| 98 |
+
{/* header */}
|
| 99 |
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
| 100 |
+
<DataWordmark height={30} />
|
| 101 |
+
<div style={{ fontSize: 20, fontWeight: 500, color: c.dim, letterSpacing: 1 }}>JUN 22–28, 2026</div>
|
| 102 |
+
</div>
|
| 103 |
+
|
| 104 |
+
{/* bottom block */}
|
| 105 |
+
<div>
|
| 106 |
+
<div style={{ fontSize: 23, fontWeight: 600, color: c.dim, letterSpacing: 2, marginBottom: 8 }}>
|
| 107 |
+
OPENCODE GO · NEW ZEALAND
|
| 108 |
+
</div>
|
| 109 |
+
<div
|
| 110 |
+
style={{
|
| 111 |
+
fontSize: 168,
|
| 112 |
+
fontWeight: 600,
|
| 113 |
+
lineHeight: 0.92,
|
| 114 |
+
letterSpacing: -5,
|
| 115 |
+
fontVariantNumeric: "tabular-nums",
|
| 116 |
+
}}
|
| 117 |
+
>
|
| 118 |
+
{nf.format(count)}
|
| 119 |
+
</div>
|
| 120 |
+
<div style={{ fontSize: 50, fontWeight: 600, letterSpacing: -1, marginTop: 4 }}>tokens per sheep</div>
|
| 121 |
+
|
| 122 |
+
<div
|
| 123 |
+
style={{
|
| 124 |
+
display: "flex",
|
| 125 |
+
justifyContent: "space-between",
|
| 126 |
+
alignItems: "center",
|
| 127 |
+
marginTop: 34,
|
| 128 |
+
fontSize: 20,
|
| 129 |
+
fontWeight: 500,
|
| 130 |
+
}}
|
| 131 |
+
>
|
| 132 |
+
<div style={{ color: c.dim }}>40.9B tokens ÷ 23.6M sheep · last week</div>
|
| 133 |
+
<div style={{ color: c.white }}>opencode.ai/data</div>
|
| 134 |
+
</div>
|
| 135 |
+
</div>
|
| 136 |
+
</div>
|
| 137 |
+
</AbsoluteFill>
|
| 138 |
+
)
|
| 139 |
+
}
|
artifacts/glm52-rise-video/src/video.tsx
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react"
|
| 2 |
+
import { AbsoluteFill, Easing, interpolate, useCurrentFrame, useVideoConfig } from "remotion"
|
| 3 |
+
import { days, launchIndex, glmWeekTokensT, segments } from "./data"
|
| 4 |
+
|
| 5 |
+
// stats.opencode.ai design tokens (light theme)
|
| 6 |
+
const c = {
|
| 7 |
+
bg: "#ffffff",
|
| 8 |
+
ink: "#161616",
|
| 9 |
+
muted: "#5c5c5c",
|
| 10 |
+
faint: "#808080",
|
| 11 |
+
line: "#e6e6e6",
|
| 12 |
+
dot: "#ededed",
|
| 13 |
+
accent: "#3b5cf6",
|
| 14 |
+
accentHi: "#5b78ff",
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
const MONO = '"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace'
|
| 18 |
+
const W = 1080
|
| 19 |
+
|
| 20 |
+
const DOT_MASK =
|
| 21 |
+
"url(\"data:image/svg+xml,%3Csvg viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0H2V2H0V0Z' fill='black'/%3E%3C/svg%3E\")"
|
| 22 |
+
|
| 23 |
+
const field = segments.filter((s) => !s.hero)
|
| 24 |
+
const glmColor = segments.find((s) => s.hero)!.color
|
| 25 |
+
|
| 26 |
+
const clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v))
|
| 27 |
+
|
| 28 |
+
// the correct opencode "DATA" wordmark (from stats.opencode.ai header)
|
| 29 |
+
function DataWordmark({ height = 30, color = c.ink }: { height?: number; color?: string }) {
|
| 30 |
+
return (
|
| 31 |
+
<svg width={(height * 66) / 20} height={height} viewBox="0 0 66 20" fill="none" style={{ color }}>
|
| 32 |
+
<path opacity="0.2" d="M12 16H4V8H12V16Z" fill="currentColor" />
|
| 33 |
+
<path d="M12 4H4V16H12V4ZM16 20H0V0H16V20Z" fill="currentColor" />
|
| 34 |
+
<path
|
| 35 |
+
d="M63.3543 16L62.5119 12.8711H58.6437L57.8013 16H55.7383L59.2454 4H61.9618L65.4689 16H63.3543ZM61.0678 7.851L60.6896 5.94269H60.4489L60.0707 7.851L59.1595 11.1347H61.9962L61.0678 7.851Z"
|
| 36 |
+
fill="currentColor"
|
| 37 |
+
/>
|
| 38 |
+
<path d="M52.5951 5.87392V16H50.4461V5.87392H47.4375V4H55.6209V5.87392H52.5951Z" fill="currentColor" />
|
| 39 |
+
<path
|
| 40 |
+
d="M45.2059 16L44.3635 12.8711H40.4953L39.6529 16H37.5898L41.097 4H43.8133L47.3205 16H45.2059ZM42.9194 7.851L42.5411 5.94269H42.3004L41.9222 7.851L41.011 11.1347H43.8477L42.9194 7.851Z"
|
| 41 |
+
fill="currentColor"
|
| 42 |
+
/>
|
| 43 |
+
<path
|
| 44 |
+
d="M28 4H32.0917C32.8138 4 33.4556 4.11461 34.0172 4.34384C34.5903 4.5616 35.0716 4.9169 35.4613 5.40974C35.8625 5.89112 36.1662 6.51003 36.3725 7.26648C36.5788 8.02292 36.6819 8.9341 36.6819 10C36.6819 11.0659 36.5788 11.9771 36.3725 12.7335C36.1662 13.49 35.8625 14.1146 35.4613 14.6075C35.0716 15.0888 34.5903 15.4441 34.0172 15.6734C33.4556 15.8911 32.8138 16 32.0917 16H28V4ZM32.0917 14.1261C32.8252 14.1261 33.3926 13.9026 33.7937 13.4556C34.1948 12.9971 34.3954 12.3152 34.3954 11.4097V8.59026C34.3954 7.68481 34.1948 7.0086 33.7937 6.5616C33.3926 6.10315 32.8252 5.87392 32.0917 5.87392H30.149V14.1261H32.0917Z"
|
| 45 |
+
fill="currentColor"
|
| 46 |
+
/>
|
| 47 |
+
</svg>
|
| 48 |
+
)
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
export function GLM52Rise() {
|
| 52 |
+
const frame = useCurrentFrame()
|
| 53 |
+
const { fps } = useVideoConfig()
|
| 54 |
+
|
| 55 |
+
// ---------- virtual camera ----------
|
| 56 |
+
// open zoomed-in on the field, pan right while the blue fills, then pull back to reveal.
|
| 57 |
+
const K = [0, 32, 150, 206, 240]
|
| 58 |
+
const ease = Easing.inOut(Easing.cubic)
|
| 59 |
+
const opt = { extrapolateLeft: "clamp" as const, extrapolateRight: "clamp" as const, easing: ease }
|
| 60 |
+
const s = interpolate(frame, K, [1.82, 1.72, 1.72, 1.0, 1.0], opt)
|
| 61 |
+
let fx = interpolate(frame, K, [420, 438, 760, 540, 540], opt)
|
| 62 |
+
let fy = interpolate(frame, K, [664, 664, 664, 540, 540], opt)
|
| 63 |
+
// keep the framing inside the 1080 canvas so edges never reveal black
|
| 64 |
+
fx = clamp(fx, 540 / s, W - 540 / s)
|
| 65 |
+
fy = clamp(fy, 540 / s, W - 540 / s)
|
| 66 |
+
const camera = `translate(${540 - fx * s}px, ${540 - fy * s}px) scale(${s})`
|
| 67 |
+
|
| 68 |
+
// ---------- blue sweep (synced to the pan) ----------
|
| 69 |
+
const p = interpolate(frame, [32, 150], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: ease })
|
| 70 |
+
const revealAmount = p * (days.length - launchIndex) + 0.35
|
| 71 |
+
const fillOf = (i: number) => clamp(revealAmount - (i - launchIndex), 0, 1)
|
| 72 |
+
|
| 73 |
+
// token number climbs as the camera pulls back and the headline re-enters frame
|
| 74 |
+
const tokensT =
|
| 75 |
+
glmWeekTokensT *
|
| 76 |
+
interpolate(frame, [150, 202], [0, 1], {
|
| 77 |
+
extrapolateLeft: "clamp",
|
| 78 |
+
extrapolateRight: "clamp",
|
| 79 |
+
easing: Easing.out(Easing.cubic),
|
| 80 |
+
})
|
| 81 |
+
|
| 82 |
+
// chart geometry
|
| 83 |
+
const chartH = 440
|
| 84 |
+
const chartW = 936
|
| 85 |
+
const gap = 14
|
| 86 |
+
const EXAGGERATE = 2.876 // broken y-axis: GLM-5.2 magnified ~2.9x for emphasis
|
| 87 |
+
|
| 88 |
+
return (
|
| 89 |
+
<AbsoluteFill style={{ background: c.bg, overflow: "hidden" }}>
|
| 90 |
+
<div
|
| 91 |
+
style={{
|
| 92 |
+
position: "absolute",
|
| 93 |
+
width: W,
|
| 94 |
+
height: W,
|
| 95 |
+
background: c.bg,
|
| 96 |
+
transformOrigin: "0 0",
|
| 97 |
+
transform: camera,
|
| 98 |
+
}}
|
| 99 |
+
>
|
| 100 |
+
<div
|
| 101 |
+
style={{
|
| 102 |
+
width: W,
|
| 103 |
+
height: W,
|
| 104 |
+
boxSizing: "border-box",
|
| 105 |
+
padding: 72,
|
| 106 |
+
color: c.ink,
|
| 107 |
+
fontFamily: MONO,
|
| 108 |
+
display: "flex",
|
| 109 |
+
flexDirection: "column",
|
| 110 |
+
}}
|
| 111 |
+
>
|
| 112 |
+
{/* header */}
|
| 113 |
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
|
| 114 |
+
<DataWordmark height={30} />
|
| 115 |
+
<div style={{ fontSize: 20, fontWeight: 500, color: c.faint, letterSpacing: 1 }}>JUN 12–25, 2026</div>
|
| 116 |
+
</div>
|
| 117 |
+
|
| 118 |
+
{/* headline (static) */}
|
| 119 |
+
<div style={{ marginTop: 52 }}>
|
| 120 |
+
<div style={{ fontSize: 92, fontWeight: 600, lineHeight: 0.98, letterSpacing: -2 }}>
|
| 121 |
+
GLM-5.2 <span style={{ color: c.accent }}>broke out</span>
|
| 122 |
+
</div>
|
| 123 |
+
<div style={{ marginTop: 22, fontSize: 30, fontWeight: 500, color: c.muted }}>
|
| 124 |
+
From 0 to <span style={{ color: c.ink }}>{tokensT.toFixed(2)}T tokens</span> in a week.
|
| 125 |
+
</div>
|
| 126 |
+
</div>
|
| 127 |
+
|
| 128 |
+
{/* stacked chart */}
|
| 129 |
+
<div style={{ flex: 1, display: "flex", alignItems: "flex-end", marginTop: 40 }}>
|
| 130 |
+
<div
|
| 131 |
+
style={{
|
| 132 |
+
position: "relative",
|
| 133 |
+
width: chartW,
|
| 134 |
+
height: chartH,
|
| 135 |
+
margin: "0 auto",
|
| 136 |
+
borderBottom: `2px solid ${c.ink}`,
|
| 137 |
+
boxSizing: "border-box",
|
| 138 |
+
}}
|
| 139 |
+
>
|
| 140 |
+
{/* faint dotted backdrop */}
|
| 141 |
+
<div
|
| 142 |
+
style={{
|
| 143 |
+
position: "absolute",
|
| 144 |
+
left: -8,
|
| 145 |
+
right: -8,
|
| 146 |
+
top: -8,
|
| 147 |
+
bottom: 0,
|
| 148 |
+
background: c.dot,
|
| 149 |
+
WebkitMaskImage: DOT_MASK,
|
| 150 |
+
maskImage: DOT_MASK,
|
| 151 |
+
WebkitMaskSize: "12px 12px",
|
| 152 |
+
maskSize: "12px 12px",
|
| 153 |
+
WebkitMaskRepeat: "repeat",
|
| 154 |
+
maskRepeat: "repeat",
|
| 155 |
+
}}
|
| 156 |
+
/>
|
| 157 |
+
|
| 158 |
+
{/* columns */}
|
| 159 |
+
<div style={{ position: "absolute", inset: 0, display: "flex", gap, alignItems: "flex-end" }}>
|
| 160 |
+
{days.map((d, i) => {
|
| 161 |
+
const glmShare = d.glm / d.total
|
| 162 |
+
const blueH = Math.round(glmShare * EXAGGERATE * chartH)
|
| 163 |
+
const filled = Math.round(blueH * fillOf(i))
|
| 164 |
+
const slotGap = filled > 2 ? 5 : 0
|
| 165 |
+
const fieldH = chartH - filled - slotGap
|
| 166 |
+
const fieldTotal = d.dsf + d.dsp + d.mm + d.others
|
| 167 |
+
return (
|
| 168 |
+
<div key={i} style={{ position: "relative", flex: 1, height: chartH }}>
|
| 169 |
+
{/* gray field of other models (already in place) */}
|
| 170 |
+
<div
|
| 171 |
+
style={{
|
| 172 |
+
position: "absolute",
|
| 173 |
+
top: 0,
|
| 174 |
+
left: 0,
|
| 175 |
+
right: 0,
|
| 176 |
+
height: fieldH,
|
| 177 |
+
display: "flex",
|
| 178 |
+
flexDirection: "column-reverse",
|
| 179 |
+
}}
|
| 180 |
+
>
|
| 181 |
+
{field.map((seg) => (
|
| 182 |
+
<div
|
| 183 |
+
key={seg.key}
|
| 184 |
+
style={{
|
| 185 |
+
height: Math.round(((d[seg.key as keyof typeof d] as number) / fieldTotal) * fieldH),
|
| 186 |
+
background: seg.color,
|
| 187 |
+
borderTop: `2px solid ${c.bg}`,
|
| 188 |
+
}}
|
| 189 |
+
/>
|
| 190 |
+
))}
|
| 191 |
+
</div>
|
| 192 |
+
{/* GLM-5.2, animates in */}
|
| 193 |
+
{filled > 2 && (
|
| 194 |
+
<div
|
| 195 |
+
style={{
|
| 196 |
+
position: "absolute",
|
| 197 |
+
left: 0,
|
| 198 |
+
right: 0,
|
| 199 |
+
bottom: 0,
|
| 200 |
+
height: filled,
|
| 201 |
+
background: glmColor,
|
| 202 |
+
borderTop: `2px solid ${c.accentHi}`,
|
| 203 |
+
}}
|
| 204 |
+
/>
|
| 205 |
+
)}
|
| 206 |
+
</div>
|
| 207 |
+
)
|
| 208 |
+
})}
|
| 209 |
+
</div>
|
| 210 |
+
</div>
|
| 211 |
+
</div>
|
| 212 |
+
|
| 213 |
+
{/* day axis */}
|
| 214 |
+
<div style={{ display: "flex", gap, width: chartW, margin: "14px auto 0" }}>
|
| 215 |
+
{days.map((d, i) => (
|
| 216 |
+
<div
|
| 217 |
+
key={i}
|
| 218 |
+
style={{
|
| 219 |
+
flex: 1,
|
| 220 |
+
textAlign: "center",
|
| 221 |
+
fontSize: 15,
|
| 222 |
+
fontWeight: 500,
|
| 223 |
+
color: i === days.length - 1 ? c.ink : c.faint,
|
| 224 |
+
}}
|
| 225 |
+
>
|
| 226 |
+
{i === 0 || i === launchIndex || i === days.length - 1 ? d.date : ""}
|
| 227 |
+
</div>
|
| 228 |
+
))}
|
| 229 |
+
</div>
|
| 230 |
+
|
| 231 |
+
{/* footer */}
|
| 232 |
+
<div
|
| 233 |
+
style={{
|
| 234 |
+
display: "flex",
|
| 235 |
+
justifyContent: "space-between",
|
| 236 |
+
alignItems: "center",
|
| 237 |
+
marginTop: 28,
|
| 238 |
+
paddingTop: 22,
|
| 239 |
+
borderTop: `1px solid ${c.line}`,
|
| 240 |
+
fontSize: 20,
|
| 241 |
+
fontWeight: 500,
|
| 242 |
+
}}
|
| 243 |
+
>
|
| 244 |
+
<div style={{ display: "inline-flex", alignItems: "center", gap: 9, color: c.muted }}>
|
| 245 |
+
<span style={{ width: 13, height: 13, background: c.accent, display: "inline-block" }} />
|
| 246 |
+
GLM-5.2
|
| 247 |
+
</div>
|
| 248 |
+
<div style={{ color: c.ink }}>opencode.ai/data</div>
|
| 249 |
+
</div>
|
| 250 |
+
</div>
|
| 251 |
+
</div>
|
| 252 |
+
</AbsoluteFill>
|
| 253 |
+
)
|
| 254 |
+
}
|
artifacts/glm52-rise-video/sst-env.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is auto-generated by SST. Do not edit. */
|
| 2 |
+
/* tslint:disable */
|
| 3 |
+
/* eslint-disable */
|
| 4 |
+
/* deno-fmt-ignore-file */
|
| 5 |
+
/* biome-ignore-all lint: auto-generated */
|
| 6 |
+
|
| 7 |
+
/// <reference path="../../sst-env.d.ts" />
|
| 8 |
+
|
| 9 |
+
import "sst"
|
| 10 |
+
export {}
|
github/script/publish
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
|
| 3 |
+
# Get the latest Git tag
|
| 4 |
+
latest_tag=$(git tag --sort=committerdate | grep -E '^github-v[0-9]+\.[0-9]+\.[0-9]+$' | tail -1)
|
| 5 |
+
if [ -z "$latest_tag" ]; then
|
| 6 |
+
echo "No tags found"
|
| 7 |
+
exit 1
|
| 8 |
+
fi
|
| 9 |
+
echo "Latest tag: $latest_tag"
|
| 10 |
+
|
| 11 |
+
# Update latest tag
|
| 12 |
+
git tag -d latest
|
| 13 |
+
git push origin :refs/tags/latest
|
| 14 |
+
git tag -a latest $latest_tag -m "Update latest to $latest_tag"
|
| 15 |
+
git push origin latest
|
github/script/release
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
|
| 3 |
+
# Parse command line arguments
|
| 4 |
+
minor=false
|
| 5 |
+
while [ "$#" -gt 0 ]; do
|
| 6 |
+
case "$1" in
|
| 7 |
+
--minor) minor=true; shift 1;;
|
| 8 |
+
*) echo "Unknown parameter: $1"; exit 1;;
|
| 9 |
+
esac
|
| 10 |
+
done
|
| 11 |
+
|
| 12 |
+
# Get the latest Git tag
|
| 13 |
+
git fetch --force --tags
|
| 14 |
+
latest_tag=$(git tag --sort=committerdate | grep -E '^github-v[0-9]+\.[0-9]+\.[0-9]+$' | tail -1)
|
| 15 |
+
if [ -z "$latest_tag" ]; then
|
| 16 |
+
echo "No tags found"
|
| 17 |
+
exit 1
|
| 18 |
+
fi
|
| 19 |
+
|
| 20 |
+
echo "Latest tag: $latest_tag"
|
| 21 |
+
|
| 22 |
+
# Split the tag into major, minor, and patch numbers
|
| 23 |
+
IFS='.' read -ra VERSION <<< "$latest_tag"
|
| 24 |
+
|
| 25 |
+
if [ "$minor" = true ]; then
|
| 26 |
+
# Increment the minor version and reset patch to 0
|
| 27 |
+
minor_number=${VERSION[1]}
|
| 28 |
+
let "minor_number++"
|
| 29 |
+
new_version="${VERSION[0]}.$minor_number.0"
|
| 30 |
+
else
|
| 31 |
+
# Increment the patch version
|
| 32 |
+
patch_number=${VERSION[2]}
|
| 33 |
+
let "patch_number++"
|
| 34 |
+
new_version="${VERSION[0]}.${VERSION[1]}.$patch_number"
|
| 35 |
+
fi
|
| 36 |
+
|
| 37 |
+
echo "New version: $new_version"
|
| 38 |
+
|
| 39 |
+
# Tag
|
| 40 |
+
git tag $new_version
|
| 41 |
+
git push --tags
|