Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
b1a25ec
feat(editor): wire the warehouse plugin and fix the dev script on Win…
ovurrsl Jul 26, 2026
83517b3
fix: node id prefixes split at the wrong underscore, breaking plugin …
ovurrsl Jul 26, 2026
3c625ea
fix: surface upload failures, survive insecure contexts, stop mid-dra…
ovurrsl Jul 29, 2026
7c13873
chore: pin plugin-warehouse at the per-level-clears catalogue
ovurrsl Jul 29, 2026
4384898
chore: pin plugin-warehouse at the telescopic conveyor
ovurrsl Jul 30, 2026
35bc745
chore: pin plugin-warehouse at the shared-collider perf fix
ovurrsl Jul 30, 2026
03bd8eb
chore: pin plugin-warehouse at instancing + slice 8
ovurrsl Jul 30, 2026
9b4dbcb
chore: pin plugin-warehouse at the ghost-stock target fix
ovurrsl Jul 30, 2026
1a1742e
chore: pin plugin-warehouse at the audit fixes
ovurrsl Jul 30, 2026
ae1fa9f
Merge branch 'pascalorg:main' into main
ctudanismanlik Jul 30, 2026
7dd1838
chore: pin plugin-warehouse at telescopic sensor+platform (20bffb3)
ovurrsl Jul 30, 2026
ba8ec6d
chore: pin plugin-warehouse at telescopic nose-equipment panel toggle…
ovurrsl Jul 30, 2026
936d4d4
chore: pin plugin-warehouse at lamp-in-hazard-stripe (e959a11)
ovurrsl Jul 30, 2026
6d55d4c
Merge branch 'pascalorg:main' into main
ovurrsl Jul 30, 2026
9a1360c
chore: pin plugin-warehouse at mezzanine Phase 1 (2c54178)
ovurrsl Jul 30, 2026
18fb842
chore: sync lockfile and generated types after full monorepo rebuild
ovurrsl Jul 30, 2026
677b315
chore: pin plugin-warehouse at mezzanine Phases 2-4 (fe05208)
ovurrsl Jul 30, 2026
94a872e
chore: pin plugin-warehouse at live racking (ee29014)
ovurrsl Jul 30, 2026
5df7ddb
chore: pin plugin-warehouse at the mezzanine deck-slab release
ovurrsl Jul 30, 2026
dc3aff0
chore: pin plugin-warehouse at the live-racking Phase 2 release
ovurrsl Jul 30, 2026
4c0245d
chore: pin plugin-warehouse at the live-racking SKU release
ovurrsl Jul 30, 2026
7d8153b
deploy: self-contained standalone build for Hostinger Node.js hosting
claude Jul 30, 2026
1c2d91d
chore: pin plugin-warehouse at the mezzanine control-honesty release
ovurrsl Jul 30, 2026
4800db4
deploy: run the full standalone assembly from the root build script
claude Jul 30, 2026
50bde99
deploy: reinstall with bun before building on the host
claude Jul 30, 2026
e120fb7
chore: pin plugin-warehouse at the mezzanine staircase release
ovurrsl Jul 30, 2026
22d31a2
deploy: hoisted install layout and hand off to Next's generated server
claude Jul 30, 2026
1caedd6
chore: pin plugin-warehouse at the mezzanine catalogue release
ovurrsl Jul 30, 2026
dd80b01
deploy: restore execute bits after bun install on the host
claude Jul 30, 2026
2a98222
chore: pin plugin-warehouse at the mezzanine tier-targeting fix
ovurrsl Jul 30, 2026
0ea9cea
chore: pin plugin-warehouse at the mezzanine custom-outline release
ovurrsl Jul 30, 2026
5b8660a
chore: pin plugin-warehouse at the free stair placement release
ovurrsl Jul 30, 2026
665f69d
chore: pin plugin-warehouse at the mezzanine outline drawing release
ovurrsl Jul 30, 2026
3f48f18
feat(mcp): add a MySQL scene store and let browsers reach the scene API
claude Jul 30, 2026
4368ca6
fix: render scene pages from the store, and index MySQL for older ser…
claude Jul 30, 2026
0152eae
chore: pin plugin-warehouse at the polygon railing release
ovurrsl Jul 30, 2026
c9df99c
feat(mcp): log which scene backend was selected
claude Jul 30, 2026
46b8217
Merge fork main: newer plugin-warehouse pins
claude Jul 30, 2026
0103c19
ci: rebuild and publish the deployment bundle
claude Jul 30, 2026
bf3798a
fix: let the live scene stream through, retry a failed pool, add disc…
claude Jul 30, 2026
0b92e68
chore: pin plugin-warehouse at the outline editor release
ovurrsl Jul 31, 2026
3a145fe
chore: pin plugin-warehouse at the mezzanine 2D completion release
ovurrsl Jul 31, 2026
cebff47
chore: pin plugin-warehouse at the 2D tier selector + GL2000 release
ovurrsl Jul 31, 2026
e721d18
chore: pin plugin-warehouse at the panel reachability release
ovurrsl Jul 31, 2026
12788f1
feat: require MySQL in production and persist projects in the database
claude Jul 31, 2026
9a7aca8
chore: rebrand the user-visible and console surface to digitaltwin
claude Jul 31, 2026
d11efe5
chore: pin plugin-warehouse at the slot pinning release
ovurrsl Jul 31, 2026
d2d7d24
feat(auth): email+password sign-in on MySQL, scenes owned by users
claude Jul 31, 2026
69292ca
feat(admin): admin panel for users and scene ownership
claude Jul 31, 2026
01d5667
config: name the deployment variables DIGITALTWIN_*
claude Jul 31, 2026
20761bd
ci: fetch the ssh-pinned plugins over https
claude Jul 31, 2026
aa7a1f4
Revert "ci: fetch the ssh-pinned plugins over https"
claude Jul 31, 2026
7799aef
Merge remote-tracking branch 'origin/main' into claude/incele-nq4heb
claude Jul 31, 2026
7753b87
deps: pin plugin-warehouse the same way plugin-trees is pinned
claude Jul 31, 2026
f53550a
fix: say why the database is unreachable at startup
claude Jul 31, 2026
e6daedc
feat: read configuration from a file when the panel loses it
claude Jul 31, 2026
db00848
feat: import IFC building models as scenes
claude Jul 31, 2026
02da3fb
feat(mcp): serve MCP per user, granted from the admin panel
claude Jul 31, 2026
46cc03e
Revert "feat(mcp): serve MCP per user, granted from the admin panel"
claude Jul 31, 2026
d4147f9
ci: authorize the now-private plugin repository with an ssh key
claude Jul 31, 2026
2f18cf6
fix: accept plugin nodes at the scene API boundary
claude Jul 31, 2026
f8d77a5
panel: vendor ovurrsl/panel sources (not yet wired)
claude Jul 31, 2026
04f57f9
feat: the console becomes the front door and owns identity
claude Jul 31, 2026
57168c9
ci: retrigger after the plugin deploy key
claude Jul 31, 2026
b10061e
chore: pin plugin-warehouse at the merged rack level table
ovurrsl Jul 31, 2026
7a15d52
ci: the plugin repo is public again — drop the key, relock on a runner
claude Jul 31, 2026
9a50c9d
ci: fire relock from a push to this branch
claude Jul 31, 2026
70f6ff4
chore: regenerate bun.lock on a real runner
github-actions[bot] Jul 31, 2026
678d0a1
ci: run checks against the regenerated lockfile
claude Jul 31, 2026
704b2cb
feat: self-migrating boot for the console takeover
claude Jul 31, 2026
7edec2e
Merge remote-tracking branch 'origin/main' into claude/incele-nq4heb
claude Jul 31, 2026
16ff497
ci: relock for the new plugin pin (9e1b525b)
claude Jul 31, 2026
60be574
chore: regenerate bun.lock on a real runner
github-actions[bot] Jul 31, 2026
aaef7c9
ci: run checks against the relocked pin
claude Jul 31, 2026
365cf8f
fix: satisfy the editor's stricter lint and type gates for the vendor…
claude Jul 31, 2026
22e2339
ci: relock for the new @types devDependencies
claude Jul 31, 2026
8334842
chore: regenerate bun.lock on a real runner
github-actions[bot] Jul 31, 2026
7db9c80
ci: run checks against the relocked dependencies
claude Jul 31, 2026
90d7164
fix: declare mysql2 in the editor app, which imports it directly
claude Jul 31, 2026
8ac837b
chore: regenerate bun.lock on a real runner
github-actions[bot] Jul 31, 2026
59b0509
ci: run checks against the relocked dependencies
claude Jul 31, 2026
7413fea
feat: give the console's transactional mail a designed HTML part
claude Jul 31, 2026
a5baa0b
fix: ship the console's migrations and native-alias step with the bundle
claude Jul 31, 2026
7096d12
feat: push console changes back to its own repository
claude Aug 1, 2026
bc85e93
fix: remove the account menu overlaid on the editor toolbar
claude Aug 1, 2026
3f73158
fix: Home links point at the editor, not the console
claude Aug 1, 2026
78130a6
feat: the editor lives at the root URL, and access follows the consol…
claude Aug 1, 2026
e184c09
feat: scene administration moves into the console
claude Aug 1, 2026
cca8b0c
feat: console sites become real 3D scenes
claude Aug 1, 2026
4f1d1d5
feat: scenes created in the editor appear on Sites & Projects
claude Aug 1, 2026
4af6eee
feat: publishing is an admin decision, and the guide is public
claude Aug 1, 2026
1544a92
feat: a documentation site, a public changelog, and project management
claude Aug 1, 2026
5b62591
feat: the real brand mark, a documentation shell, and a theme that fo…
claude Aug 1, 2026
a43b223
feat: system theme by default, a call to action that knows who is rea…
claude Aug 1, 2026
aae442f
fix: the sign-in notice reports real activity, not a fabricated line
claude Aug 1, 2026
d417a8f
fix: the browser tab shows the brand mark
claude Aug 1, 2026
d73bf6a
One theme button that starts on the system, and a language switch on …
claude Aug 1, 2026
5c87db5
The scenes library moves into the editor, and every message the syste…
claude Aug 1, 2026
fb20d27
The console stops answering to accounts that may only look
claude Aug 1, 2026
8e7cb2a
Mail stops being a card that resembles the console and becomes the co…
claude Aug 1, 2026
8fd5c67
Scenes stops wearing the zone tool's icon, and Settings learns who is…
claude Aug 1, 2026
f7d406b
Expert floor-plan mode gains the way back out
claude Aug 1, 2026
79e12ab
Every changelog entry says which component it belongs to, and carries…
claude Aug 1, 2026
eb5cb7b
Say why an account cannot be deleted instead of reporting a server error
claude Aug 1, 2026
4a9895f
The test message reports whether it was actually delivered
claude Aug 1, 2026
a01ab0b
deploy: the bundle stops calling itself Pascal
claude Aug 1, 2026
fac88a2
Deleting a user stops being blocked by what they once did
claude Aug 1, 2026
392b3f4
An invitation that is not delivered stops reporting success
claude Aug 1, 2026
3726b24
Close an unauthenticated read of every scene, and five findings from …
claude Aug 1, 2026
6c482d1
A converter carries scenes out of the legacy desktop build
claude Aug 3, 2026
91e9cb0
Migrated nodes are parsed to their schema's shape before they are saved
claude Aug 3, 2026
9aeb9d2
The warehouse plugin follows its own main again
claude Aug 3, 2026
056db12
The published bundle says 2.13.0
claude Aug 3, 2026
f3a1077
Write down how a plugin release reaches the site
claude Aug 3, 2026
4353d2c
Pin the plugin's v0.1.1 release
claude Aug 4, 2026
74acee6
chore: regenerate bun.lock on a real runner
github-actions[bot] Aug 4, 2026
49e2781
Pin the plugin's v0.1.2 release
claude Aug 4, 2026
eb4485d
ci: relock for the new plugin pin (49b2f16)
claude Aug 4, 2026
14c6183
chore: regenerate bun.lock on a real runner
github-actions[bot] Aug 4, 2026
3840a0c
The published bundle says 2.15.0
claude Aug 4, 2026
261afe6
chore: pin plugin-warehouse v0.1.4
claude Aug 5, 2026
6e84ee4
chore: pin plugin-warehouse v0.1.4 — canlıya çıkabilen dala (#3)
ovurrsl Aug 5, 2026
ee5bf46
fix(auth): enforce the lockout on the second factor, not just report it
claude Aug 5, 2026
4f0589e
fix(sync-panel): stop pushing the two tabs the console cannot serve
claude Aug 5, 2026
3b5f52a
fix(sync-panel): hold back three more files the console cannot compile
claude Aug 5, 2026
bad4115
feat(sync-panel): pull the console back, from the same tables
claude Aug 5, 2026
e44fd3b
feat(ci): pull the console automatically, and stop pushing it back
claude Aug 5, 2026
23d72ad
feat(ci): move the plugin pin automatically, and hand off to the deploy
claude Aug 5, 2026
871d012
feat(ci): make `integration` the branch every workflow agrees on, and…
claude Aug 5, 2026
6232999
Merge pull request #4 from ovurrsl/claude/mfa-lockout-and-panel-sync
ovurrsl Aug 5, 2026
257bb93
chore: pin plugin-warehouse b53d9de
github-actions[bot] Aug 5, 2026
bc621b6
fix(ci): stop the hourly console pull failing on every quiet run
claude Aug 5, 2026
75c5a89
fix(ci): open the upstream pull request whenever integration is behind
claude Aug 5, 2026
f82ce6f
docs: describe the automation as it now works
claude Aug 5, 2026
ec6f460
docs: tell an agent it is in the fork before it reads upstream's rules
claude Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions .github/deploy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# digitaltwin

Pascal Editor, compiled and ready to run on Hostinger's Node.js hosting. Built
from [pascalorg/editor](https://github.com/pascalorg/editor) at commit
`08e2279`, plus the MySQL scene store from
[ovurrsl/editor](https://github.com/ovurrsl/editor).

The application sits at the root of this repository — there is one
`package.json` and one entry point, so the host cannot pick the wrong
directory. It follows the stock sequence: `npm install` fetches the runtime
packages, `npm run build` has nothing to compile and exits cleanly, and
`server.js` starts the app. `PORT` and `HOSTNAME` are read from the
environment.

## hPanel settings

Everything is the default except the output directory.

| Field | Value |
|---|---|
| Repository | `ovurrsl/digitaltwin` |
| Branch | `main` |
| Framework preset | Other |
| Root directory | `./` |
| Node.js version | 22.x |
| Package manager | npm |
| Build command | `npm run build` |
| Output directory | `./` |
| Entry file | `server.js` |

## Environment variables

| Name | Value |
|---|---|
| `DIGITALTWIN_MYSQL_HOST` | `localhost` |
| `DIGITALTWIN_MYSQL_USER` | database user |
| `DIGITALTWIN_MYSQL_PASSWORD` | database password |
| `DIGITALTWIN_MYSQL_DATABASE` | database name |
| `DIGITALTWIN_MYSQL_PORT` | `3306` (optional) |

or, as a single value:

| Name | Value |
|---|---|
| `DIGITALTWIN_MYSQL_URL` | `mysql://user:password@localhost:3306/database` |

In `DIGITALTWIN_MYSQL_URL`, percent-encode any of `@ : / ? # [ ] %` that appear
in the password — `@` becomes `%40`, `#` becomes `%23`. The separate fields
need no encoding, which is why they are listed first.

Optional:

| Name | Value |
|---|---|
| `DIGITALTWIN_ADMIN_EMAIL` | the address that gets the admin role on sign-up |

**MySQL is required.** Without a database configured the server refuses to
start — check the runtime log for the reason. Tables are created on first
connection. `/api/health` reports the selected backend
(`"backend":"mysql"`) and whether the database answers (`"db":"ok"`), so one
curl verifies a deploy. Setting `DIGITALTWIN_ALLOW_SQLITE=1` overrides the
requirement, writing scenes to a local file the host discards on every
release — never set it here.

Every variable is also read under its older `PASCAL_` name, so an existing
deployment keeps working until it is renamed.

## When the panel forgets its variables

Some panels drop their environment variables on redeploy, which takes the
database down with them. The same settings can come from a file instead. A real
environment variable always wins, so the panel stays in charge wherever it is
configured.

Two locations are read, in this order:

| Path | Survives a redeploy? |
|---|---|
| `.env` next to `server.js` | only until the next release replaces this tree |
| `~/.digitaltwin.env` | yes — it sits outside the deployed directory |

Prefer the second. Create it once with the host's file manager:

DIGITALTWIN_MYSQL_HOST=127.0.0.1
DIGITALTWIN_MYSQL_PORT=3306
DIGITALTWIN_MYSQL_USER=your_user
DIGITALTWIN_MYSQL_PASSWORD=your_password
DIGITALTWIN_MYSQL_DATABASE=your_database

`KEY=value` per line; `#` starts a comment; surrounding quotes are stripped.
Values are never expanded, so a `$` in a password is a literal `$`.

The boot log names the files it read and how many settings each supplied — the
values are credentials and are never logged. `DIGITALTWIN_ENV_FILE` points at a
different path when neither default suits.

A `.env` committed here is carried across by the publish workflow, which
otherwise replaces this tree wholesale. It is still a credential in git
history — the home-directory file avoids that.

## Layout

server.js entry point, generated by the standalone build
package.json runtime dependencies and the build/start scripts
.next/ the compiled application
public/ static assets: models, textures, icons, sounds

## Regenerating

Build the source with `output: 'standalone'` in `apps/editor/next.config.ts`.
From the resulting `apps/editor/.next/standalone` tree, lift `apps/editor/.next`,
`apps/editor/public` and `apps/editor/server.js` to the top level and drop the
rest — the vendored `node_modules` is replaced by the dependency list in
`package.json`, and the app's original manifest cannot be reused because it
names workspace packages that are not published to npm. Two things the
standalone build leaves out: copy `apps/editor/public` and
`apps/editor/.next/static` into the tree before lifting, and add `mysql2` to
the dependency list by hand — the store imports it dynamically, so file
tracing does not see it.
27 changes: 27 additions & 0 deletions .github/deploy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "digitaltwin",
"version": "2.15.0",
"private": true,
"type": "module",
"description": "DigitalTwin, compiled and ready to run. Nothing is built at deploy time.",
"engines": {
"node": ">=20.9"
},
"scripts": {
"build": "node setup-native.mjs",
"start": "node server.js"
},
"dependencies": {
"@node-rs/argon2": "2.0.2",
"@opentelemetry/api": "1.9.1",
"mysql2": "3.23.2",
"next": "16.2.9",
"nodemailer": "9.0.3",
"otpauth": "9.5.1",
"qrcode": "1.5.4",
"react": "19.2.7",
"react-dom": "19.2.7",
"sharp": "0.34.5",
"ulid": "3.0.2"
}
}
22 changes: 22 additions & 0 deletions .github/deploy/setup-native.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Turbopack requires an externalized native package under a build-specific
// hashed alias (e.g. "@node-rs/argon2-4d195bca84303183") but emits no package
// by that name. Recreate the alias as a symlink to the real install. Runs as
// the bundle's "build" step, i.e. right after npm install on the host.
import { readdirSync, readFileSync, mkdirSync, symlinkSync, existsSync, rmSync } from 'node:fs'
import { join } from 'node:path'

const chunks = join('.next', 'server', 'chunks')
const found = new Set()
for (const f of readdirSync(chunks)) {
if (!f.endsWith('.js')) continue
const m = readFileSync(join(chunks, f), 'utf8').matchAll(/@node-rs\/argon2-[a-f0-9]{16}/g)
for (const hit of m) found.add(hit[0])
}
for (const alias of found) {
const target = join('node_modules', alias)
if (existsSync(target)) rmSync(target, { recursive: true })
mkdirSync(join('node_modules', '@node-rs'), { recursive: true })
symlinkSync('argon2', target)
console.log(`[setup-native] ${alias} -> @node-rs/argon2`)
}
if (found.size === 0) console.log('[setup-native] no hashed native aliases found')
104 changes: 104 additions & 0 deletions .github/workflows/bump-plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Bump warehouse plugin

# The warehouse plugin is a git dependency pinned to an exact sha, and it
# compiles into the app — so a plugin release reaches the site only when this
# repository moves the pin AND the bundle is rebuilt. Doing that by hand is
# what left a set of freeze fixes sitting unreleased: the plugin's main had
# moved on for weeks while the pin, and therefore production, had not.
#
# Needs no secret. The plugin repository is public, so reading its head and
# resolving the dependency both work with nothing configured.
on:
workflow_dispatch:
# ovurrsl/plugin-warehouse can fire this on a push to main; the schedule is
# what keeps the pin current until it does.
repository_dispatch:
types: [plugin-updated]
schedule:
- cron: '42 * * * *'

concurrency:
group: bump-plugin
cancel-in-progress: true

permissions:
contents: write
# To hand off to the deploy — see the last step.
actions: write

env:
PLUGIN_REPO: https://github.com/ovurrsl/plugin-warehouse.git

jobs:
bump:
runs-on: ubuntu-latest
steps:
# A scheduled run starts on the default branch, so the branch to update
# is named rather than inherited. Set the INTEGRATION_BRANCH repository
# variable to move it; the fallback is the branch it is today.
- uses: actions/checkout@v4
with:
ref: ${{ vars.INTEGRATION_BRANCH || 'integration' }}

- name: Compare the pin with the plugin's head
id: compare
run: |
head=$(git ls-remote "$PLUGIN_REPO" refs/heads/main | cut -f1)
pinned=$(grep -o 'plugin-warehouse\.git#[0-9a-f]\{40\}' apps/editor/package.json | cut -d'#' -f2)
echo "head=$head" >> "$GITHUB_OUTPUT"
echo "pinned=$pinned" >> "$GITHUB_OUTPUT"
if [ -z "$head" ] || [ -z "$pinned" ]; then
echo "could not read one of them (head='$head' pinned='$pinned')" >&2
exit 1
fi
if [ "$head" = "$pinned" ]; then
echo 'the pin is current'
echo 'changed=false' >> "$GITHUB_OUTPUT"
else
echo "pin $pinned -> $head"
echo 'changed=true' >> "$GITHUB_OUTPUT"
fi

- uses: oven-sh/setup-bun@v2
if: steps.compare.outputs.changed == 'true'
with:
bun-version: 1.3.0

# The lockfile records the sha512 of the resolved tarball, so it is
# regenerated by a real install rather than edited — the same reason
# `relock.yml` exists.
- name: Move the pin and relock
if: steps.compare.outputs.changed == 'true'
run: |
sed -i "s|plugin-warehouse\.git#${{ steps.compare.outputs.pinned }}|plugin-warehouse.git#${{ steps.compare.outputs.head }}|" \
apps/editor/package.json
bun install

# The gate. A plugin release that does not compile against this editor
# must not reach the branch the bundle is built from — which is exactly
# the failure a version range would hide and an exact pin makes visible.
- name: Type check
if: steps.compare.outputs.changed == 'true'
run: bun run check-types

- name: Commit to the integration branch
if: steps.compare.outputs.changed == 'true'
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git add apps/editor/package.json bun.lock
git commit -m "$(printf 'chore: pin plugin-warehouse %s\n\nWas %s.' \
"$(echo '${{ steps.compare.outputs.head }}' | cut -c1-7)" \
"$(echo '${{ steps.compare.outputs.pinned }}' | cut -c1-7)")"
git push

# Handed off explicitly: a push made with GITHUB_TOKEN starts no workflow
# runs, so without this the pin moves and the site never rebuilds.
- name: Build and publish
if: steps.compare.outputs.changed == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
gh workflow run deploy-bundle.yml \
--repo "$GITHUB_REPOSITORY" \
--ref "${{ vars.INTEGRATION_BRANCH || 'integration' }}"
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [main]
branches: [integration]
pull_request:
branches: [main]
branches: [integration]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -18,6 +18,7 @@ jobs:

- uses: oven-sh/setup-bun@v2


- name: Install dependencies
run: bun install --frozen-lockfile

Expand Down
Loading