Compare commits
21 commits
main
...
ci/frozen-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f7cc2d5b0 | ||
|
|
ca0d2fdd3a | ||
|
|
819ed20e98 | ||
|
|
9c0372d132 | ||
|
|
dc2292a5a0 | ||
|
|
35a30f1960 | ||
|
|
1f397f45df | ||
|
|
220ae1116f | ||
|
|
888347d551 |
||
|
|
c244a9d0f5 |
||
|
|
7238504b47 | ||
|
|
032eb880d9 | ||
|
|
b743e1b4ff | ||
|
|
d43b0e3029 | ||
|
|
cf39fb6957 | ||
|
|
fd5f9be57d | ||
|
|
d1124c52a9 | ||
|
|
75a8129e3b | ||
|
|
2f1d2deb5c | ||
|
|
883f26a2a4 | ||
|
|
53c0d8c477 |
17 changed files with 4111 additions and 171 deletions
31
.github/workflows/release-desktop.yml
vendored
31
.github/workflows/release-desktop.yml
vendored
|
|
@ -361,14 +361,19 @@ jobs:
|
|||
with:
|
||||
node-version: 24
|
||||
|
||||
# Pre-install lockfile structural audit. Has to fire BEFORE
|
||||
# `npm ci` so any tarball's `prepare` / `postinstall` cannot run
|
||||
# ahead of the scan. Pure-Python read-only; safe everywhere.
|
||||
- name: Lockfile supply-chain audit (pre-install scan)
|
||||
shell: bash
|
||||
run: python3 scripts/lockfile_supply_chain_audit.py
|
||||
|
||||
- name: Install pinned Tauri CLI
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
# required for `vite build`. The pre-install lockfile structural
|
||||
# audit (lockfile_supply_chain_audit.py) is the practical defence
|
||||
# against the npm postinstall-dropper class -- it fires BEFORE any
|
||||
# tarball runs, on the injection pattern itself rather than an
|
||||
# advisory-DB lookup.
|
||||
run: npm install --save-dev --prefix studio @tauri-apps/cli@2.10.1 --no-fund --no-audit
|
||||
# `npm ci` resolves @tauri-apps/cli and its 11 platform-specific
|
||||
# optional native binaries from studio/package-lock.json --
|
||||
# transitive versions are fully pinned, integrity hashes are
|
||||
# verified, and the install is reproducible across re-runs.
|
||||
run: npm ci --prefix studio --no-fund --no-audit
|
||||
|
||||
- name: Verify pinned Tauri CLI
|
||||
shell: bash
|
||||
|
|
@ -443,13 +448,11 @@ jobs:
|
|||
|
||||
- name: Install frontend dependencies
|
||||
working-directory: studio/frontend
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
# required for `vite build`. The pre-install lockfile structural
|
||||
# audit (lockfile_supply_chain_audit.py) is the practical defence
|
||||
# against the npm postinstall-dropper class -- it fires BEFORE any
|
||||
# tarball runs, on the injection pattern itself rather than an
|
||||
# advisory-DB lookup.
|
||||
run: npm install --no-fund --no-audit
|
||||
# npm ci: release build installs exactly what the lockfile pins.
|
||||
# Lifecycle scripts (esbuild native-binary postinstall) are required
|
||||
# for vite build; lockfile_supply_chain_audit.py runs pre-install as
|
||||
# the defence against the postinstall-dropper class.
|
||||
run: npm ci --no-fund --no-audit
|
||||
|
||||
# ── Rust ──
|
||||
- name: Install Rust stable
|
||||
|
|
|
|||
157
.github/workflows/security-audit.yml
vendored
157
.github/workflows/security-audit.yml
vendored
|
|
@ -53,6 +53,10 @@ on:
|
|||
- 'studio/backend/requirements/**'
|
||||
- 'studio/frontend/package.json'
|
||||
- 'studio/frontend/package-lock.json'
|
||||
- 'studio/backend/core/data_recipe/oxc-validator/package.json'
|
||||
- 'studio/backend/core/data_recipe/oxc-validator/package-lock.json'
|
||||
- 'studio/package.json'
|
||||
- 'studio/package-lock.json'
|
||||
- 'studio/src-tauri/Cargo.toml'
|
||||
- 'studio/src-tauri/Cargo.lock'
|
||||
- 'pyproject.toml'
|
||||
|
|
@ -278,7 +282,7 @@ jobs:
|
|||
{
|
||||
echo "## Lockfile supply-chain audit"
|
||||
echo
|
||||
echo "Scanned: studio/frontend/package-lock.json + studio/src-tauri/Cargo.lock"
|
||||
echo "Scanned: studio/frontend/package-lock.json + studio/backend/core/data_recipe/oxc-validator/package-lock.json + studio/package-lock.json + studio/src-tauri/Cargo.lock"
|
||||
echo
|
||||
echo "No structural anomalies or known IOC strings."
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
|
@ -307,6 +311,39 @@ jobs:
|
|||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: npm audit (oxc-validator runtime)
|
||||
# Same audit surface, separate npm project (oxc-parser, oxlint).
|
||||
continue-on-error: true
|
||||
working-directory: studio/backend/core/data_recipe/oxc-validator
|
||||
run: |
|
||||
set +e
|
||||
npm audit --audit-level=high | tee "$GITHUB_WORKSPACE/logs-npm-audit-oxc.txt"
|
||||
npm audit --json > "$GITHUB_WORKSPACE/logs-npm-audit-oxc.json" || true
|
||||
{
|
||||
echo "## npm audit (oxc-validator)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$GITHUB_WORKSPACE/logs-npm-audit-oxc.txt"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: npm audit (Studio Tauri CLI holder)
|
||||
# Same audit surface, third npm project (@tauri-apps/cli for the
|
||||
# signed desktop release; lockfile lives at studio/package-lock.json).
|
||||
continue-on-error: true
|
||||
working-directory: studio
|
||||
run: |
|
||||
set +e
|
||||
npm audit --audit-level=high | tee "$GITHUB_WORKSPACE/logs-npm-audit-studio.txt"
|
||||
npm audit --json > "$GITHUB_WORKSPACE/logs-npm-audit-studio.json" || true
|
||||
{
|
||||
echo "## npm audit (Studio Tauri CLI holder)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$GITHUB_WORKSPACE/logs-npm-audit-studio.txt"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# cargo: Studio Tauri shell
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
|
|
@ -348,6 +385,8 @@ jobs:
|
|||
/tmp/osv-scanner --version
|
||||
/tmp/osv-scanner scan source \
|
||||
--lockfile=studio/frontend/package-lock.json \
|
||||
--lockfile=studio/backend/core/data_recipe/oxc-validator/package-lock.json \
|
||||
--lockfile=studio/package-lock.json \
|
||||
--lockfile=studio/src-tauri/Cargo.lock \
|
||||
--lockfile=requirements.txt:audit-reqs/unsloth-deps.txt \
|
||||
--lockfile=requirements.txt:audit-reqs/studio.txt \
|
||||
|
|
@ -911,26 +950,71 @@ jobs:
|
|||
# full log and surface it in the step summary either way. It
|
||||
# never runs `npm install`, never executes anything from a
|
||||
# downloaded tarball, and only fetches from registry.npmjs.org.
|
||||
# Initially non-blocking so the baseline can settle; drop
|
||||
# continue-on-error once the baseline is clean for a week.
|
||||
# This step is blocking: the final exit code is the worst rc
|
||||
# across all three npm projects (no continue-on-error).
|
||||
#
|
||||
# Three separate npm projects share this scan surface; scan each.
|
||||
# Capture exit codes via PIPESTATUS so a HIGH/CRITICAL on one
|
||||
# lockfile does not skip the next scan (all reports are most
|
||||
# useful exactly when one already failed).
|
||||
run: |
|
||||
set -o pipefail
|
||||
set +e
|
||||
|
||||
LOG=logs-scan-npm.txt
|
||||
python3 scripts/scan_npm_packages.py 2>&1 | tee "$LOG"
|
||||
frontend_rc=${PIPESTATUS[0]}
|
||||
|
||||
LOG2=logs-scan-npm-oxc.txt
|
||||
python3 scripts/scan_npm_packages.py \
|
||||
--lockfile studio/backend/core/data_recipe/oxc-validator/package-lock.json \
|
||||
2>&1 | tee "$LOG2"
|
||||
oxc_rc=${PIPESTATUS[0]}
|
||||
|
||||
LOG3=logs-scan-npm-studio.txt
|
||||
python3 scripts/scan_npm_packages.py \
|
||||
--lockfile studio/package-lock.json \
|
||||
2>&1 | tee "$LOG3"
|
||||
studio_rc=${PIPESTATUS[0]}
|
||||
|
||||
{
|
||||
echo "## scan_npm_packages"
|
||||
echo "## scan_npm_packages (Studio frontend)"
|
||||
echo
|
||||
echo '### Findings (tail)'
|
||||
echo '```'
|
||||
tail -300 "$LOG"
|
||||
echo '```'
|
||||
echo
|
||||
echo "## scan_npm_packages (oxc-validator)"
|
||||
echo
|
||||
echo '### Findings (tail)'
|
||||
echo '```'
|
||||
tail -300 "$LOG2"
|
||||
echo '```'
|
||||
echo
|
||||
echo "## scan_npm_packages (Studio Tauri CLI holder)"
|
||||
echo
|
||||
echo '### Findings (tail)'
|
||||
echo '```'
|
||||
tail -300 "$LOG3"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
if [ "$frontend_rc" -ne 0 ]; then
|
||||
exit "$frontend_rc"
|
||||
fi
|
||||
if [ "$oxc_rc" -ne 0 ]; then
|
||||
exit "$oxc_rc"
|
||||
fi
|
||||
exit "$studio_rc"
|
||||
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
if: always()
|
||||
with:
|
||||
name: scan-npm-packages-log
|
||||
path: logs-scan-npm.txt
|
||||
path: |
|
||||
logs-scan-npm.txt
|
||||
logs-scan-npm-oxc.txt
|
||||
logs-scan-npm-studio.txt
|
||||
retention-days: 30
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
|
|
@ -1077,7 +1161,7 @@ jobs:
|
|||
working-directory: studio/frontend
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: npm audit signatures (informational)
|
||||
- name: npm audit signatures (Studio frontend, informational)
|
||||
# Surfaces unsigned / mis-signed packages from the npm
|
||||
# transparency log. continue-on-error during baseline-build
|
||||
# phase; promote to hard gate once the lockfile is fully
|
||||
|
|
@ -1086,10 +1170,48 @@ jobs:
|
|||
continue-on-error: true
|
||||
run: |
|
||||
set -o pipefail
|
||||
LOG=logs-audit-signatures.txt
|
||||
LOG="$GITHUB_WORKSPACE/logs-audit-signatures.txt"
|
||||
npm audit signatures 2>&1 | tee "$LOG"
|
||||
{
|
||||
echo "## npm audit signatures"
|
||||
echo "## npm audit signatures (Studio frontend)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$LOG"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Install oxc-validator deps (--ignore-scripts)
|
||||
working-directory: studio/backend/core/data_recipe/oxc-validator
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: npm audit signatures (oxc-validator, informational)
|
||||
working-directory: studio/backend/core/data_recipe/oxc-validator
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set -o pipefail
|
||||
LOG="$GITHUB_WORKSPACE/logs-audit-signatures-oxc.txt"
|
||||
npm audit signatures 2>&1 | tee "$LOG"
|
||||
{
|
||||
echo "## npm audit signatures (oxc-validator)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$LOG"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Install Studio Tauri CLI holder deps (--ignore-scripts)
|
||||
working-directory: studio
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: npm audit signatures (Studio Tauri CLI holder, informational)
|
||||
working-directory: studio
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set -o pipefail
|
||||
LOG="$GITHUB_WORKSPACE/logs-audit-signatures-studio.txt"
|
||||
npm audit signatures 2>&1 | tee "$LOG"
|
||||
{
|
||||
echo "## npm audit signatures (Studio Tauri CLI holder)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$LOG"
|
||||
|
|
@ -1103,6 +1225,12 @@ jobs:
|
|||
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
||||
git show "$BASE_SHA:studio/frontend/package-lock.json" \
|
||||
> /tmp/base-package-lock.json
|
||||
# OXC lockfile may not exist on the base ref (newly added).
|
||||
git show "$BASE_SHA:studio/backend/core/data_recipe/oxc-validator/package-lock.json" \
|
||||
> /tmp/base-oxc-package-lock.json 2>/dev/null || echo '{}' > /tmp/base-oxc-package-lock.json
|
||||
# Tauri CLI holder lockfile may not exist on the base ref (newly added).
|
||||
git show "$BASE_SHA:studio/package-lock.json" \
|
||||
> /tmp/base-studio-package-lock.json 2>/dev/null || echo '{}' > /tmp/base-studio-package-lock.json
|
||||
|
||||
- name: Diff for newly-added install-script deps
|
||||
if: github.event_name == 'pull_request'
|
||||
|
|
@ -1110,6 +1238,12 @@ jobs:
|
|||
python3 scripts/check_new_install_scripts.py \
|
||||
--base /tmp/base-package-lock.json \
|
||||
--head studio/frontend/package-lock.json
|
||||
python3 scripts/check_new_install_scripts.py \
|
||||
--base /tmp/base-oxc-package-lock.json \
|
||||
--head studio/backend/core/data_recipe/oxc-validator/package-lock.json
|
||||
python3 scripts/check_new_install_scripts.py \
|
||||
--base /tmp/base-studio-package-lock.json \
|
||||
--head studio/package-lock.json
|
||||
|
||||
- name: Skip install-script diff (non-PR trigger)
|
||||
if: github.event_name != 'pull_request'
|
||||
|
|
@ -1121,6 +1255,9 @@ jobs:
|
|||
if: always()
|
||||
with:
|
||||
name: npm-audit-signatures-log
|
||||
path: studio/frontend/logs-audit-signatures.txt
|
||||
path: |
|
||||
logs-audit-signatures.txt
|
||||
logs-audit-signatures-oxc.txt
|
||||
logs-audit-signatures-studio.txt
|
||||
if-no-files-found: ignore
|
||||
retention-days: 30
|
||||
|
|
|
|||
27
.github/workflows/studio-tauri-smoke.yml
vendored
27
.github/workflows/studio-tauri-smoke.yml
vendored
|
|
@ -60,14 +60,15 @@ jobs:
|
|||
with:
|
||||
workspaces: studio/src-tauri -> target
|
||||
|
||||
# Must run BEFORE any `npm ci` so a tarball's prepare/postinstall
|
||||
# cannot execute ahead of the structural scan.
|
||||
- name: Lockfile supply-chain audit (pre-install scan)
|
||||
run: python3 scripts/lockfile_supply_chain_audit.py
|
||||
|
||||
- name: Install pinned Tauri CLI (matches release-desktop.yml)
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
# required for `vite build`. The pre-install lockfile structural
|
||||
# audit (lockfile_supply_chain_audit.py) is the practical defence
|
||||
# against the npm postinstall-dropper class -- it fires BEFORE any
|
||||
# tarball runs, on the injection pattern itself rather than an
|
||||
# advisory-DB lookup.
|
||||
run: npm install --save-dev --prefix studio @tauri-apps/cli@2.10.1 --no-fund --no-audit
|
||||
# `npm ci` resolves @tauri-apps/cli from studio/package-lock.json
|
||||
# (transitives fully pinned, integrity hashes verified).
|
||||
run: npm ci --prefix studio --no-fund --no-audit
|
||||
|
||||
- name: Verify pinned Tauri CLI version
|
||||
run: |
|
||||
|
|
@ -75,17 +76,11 @@ jobs:
|
|||
echo "$out"
|
||||
[ "$out" = "tauri-cli 2.10.1" ] || { echo "::error::expected tauri-cli 2.10.1, got $out"; exit 1; }
|
||||
|
||||
- name: Lockfile supply-chain audit (pre-install scan)
|
||||
run: python3 scripts/lockfile_supply_chain_audit.py
|
||||
|
||||
- name: Frontend build (npm ci, vite)
|
||||
working-directory: studio/frontend
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
# required for `vite build`. The pre-install lockfile structural
|
||||
# audit (lockfile_supply_chain_audit.py) is the practical defence
|
||||
# against the npm postinstall-dropper class -- it fires BEFORE any
|
||||
# tarball runs, on the injection pattern itself rather than an
|
||||
# advisory-DB lookup.
|
||||
# Vite build needs esbuild's native-binary postinstall; the
|
||||
# pre-install lockfile audit above is what gates that path
|
||||
# against the npm postinstall-dropper class.
|
||||
run: |
|
||||
npm ci --no-fund --no-audit
|
||||
npm run build
|
||||
|
|
|
|||
1
.github/workflows/wheel-smoke.yml
vendored
1
.github/workflows/wheel-smoke.yml
vendored
|
|
@ -87,6 +87,7 @@ jobs:
|
|||
n = z.namelist()
|
||||
checks = {
|
||||
"lockfile shipped": any(s.endswith("studio/frontend/package-lock.json") for s in n),
|
||||
"oxc lockfile shipped": any(s.endswith("oxc-validator/package-lock.json") for s in n),
|
||||
"frontend dist shipped": any(s.endswith("studio/frontend/dist/index.html") for s in n),
|
||||
"no node_modules": not any("studio/frontend/node_modules/" in s for s in n),
|
||||
"no bun.lock": not any(s.endswith("studio/frontend/bun.lock") for s in n),
|
||||
|
|
|
|||
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -229,5 +229,15 @@ log.txt
|
|||
setup_leo.sh
|
||||
server.pid
|
||||
*.log
|
||||
# Ignore stray lockfiles; real npm projects opt back in below (npm ci needs them).
|
||||
package-lock.json
|
||||
!studio/frontend/package-lock.json
|
||||
!studio/backend/core/data_recipe/oxc-validator/package-lock.json
|
||||
!studio/package-lock.json
|
||||
# Bun lockfiles: same opt-in policy as package-lock.json above.
|
||||
# bun install --frozen-lockfile needs these committed for the same surfaces.
|
||||
bun.lock
|
||||
!studio/frontend/bun.lock
|
||||
!studio/backend/core/data_recipe/oxc-validator/bun.lock
|
||||
!studio/bun.lock
|
||||
llama.cpp/
|
||||
|
|
|
|||
35
build.sh
35
build.sh
|
|
@ -33,19 +33,36 @@ _restore_gitignores() {
|
|||
}
|
||||
trap _restore_gitignores EXIT
|
||||
|
||||
# Use bun for install if available (faster), fall back to npm.
|
||||
# Frontend install: Bun --frozen-lockfile first (faster) if a
|
||||
# committed bun.lock is present, npm ci as the always-available
|
||||
# fallback. Both run lockfile-strict so the install is byte-
|
||||
# reproducible from whichever lockfile the chosen package manager
|
||||
# understands. Build always runs through Node -- avoids bun runtime
|
||||
# quirks on some platforms. This is build.sh (release wheel build,
|
||||
# typically CI); we do NOT auto-install bun here -- the calling
|
||||
# environment should provide it explicitly. The cache-corruption
|
||||
# recovery ladder mirrors studio/setup.sh.
|
||||
_install_ok=false
|
||||
if command -v bun &>/dev/null; then
|
||||
if bun install; then
|
||||
_install_ok=true
|
||||
else
|
||||
echo "⚠ bun install failed, falling back to npm"
|
||||
if [ -f bun.lock ] && command -v bun &>/dev/null; then
|
||||
_attempts=0
|
||||
while [ "$_attempts" -lt 2 ] && [ "$_install_ok" != "true" ]; do
|
||||
_attempts=$((_attempts + 1))
|
||||
if bun install --frozen-lockfile --no-progress \
|
||||
&& { [ -x node_modules/.bin/tsc ] || [ -f node_modules/.bin/tsc.exe ]; } \
|
||||
&& { [ -x node_modules/.bin/vite ] || [ -f node_modules/.bin/vite.exe ]; }; then
|
||||
_install_ok=true
|
||||
break
|
||||
fi
|
||||
echo "⚠ bun --frozen-lockfile incomplete (try $_attempts); clearing cache + retrying"
|
||||
rm -rf node_modules
|
||||
fi
|
||||
bun pm cache rm >/dev/null 2>&1 || true
|
||||
done
|
||||
fi
|
||||
if [ "$_install_ok" != "true" ]; then
|
||||
if ! npm install; then
|
||||
echo "❌ ERROR: package install failed" >&2
|
||||
echo "→ falling back to npm ci"
|
||||
rm -rf node_modules
|
||||
if ! npm ci --no-fund --no-audit; then
|
||||
echo "❌ ERROR: npm ci failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ EXPECTED_NOISE_FILES = {
|
|||
"studio/frontend/package-lock.json",
|
||||
"studio/backend/core/data_recipe/oxc-validator/package.json",
|
||||
"studio/backend/core/data_recipe/oxc-validator/package-lock.json",
|
||||
"studio/package.json",
|
||||
"studio/package-lock.json",
|
||||
}
|
||||
|
||||
# Only quoted-string occurrences in these file types can be module specifiers.
|
||||
|
|
|
|||
|
|
@ -397,9 +397,35 @@ class Finding:
|
|||
def audit_npm_lockfile(path: Path) -> list[Finding]:
|
||||
findings: list[Finding] = []
|
||||
if not path.exists():
|
||||
# A missing requested lockfile is a config error, not a clean
|
||||
# audit; surface it so a deleted default cannot pass silently.
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "missing-lockfile",
|
||||
detail = (
|
||||
"expected lockfile not found; refusing to silently "
|
||||
"report a clean audit for a path that was not scanned"
|
||||
),
|
||||
)
|
||||
)
|
||||
return findings
|
||||
|
||||
raw = path.read_text(encoding = "utf-8")
|
||||
try:
|
||||
raw = path.read_text(encoding = "utf-8")
|
||||
except OSError as exc:
|
||||
# Permission denied, is-a-directory, broken-pipe etc. -- surface
|
||||
# as a finding instead of crashing CI with a raw traceback.
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "unreadable-lockfile",
|
||||
detail = f"could not read file: {exc}",
|
||||
)
|
||||
)
|
||||
return findings
|
||||
try:
|
||||
lock = json.loads(raw)
|
||||
except json.JSONDecodeError as exc:
|
||||
|
|
@ -550,12 +576,201 @@ def _first_line_containing(text: str, needle: str) -> int | None:
|
|||
_PACKAGE_HEADER = re.compile(r"^\[\[package\]\]\s*$")
|
||||
|
||||
|
||||
# Bun's text lockfile (bun.lock, Bun >= 1.2) is JSONC -- valid JSON with
|
||||
# trailing commas allowed. Strip them before json.loads.
|
||||
_BUN_LOCK_TRAILING_COMMA_RE = re.compile(r",(\s*[}\]])")
|
||||
|
||||
|
||||
def _parse_bun_lockfile_text(raw: str) -> dict:
|
||||
"""Parse bun.lock JSONC text by stripping trailing commas."""
|
||||
cleaned = _BUN_LOCK_TRAILING_COMMA_RE.sub(r"\1", raw)
|
||||
return json.loads(cleaned)
|
||||
|
||||
|
||||
def audit_bun_lockfile(path: Path) -> list[Finding]:
|
||||
"""Pre-install audit for Bun's text lockfile (bun.lock, version 1).
|
||||
|
||||
Each package entry is a JSON array shaped like:
|
||||
"pkg-name": [
|
||||
"pkg-name@version",
|
||||
"<registry-url-or-empty>",
|
||||
{"optionalDependencies": ..., "bin": ..., "os": ..., ...},
|
||||
"sha512-<base64>" # integrity, registry-resolved only
|
||||
]
|
||||
git/file/tarball-resolved entries carry the source URL in element 1
|
||||
and lack the sha512 tail. We flag any non-default-registry source
|
||||
and any registry entry without a sha512 tail.
|
||||
"""
|
||||
findings: list[Finding] = []
|
||||
if not path.exists():
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "missing-lockfile",
|
||||
detail = (
|
||||
"expected lockfile not found; refusing to silently "
|
||||
"report a clean audit for a path that was not scanned"
|
||||
),
|
||||
)
|
||||
)
|
||||
return findings
|
||||
|
||||
try:
|
||||
raw = path.read_text(encoding = "utf-8")
|
||||
except OSError as exc:
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "unreadable-lockfile",
|
||||
detail = f"could not read file: {exc}",
|
||||
)
|
||||
)
|
||||
return findings
|
||||
|
||||
try:
|
||||
lock = _parse_bun_lockfile_text(raw)
|
||||
except json.JSONDecodeError as exc:
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "malformed-lockfile",
|
||||
detail = f"could not parse bun.lock as JSONC: {exc}",
|
||||
)
|
||||
)
|
||||
return findings
|
||||
|
||||
lockfile_version = lock.get("lockfileVersion")
|
||||
if lockfile_version != 1:
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "unsupported-lockfile-version",
|
||||
detail = f"only bun lockfileVersion 1 audited; got {lockfile_version}",
|
||||
)
|
||||
)
|
||||
|
||||
packages = lock.get("packages") or {}
|
||||
for pkg_name, entry in packages.items():
|
||||
if not isinstance(entry, list) or len(entry) < 2:
|
||||
continue
|
||||
|
||||
# entry[0] is "name@version"; entry[1] is the source URL when
|
||||
# non-default-registry (e.g. "git+https://..." or "file:./..."),
|
||||
# or "" when resolved against the default npm registry.
|
||||
nv = entry[0] if isinstance(entry[0], str) else ""
|
||||
# version is everything after the LAST '@' (handles scoped names
|
||||
# like "@scope/name@1.2.3").
|
||||
version = nv.rsplit("@", 1)[-1] if "@" in nv else ""
|
||||
|
||||
source = entry[1] if len(entry) > 1 and isinstance(entry[1], str) else ""
|
||||
|
||||
# 1. Source origin: empty string means default registry. Anything
|
||||
# else (git+, file:, http://github.com/, tarball URL) is flagged
|
||||
# the same way audit_npm_lockfile flags non-registry resolved URLs.
|
||||
if source and not any(
|
||||
source.startswith(p) for p in NPM_REGISTRY_PREFIXES_ALLOWED
|
||||
):
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = pkg_name,
|
||||
kind = "non-registry-resolved-url",
|
||||
detail = (
|
||||
f"source={source!r}; only {NPM_REGISTRY_PREFIX} "
|
||||
"is permitted. Direct GitHub / git / file references "
|
||||
"are the Shai-Hulud injection vector."
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
# 2. Integrity hash: registry-resolved entries carry a sha-prefixed
|
||||
# tail element. Missing tail on a registry entry is a finding.
|
||||
has_sha_tail = isinstance(entry[-1], str) and (
|
||||
entry[-1].startswith("sha512-")
|
||||
or entry[-1].startswith("sha256-")
|
||||
or entry[-1].startswith("sha1-")
|
||||
)
|
||||
if not source and not has_sha_tail:
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = pkg_name,
|
||||
kind = "missing-integrity-hash",
|
||||
detail = (
|
||||
"no sha-prefixed integrity tail in bun.lock entry; "
|
||||
"bun cannot verify the tarball SHA against the "
|
||||
"registry-published hash"
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
# 3. Blocked-malicious-version list.
|
||||
blocked = BLOCKED_NPM_VERSIONS.get(pkg_name, set())
|
||||
if version and version in blocked:
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = pkg_name,
|
||||
kind = "blocked-known-malicious",
|
||||
detail = (
|
||||
f"{pkg_name}@{version} is on the BLOCKED_NPM_VERSIONS list"
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
# 4. IOC string scan against the raw file body (mirrors audit_npm_lockfile).
|
||||
for ioc in NPM_IOC_STRINGS:
|
||||
if ioc in raw:
|
||||
line_no = _first_line_containing(raw, ioc)
|
||||
findings.append(
|
||||
Finding(
|
||||
path = f"{path}:{line_no}" if line_no else str(path),
|
||||
package = "<ioc-match>",
|
||||
kind = "known-ioc-string",
|
||||
detail = (
|
||||
f"matched known IOC substring {ioc!r}; this is "
|
||||
"a public indicator of a recent supply-chain "
|
||||
"compromise. Refuse to install."
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
return findings
|
||||
|
||||
|
||||
def audit_cargo_lockfile(path: Path) -> list[Finding]:
|
||||
findings: list[Finding] = []
|
||||
if not path.exists():
|
||||
# See audit_npm_lockfile: missing lockfile is a finding.
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "missing-lockfile",
|
||||
detail = (
|
||||
"expected lockfile not found; refusing to silently "
|
||||
"report a clean audit for a path that was not scanned"
|
||||
),
|
||||
)
|
||||
)
|
||||
return findings
|
||||
|
||||
raw = path.read_text(encoding = "utf-8")
|
||||
try:
|
||||
raw = path.read_text(encoding = "utf-8")
|
||||
except OSError as exc:
|
||||
findings.append(
|
||||
Finding(
|
||||
path = str(path),
|
||||
package = "<root>",
|
||||
kind = "unreadable-lockfile",
|
||||
detail = f"could not read file: {exc}",
|
||||
)
|
||||
)
|
||||
return findings
|
||||
try:
|
||||
import tomllib # type: ignore[import-not-found]
|
||||
except ImportError:
|
||||
|
|
@ -652,7 +867,16 @@ def audit_cargo_lockfile(path: Path) -> list[Finding]:
|
|||
# ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
DEFAULT_NPM_LOCKFILES = ("studio/frontend/package-lock.json",)
|
||||
DEFAULT_NPM_LOCKFILES = (
|
||||
"studio/frontend/package-lock.json",
|
||||
"studio/backend/core/data_recipe/oxc-validator/package-lock.json",
|
||||
"studio/package-lock.json",
|
||||
)
|
||||
DEFAULT_BUN_LOCKFILES = (
|
||||
"studio/frontend/bun.lock",
|
||||
"studio/backend/core/data_recipe/oxc-validator/bun.lock",
|
||||
"studio/bun.lock",
|
||||
)
|
||||
DEFAULT_CARGO_LOCKFILES = ("studio/src-tauri/Cargo.lock",)
|
||||
|
||||
|
||||
|
|
@ -671,7 +895,20 @@ def main(argv: list[str] | None = None) -> int:
|
|||
default = None,
|
||||
help = (
|
||||
"Path to a package-lock.json (repeatable). "
|
||||
"Default: studio/frontend/package-lock.json."
|
||||
"Default: studio/frontend/package-lock.json, "
|
||||
"studio/backend/core/data_recipe/oxc-validator/package-lock.json, "
|
||||
"and studio/package-lock.json (Tauri CLI for desktop release)."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--bun-lockfile",
|
||||
action = "append",
|
||||
default = None,
|
||||
help = (
|
||||
"Path to a bun.lock (repeatable). "
|
||||
"Default: studio/frontend/bun.lock, "
|
||||
"studio/backend/core/data_recipe/oxc-validator/bun.lock, "
|
||||
"and studio/bun.lock (Tauri CLI for desktop release)."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
|
|
@ -715,13 +952,29 @@ def main(argv: list[str] | None = None) -> int:
|
|||
return 0
|
||||
|
||||
root = Path(args.root).resolve()
|
||||
npm_paths = [root / p for p in (args.npm_lockfile or DEFAULT_NPM_LOCKFILES)]
|
||||
cargo_paths = [root / p for p in (args.cargo_lockfile or DEFAULT_CARGO_LOCKFILES)]
|
||||
# Explicit --npm-lockfile/--bun-lockfile/--cargo-lockfile scopes the
|
||||
# scan to those paths; defaults apply only to the no-args CI invocation.
|
||||
_user_explicit = (
|
||||
args.npm_lockfile is not None
|
||||
or args.bun_lockfile is not None
|
||||
or args.cargo_lockfile is not None
|
||||
)
|
||||
if _user_explicit:
|
||||
npm_paths = [root / p for p in (args.npm_lockfile or ())]
|
||||
bun_paths = [root / p for p in (args.bun_lockfile or ())]
|
||||
cargo_paths = [root / p for p in (args.cargo_lockfile or ())]
|
||||
else:
|
||||
npm_paths = [root / p for p in DEFAULT_NPM_LOCKFILES]
|
||||
bun_paths = [root / p for p in DEFAULT_BUN_LOCKFILES]
|
||||
cargo_paths = [root / p for p in DEFAULT_CARGO_LOCKFILES]
|
||||
|
||||
all_findings: list[Finding] = []
|
||||
for p in npm_paths:
|
||||
print(f"[lockfile-audit] npm: {p}", flush = True)
|
||||
all_findings.extend(audit_npm_lockfile(p))
|
||||
for p in bun_paths:
|
||||
print(f"[lockfile-audit] bun: {p}", flush = True)
|
||||
all_findings.extend(audit_bun_lockfile(p))
|
||||
for p in cargo_paths:
|
||||
print(f"[lockfile-audit] cargo: {p}", flush = True)
|
||||
all_findings.extend(audit_cargo_lockfile(p))
|
||||
|
|
@ -729,7 +982,8 @@ def main(argv: list[str] | None = None) -> int:
|
|||
if not all_findings:
|
||||
print(
|
||||
f"[lockfile-audit] OK: 0 findings across "
|
||||
f"{len(npm_paths)} npm + {len(cargo_paths)} cargo lockfile(s)",
|
||||
f"{len(npm_paths)} npm + {len(bun_paths)} bun + "
|
||||
f"{len(cargo_paths)} cargo lockfile(s)",
|
||||
flush = True,
|
||||
)
|
||||
return 0
|
||||
|
|
|
|||
110
studio/backend/core/data_recipe/oxc-validator/bun.lock
Normal file
110
studio/backend/core/data_recipe/oxc-validator/bun.lock
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "unsloth-oxc-validator-runtime",
|
||||
"dependencies": {
|
||||
"oxc-parser": "^0.123.0",
|
||||
"oxlint": "^1.51.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="],
|
||||
|
||||
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
|
||||
|
||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="],
|
||||
|
||||
"@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.123.0", "", { "os": "android", "cpu": "arm" }, "sha512-EHQ58z+6DbZWokMOKg5AB1KuwrXVgfbBLuuLFfzdc7bI5A4igvdvjKMhUv1VBV+0FABiUCOjNKUmMF7ugprwbQ=="],
|
||||
|
||||
"@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.123.0", "", { "os": "android", "cpu": "arm64" }, "sha512-BK1E0zqNoHf38nTHjnGZ+olKHSKNHh65pChjY06yhaWYP8X7yNDqhQDA4neMPRqnPBgpN4/OW1oSMrdJgDi2aw=="],
|
||||
|
||||
"@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.123.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dkMPbtTbqU+cm+k4YGOBs4zAuq3Xu+wqjbGQvLAuVO7qHhNY4p5LBNudOmOoi0jxS8h1W6Jmlzv8MAKGpK+iDg=="],
|
||||
|
||||
"@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.123.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-85pic0rCd59DGdM69jI9xE/Snb2KtrfiU48QigjJXjzxUOenGvH4SAFIjFpO/2ZnI3Kz50D8pht4jKN3t2022Q=="],
|
||||
|
||||
"@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.123.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mjEiW6z7JtaiHMK/8aJic1lfjkKpzFwK2XFNmm187BFbtDamjGVuKNr2TEyrFEYJyZc217wokR1wrYeZGBQo4Q=="],
|
||||
|
||||
"@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.123.0", "", { "os": "linux", "cpu": "arm" }, "sha512-mYxigPtGt6SZfhNZBIJfuDM92cLo8XUW08WuKxzHvcmWu6xndLqwLp99Vg4uHke1AXicQEHU3Wri2X9bHF0Vlw=="],
|
||||
|
||||
"@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.123.0", "", { "os": "linux", "cpu": "arm" }, "sha512-ttWirDC9eUBn0R4Tzz3aeDaLrx9drPdNiLJ8MXeDBFxd6cwLfTIC27qjsdfGpn942tkVIZY3sjWAnvbwDDjX7g=="],
|
||||
|
||||
"@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.123.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-apAHyoMNRYT+2G98Y14caZmsr5LD9PsWpGI7nXmSwK26LGiQneCU6HvHQ+d+AX+RJ5TTWZtEb2RD7OLqAC0cYQ=="],
|
||||
|
||||
"@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.123.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-3r99Qa4egjO/iXUBxTlN6Ddt1YkLifG6olzvj8gkoKEK2U/MOW7mQfXRyBmuoMgmZ7O4vk41gO3d21c6VcN3yQ=="],
|
||||
|
||||
"@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.123.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Hr/Z24kUE4pjJs346g80WDwjyJGrxiw6hExJuOiME/76ZFz68y5L11UzprRkW9FN4HxBB7tLZ/fytczV2fEsiA=="],
|
||||
|
||||
"@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.123.0", "", { "os": "linux", "cpu": "none" }, "sha512-sxjbhs+8WXeuoLnZ2rBmQ96gPdq3SCmz24reIltsKLUt1EDMgdaQsr7RqwBphw3QAImkMtlPQfAWDWwZyo0xDg=="],
|
||||
|
||||
"@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.123.0", "", { "os": "linux", "cpu": "none" }, "sha512-d6xHHhqldA/W+VC7v8uHs24zM69Ad3HnHQ45h+uuBhCsbZx3d0E0wL2K3uJ5mYKTR6UPMFk9VMXcHWwvg1PRZQ=="],
|
||||
|
||||
"@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.123.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-+di9A5wJQlv0VodyhADjJ2rC4geyHY+uhJDl3TFjMgYhhlgLZchi9uHD5mfiUEDWHt1x7/eU2u1ge3LLazZmFw=="],
|
||||
|
||||
"@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.123.0", "", { "os": "linux", "cpu": "x64" }, "sha512-sh7pw2g/u6LE1TaRRQsV9Kv9+1y+CywaaNwWWP+3bnEPk/L692oTG0hmEviUlawI8v3OGC+AhbjtAD+HXWQAkg=="],
|
||||
|
||||
"@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.123.0", "", { "os": "linux", "cpu": "x64" }, "sha512-S+LoD8PiJ639JwIqK1knIeqAyYkeCbLHtAgfapszKX0yVCaYP+aer8dJxL25de9qcDjvYWVrYCkuDZzHmOl2Xw=="],
|
||||
|
||||
"@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.123.0", "", { "os": "none", "cpu": "arm64" }, "sha512-/65vryK11q1I+k+7ukDlwZOxUFCLYsoZBZPGZHyet5bIP5e3D8mV3uCuvpWZ9Hoe6vUZFw/nAfCrX59MeuJPgw=="],
|
||||
|
||||
"@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.123.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.2" }, "cpu": "none" }, "sha512-y4OsMGQiAbZzj2Rq0LEfvhR48rQDvbvqsl/dPdn4tdf+z3H79nZuR+lQ/+KUGjD30vpVGem138sBWHFj9UR+Vg=="],
|
||||
|
||||
"@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.123.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-9lBqI6AXAkjYavkdpizNU3Q51uoVYfp9FJPx19hnCEdPku1jSgzSnvgmCvhCue0GziIvIvIdWgZ41wXQ3EOoBw=="],
|
||||
|
||||
"@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.123.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-zJbqBHwSUB7CyvAONy9ewGtQwcQj+ylOhYGETvUPp3KIYx7lolj4Gayof7iA22SU5eMSjO5COL0c8wYhmn9agA=="],
|
||||
|
||||
"@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.123.0", "", { "os": "win32", "cpu": "x64" }, "sha512-q7RZvglQvGo3RX5ljtcGSabu2B2c0oDU/6xC3sBMhsV5KRo0PvyxLdordbEN31NTfuZu4Sgl86C76cAURZIHWA=="],
|
||||
|
||||
"@oxc-project/types": ["@oxc-project/types@0.123.0", "", {}, "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew=="],
|
||||
|
||||
"@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.64.0", "", { "os": "android", "cpu": "arm" }, "sha512-2r6Nq3XXGLHEXKkSj8JtmJ6N4gDw431DPFOg0ZoJHlNjnG6HVMm/ksQ10m0HJ8WBvwgMe1L50UHPaYZutCRPCw=="],
|
||||
|
||||
"@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.64.0", "", { "os": "android", "cpu": "arm64" }, "sha512-ePJMpePgg7fBv+L/hVx1xXRU5/5gd5m0obLA6hPEfLXF3GjpR8idIDbY1dhQYhyz1ms2wdTccSboo6KEd2Oxtg=="],
|
||||
|
||||
"@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.64.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-U4DMLQd10gJLuoSTLSGbfv3bGjTlUNsScm9Dgb8wwBqmCzidf1pE1pXV4doGNxqwH3KtVng1AGTINA0NvkGLvQ=="],
|
||||
|
||||
"@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.64.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-GoRIL48QWm4/TAvjN8pB1nAG+1/uqc9EdnWT9zqHeb6wsmjZtywj8VRe5aGW47Fdb64YtLOsdLqVxOvQuz98Wg=="],
|
||||
|
||||
"@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.64.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5dFkv4tkg7PxJJGS9/OjrJwjhuHczrd3OQOkRE0wHcLM+ncUnULtzEPWjqGOxTXxZnLWcB91bGiIznx89TVXyQ=="],
|
||||
|
||||
"@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.64.0", "", { "os": "linux", "cpu": "arm" }, "sha512-jsBqMLl/uOL5+Kq/+BtK9FrmiNGUbx8SiyZXv+WlUxA45KuwcLu9BfiSIL3I3DBDgWM3yZizDITnTK9BcqNBQg=="],
|
||||
|
||||
"@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.64.0", "", { "os": "linux", "cpu": "arm" }, "sha512-1lrj8At/Uuc9GhjrVFBQo0NEjfBrTkzpmtHIGAhNnIXqn1CAyGL+qrztUsXb2GIluJrpl9Q7qRLJOb/NqydacQ=="],
|
||||
|
||||
"@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.64.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-HpSQbubwh03mMhAdy2BYtad/fsY8vDFHDAb6bUwuCYg2VD3xCQgn6ArKcO0oZyLCheacKTv4PrF3Mfu5hgoE2g=="],
|
||||
|
||||
"@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.64.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-00QQ0h0Y7u0G69BgiH3+ky2aaq/QvkDL6DYok8htIuJHxybiux5aQ8jwmg8qIk9wha6UagUP2BAwAzbemcJbpg=="],
|
||||
|
||||
"@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.64.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-2GaimTV6EMW+s5HS0An3oGbQme3BgHswvfVdGk3EB57Xe9+/gyT+Qd7lNVzb3rtir52vbIPzXfaYArzs5b5zcw=="],
|
||||
|
||||
"@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.64.0", "", { "os": "linux", "cpu": "none" }, "sha512-H46AtFb9wypjoVwGdlxrm0DsD809NGmtiK9HiyPKTxkSte2YjhC4S+00rOIrwCaxcyPiGid3Y3OMXp5KMAkGZw=="],
|
||||
|
||||
"@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.64.0", "", { "os": "linux", "cpu": "none" }, "sha512-HEgsidjjvvyzdg82icYkuFCf7REDV7B9JFwbIMbVwrKLBY0MrXX+bku3POn/hduZ2yW91IyVDUMq0Bf02KwXQw=="],
|
||||
|
||||
"@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.64.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Axvm8qryotmKN00P5w4JapaSjvP2LOSbdbBJiX+2SuHd3QzhW7TUc8skqgw+ahQZ5DmzEYeHCqauvW8f32Ns6Q=="],
|
||||
|
||||
"@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.64.0", "", { "os": "linux", "cpu": "x64" }, "sha512-cR60vSd7+m+KRZ3GQGfDxWwahW5RMXg0qlGvAluZr0fTUYvw0H9N9AXAF/M/PMqgytyqvVNmBAkJG9l7U30Y1g=="],
|
||||
|
||||
"@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.64.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2u/aPZ9pEg7HnvZPDsHxUGNnrpr4qaHi+mCgLgpt+LYRzPrS4Px4wPfkIdRdr2GvKnaYyt+XSlto0Vm5sbStTg=="],
|
||||
|
||||
"@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.64.0", "", { "os": "none", "cpu": "arm64" }, "sha512-kfhkGfCdoXLSxEkrhDlJrvBYajGmq+ma4EMc53dsOWTq+rIBOlI0vTBmpZNnM5oH2LY/K/w1HAK+UQEgjgpVUg=="],
|
||||
|
||||
"@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.64.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-r/cNKBFieONoVu2bb1KkVouq9W+edDUgHumXJGphCRRj+U0xaD4nanrw8ZOqo0IsutPkEM4vCcGBpak6x5aXMg=="],
|
||||
|
||||
"@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.64.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-tUw0xUUwEFVZbpJoeCblkv8SJA4Xz3CdXCJbAnBsiNLyxDrk2tLcxEAS6M73Q7hHHDg3OtwI8vZVK3t5RJt4Gw=="],
|
||||
|
||||
"@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.64.0", "", { "os": "win32", "cpu": "x64" }, "sha512-9CBR+LO0JVST87fNTzzNxS5I29jIUO5gxT9i9+M3SDHHALElj9sY1Prf12tad3vIRC6OD7Ehtvvh+sn13vSwHw=="],
|
||||
|
||||
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="],
|
||||
|
||||
"oxc-parser": ["oxc-parser@0.123.0", "", { "dependencies": { "@oxc-project/types": "^0.123.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.123.0", "@oxc-parser/binding-android-arm64": "0.123.0", "@oxc-parser/binding-darwin-arm64": "0.123.0", "@oxc-parser/binding-darwin-x64": "0.123.0", "@oxc-parser/binding-freebsd-x64": "0.123.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.123.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.123.0", "@oxc-parser/binding-linux-arm64-gnu": "0.123.0", "@oxc-parser/binding-linux-arm64-musl": "0.123.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.123.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.123.0", "@oxc-parser/binding-linux-riscv64-musl": "0.123.0", "@oxc-parser/binding-linux-s390x-gnu": "0.123.0", "@oxc-parser/binding-linux-x64-gnu": "0.123.0", "@oxc-parser/binding-linux-x64-musl": "0.123.0", "@oxc-parser/binding-openharmony-arm64": "0.123.0", "@oxc-parser/binding-wasm32-wasi": "0.123.0", "@oxc-parser/binding-win32-arm64-msvc": "0.123.0", "@oxc-parser/binding-win32-ia32-msvc": "0.123.0", "@oxc-parser/binding-win32-x64-msvc": "0.123.0" } }, "sha512-F6ak0tFc01ZGbl5KxvLDQ2K005Z086mp3ByCQBDhUjqXLkapGUkMuJSsYixncdEpkLlcRDcruHR71LD339ADUA=="],
|
||||
|
||||
"oxlint": ["oxlint@1.64.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.64.0", "@oxlint/binding-android-arm64": "1.64.0", "@oxlint/binding-darwin-arm64": "1.64.0", "@oxlint/binding-darwin-x64": "1.64.0", "@oxlint/binding-freebsd-x64": "1.64.0", "@oxlint/binding-linux-arm-gnueabihf": "1.64.0", "@oxlint/binding-linux-arm-musleabihf": "1.64.0", "@oxlint/binding-linux-arm64-gnu": "1.64.0", "@oxlint/binding-linux-arm64-musl": "1.64.0", "@oxlint/binding-linux-ppc64-gnu": "1.64.0", "@oxlint/binding-linux-riscv64-gnu": "1.64.0", "@oxlint/binding-linux-riscv64-musl": "1.64.0", "@oxlint/binding-linux-s390x-gnu": "1.64.0", "@oxlint/binding-linux-x64-gnu": "1.64.0", "@oxlint/binding-linux-x64-musl": "1.64.0", "@oxlint/binding-openharmony-arm64": "1.64.0", "@oxlint/binding-win32-arm64-msvc": "1.64.0", "@oxlint/binding-win32-ia32-msvc": "1.64.0", "@oxlint/binding-win32-x64-msvc": "1.64.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1" }, "optionalPeers": ["oxlint-tsgolint"], "bin": "bin/oxlint" }, "sha512-Star3SNpWPeWFPw7kRXIhXUSn6fdiAl25q15CQzH/9WaOtG6e9CWTc25vNZOCr4PE1yEP1GtKJKIKglhj3OmEQ=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
}
|
||||
}
|
||||
799
studio/backend/core/data_recipe/oxc-validator/package-lock.json
generated
Normal file
799
studio/backend/core/data_recipe/oxc-validator/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,799 @@
|
|||
{
|
||||
"name": "unsloth-oxc-validator-runtime",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "unsloth-oxc-validator-runtime",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"oxc-parser": "^0.123.0",
|
||||
"oxlint": "^1.51.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
||||
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
||||
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
|
||||
"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-android-arm-eabi": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.123.0.tgz",
|
||||
"integrity": "sha512-EHQ58z+6DbZWokMOKg5AB1KuwrXVgfbBLuuLFfzdc7bI5A4igvdvjKMhUv1VBV+0FABiUCOjNKUmMF7ugprwbQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-android-arm64": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.123.0.tgz",
|
||||
"integrity": "sha512-BK1E0zqNoHf38nTHjnGZ+olKHSKNHh65pChjY06yhaWYP8X7yNDqhQDA4neMPRqnPBgpN4/OW1oSMrdJgDi2aw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-darwin-arm64": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.123.0.tgz",
|
||||
"integrity": "sha512-dkMPbtTbqU+cm+k4YGOBs4zAuq3Xu+wqjbGQvLAuVO7qHhNY4p5LBNudOmOoi0jxS8h1W6Jmlzv8MAKGpK+iDg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-darwin-x64": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.123.0.tgz",
|
||||
"integrity": "sha512-85pic0rCd59DGdM69jI9xE/Snb2KtrfiU48QigjJXjzxUOenGvH4SAFIjFpO/2ZnI3Kz50D8pht4jKN3t2022Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-freebsd-x64": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.123.0.tgz",
|
||||
"integrity": "sha512-mjEiW6z7JtaiHMK/8aJic1lfjkKpzFwK2XFNmm187BFbtDamjGVuKNr2TEyrFEYJyZc217wokR1wrYeZGBQo4Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-arm-gnueabihf": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.123.0.tgz",
|
||||
"integrity": "sha512-mYxigPtGt6SZfhNZBIJfuDM92cLo8XUW08WuKxzHvcmWu6xndLqwLp99Vg4uHke1AXicQEHU3Wri2X9bHF0Vlw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-arm-musleabihf": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.123.0.tgz",
|
||||
"integrity": "sha512-ttWirDC9eUBn0R4Tzz3aeDaLrx9drPdNiLJ8MXeDBFxd6cwLfTIC27qjsdfGpn942tkVIZY3sjWAnvbwDDjX7g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-arm64-gnu": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.123.0.tgz",
|
||||
"integrity": "sha512-apAHyoMNRYT+2G98Y14caZmsr5LD9PsWpGI7nXmSwK26LGiQneCU6HvHQ+d+AX+RJ5TTWZtEb2RD7OLqAC0cYQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-arm64-musl": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.123.0.tgz",
|
||||
"integrity": "sha512-3r99Qa4egjO/iXUBxTlN6Ddt1YkLifG6olzvj8gkoKEK2U/MOW7mQfXRyBmuoMgmZ7O4vk41gO3d21c6VcN3yQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-ppc64-gnu": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.123.0.tgz",
|
||||
"integrity": "sha512-Hr/Z24kUE4pjJs346g80WDwjyJGrxiw6hExJuOiME/76ZFz68y5L11UzprRkW9FN4HxBB7tLZ/fytczV2fEsiA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-riscv64-gnu": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.123.0.tgz",
|
||||
"integrity": "sha512-sxjbhs+8WXeuoLnZ2rBmQ96gPdq3SCmz24reIltsKLUt1EDMgdaQsr7RqwBphw3QAImkMtlPQfAWDWwZyo0xDg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-riscv64-musl": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.123.0.tgz",
|
||||
"integrity": "sha512-d6xHHhqldA/W+VC7v8uHs24zM69Ad3HnHQ45h+uuBhCsbZx3d0E0wL2K3uJ5mYKTR6UPMFk9VMXcHWwvg1PRZQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-s390x-gnu": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.123.0.tgz",
|
||||
"integrity": "sha512-+di9A5wJQlv0VodyhADjJ2rC4geyHY+uhJDl3TFjMgYhhlgLZchi9uHD5mfiUEDWHt1x7/eU2u1ge3LLazZmFw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-x64-gnu": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.123.0.tgz",
|
||||
"integrity": "sha512-sh7pw2g/u6LE1TaRRQsV9Kv9+1y+CywaaNwWWP+3bnEPk/L692oTG0hmEviUlawI8v3OGC+AhbjtAD+HXWQAkg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-linux-x64-musl": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.123.0.tgz",
|
||||
"integrity": "sha512-S+LoD8PiJ639JwIqK1knIeqAyYkeCbLHtAgfapszKX0yVCaYP+aer8dJxL25de9qcDjvYWVrYCkuDZzHmOl2Xw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-openharmony-arm64": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.123.0.tgz",
|
||||
"integrity": "sha512-/65vryK11q1I+k+7ukDlwZOxUFCLYsoZBZPGZHyet5bIP5e3D8mV3uCuvpWZ9Hoe6vUZFw/nAfCrX59MeuJPgw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-wasm32-wasi": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.123.0.tgz",
|
||||
"integrity": "sha512-y4OsMGQiAbZzj2Rq0LEfvhR48rQDvbvqsl/dPdn4tdf+z3H79nZuR+lQ/+KUGjD30vpVGem138sBWHFj9UR+Vg==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-win32-arm64-msvc": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.123.0.tgz",
|
||||
"integrity": "sha512-9lBqI6AXAkjYavkdpizNU3Q51uoVYfp9FJPx19hnCEdPku1jSgzSnvgmCvhCue0GziIvIvIdWgZ41wXQ3EOoBw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-win32-ia32-msvc": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.123.0.tgz",
|
||||
"integrity": "sha512-zJbqBHwSUB7CyvAONy9ewGtQwcQj+ylOhYGETvUPp3KIYx7lolj4Gayof7iA22SU5eMSjO5COL0c8wYhmn9agA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-parser/binding-win32-x64-msvc": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.123.0.tgz",
|
||||
"integrity": "sha512-q7RZvglQvGo3RX5ljtcGSabu2B2c0oDU/6xC3sBMhsV5KRo0PvyxLdordbEN31NTfuZu4Sgl86C76cAURZIHWA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.123.0.tgz",
|
||||
"integrity": "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Boshen"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-android-arm-eabi": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.64.0.tgz",
|
||||
"integrity": "sha512-2r6Nq3XXGLHEXKkSj8JtmJ6N4gDw431DPFOg0ZoJHlNjnG6HVMm/ksQ10m0HJ8WBvwgMe1L50UHPaYZutCRPCw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-android-arm64": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.64.0.tgz",
|
||||
"integrity": "sha512-ePJMpePgg7fBv+L/hVx1xXRU5/5gd5m0obLA6hPEfLXF3GjpR8idIDbY1dhQYhyz1ms2wdTccSboo6KEd2Oxtg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-darwin-arm64": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.64.0.tgz",
|
||||
"integrity": "sha512-U4DMLQd10gJLuoSTLSGbfv3bGjTlUNsScm9Dgb8wwBqmCzidf1pE1pXV4doGNxqwH3KtVng1AGTINA0NvkGLvQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-darwin-x64": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.64.0.tgz",
|
||||
"integrity": "sha512-GoRIL48QWm4/TAvjN8pB1nAG+1/uqc9EdnWT9zqHeb6wsmjZtywj8VRe5aGW47Fdb64YtLOsdLqVxOvQuz98Wg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-freebsd-x64": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.64.0.tgz",
|
||||
"integrity": "sha512-5dFkv4tkg7PxJJGS9/OjrJwjhuHczrd3OQOkRE0wHcLM+ncUnULtzEPWjqGOxTXxZnLWcB91bGiIznx89TVXyQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-arm-gnueabihf": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.64.0.tgz",
|
||||
"integrity": "sha512-jsBqMLl/uOL5+Kq/+BtK9FrmiNGUbx8SiyZXv+WlUxA45KuwcLu9BfiSIL3I3DBDgWM3yZizDITnTK9BcqNBQg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-arm-musleabihf": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.64.0.tgz",
|
||||
"integrity": "sha512-1lrj8At/Uuc9GhjrVFBQo0NEjfBrTkzpmtHIGAhNnIXqn1CAyGL+qrztUsXb2GIluJrpl9Q7qRLJOb/NqydacQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-arm64-gnu": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.64.0.tgz",
|
||||
"integrity": "sha512-HpSQbubwh03mMhAdy2BYtad/fsY8vDFHDAb6bUwuCYg2VD3xCQgn6ArKcO0oZyLCheacKTv4PrF3Mfu5hgoE2g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-arm64-musl": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.64.0.tgz",
|
||||
"integrity": "sha512-00QQ0h0Y7u0G69BgiH3+ky2aaq/QvkDL6DYok8htIuJHxybiux5aQ8jwmg8qIk9wha6UagUP2BAwAzbemcJbpg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-ppc64-gnu": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.64.0.tgz",
|
||||
"integrity": "sha512-2GaimTV6EMW+s5HS0An3oGbQme3BgHswvfVdGk3EB57Xe9+/gyT+Qd7lNVzb3rtir52vbIPzXfaYArzs5b5zcw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-riscv64-gnu": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.64.0.tgz",
|
||||
"integrity": "sha512-H46AtFb9wypjoVwGdlxrm0DsD809NGmtiK9HiyPKTxkSte2YjhC4S+00rOIrwCaxcyPiGid3Y3OMXp5KMAkGZw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-riscv64-musl": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.64.0.tgz",
|
||||
"integrity": "sha512-HEgsidjjvvyzdg82icYkuFCf7REDV7B9JFwbIMbVwrKLBY0MrXX+bku3POn/hduZ2yW91IyVDUMq0Bf02KwXQw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-s390x-gnu": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.64.0.tgz",
|
||||
"integrity": "sha512-Axvm8qryotmKN00P5w4JapaSjvP2LOSbdbBJiX+2SuHd3QzhW7TUc8skqgw+ahQZ5DmzEYeHCqauvW8f32Ns6Q==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-x64-gnu": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.64.0.tgz",
|
||||
"integrity": "sha512-cR60vSd7+m+KRZ3GQGfDxWwahW5RMXg0qlGvAluZr0fTUYvw0H9N9AXAF/M/PMqgytyqvVNmBAkJG9l7U30Y1g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-linux-x64-musl": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.64.0.tgz",
|
||||
"integrity": "sha512-2u/aPZ9pEg7HnvZPDsHxUGNnrpr4qaHi+mCgLgpt+LYRzPrS4Px4wPfkIdRdr2GvKnaYyt+XSlto0Vm5sbStTg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-openharmony-arm64": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.64.0.tgz",
|
||||
"integrity": "sha512-kfhkGfCdoXLSxEkrhDlJrvBYajGmq+ma4EMc53dsOWTq+rIBOlI0vTBmpZNnM5oH2LY/K/w1HAK+UQEgjgpVUg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-win32-arm64-msvc": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.64.0.tgz",
|
||||
"integrity": "sha512-r/cNKBFieONoVu2bb1KkVouq9W+edDUgHumXJGphCRRj+U0xaD4nanrw8ZOqo0IsutPkEM4vCcGBpak6x5aXMg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-win32-ia32-msvc": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.64.0.tgz",
|
||||
"integrity": "sha512-tUw0xUUwEFVZbpJoeCblkv8SJA4Xz3CdXCJbAnBsiNLyxDrk2tLcxEAS6M73Q7hHHDg3OtwI8vZVK3t5RJt4Gw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxlint/binding-win32-x64-msvc": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.64.0.tgz",
|
||||
"integrity": "sha512-9CBR+LO0JVST87fNTzzNxS5I29jIUO5gxT9i9+M3SDHHALElj9sY1Prf12tad3vIRC6OD7Ehtvvh+sn13vSwHw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
|
||||
"integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/oxc-parser": {
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.123.0.tgz",
|
||||
"integrity": "sha512-F6ak0tFc01ZGbl5KxvLDQ2K005Z086mp3ByCQBDhUjqXLkapGUkMuJSsYixncdEpkLlcRDcruHR71LD339ADUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "^0.123.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Boshen"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@oxc-parser/binding-android-arm-eabi": "0.123.0",
|
||||
"@oxc-parser/binding-android-arm64": "0.123.0",
|
||||
"@oxc-parser/binding-darwin-arm64": "0.123.0",
|
||||
"@oxc-parser/binding-darwin-x64": "0.123.0",
|
||||
"@oxc-parser/binding-freebsd-x64": "0.123.0",
|
||||
"@oxc-parser/binding-linux-arm-gnueabihf": "0.123.0",
|
||||
"@oxc-parser/binding-linux-arm-musleabihf": "0.123.0",
|
||||
"@oxc-parser/binding-linux-arm64-gnu": "0.123.0",
|
||||
"@oxc-parser/binding-linux-arm64-musl": "0.123.0",
|
||||
"@oxc-parser/binding-linux-ppc64-gnu": "0.123.0",
|
||||
"@oxc-parser/binding-linux-riscv64-gnu": "0.123.0",
|
||||
"@oxc-parser/binding-linux-riscv64-musl": "0.123.0",
|
||||
"@oxc-parser/binding-linux-s390x-gnu": "0.123.0",
|
||||
"@oxc-parser/binding-linux-x64-gnu": "0.123.0",
|
||||
"@oxc-parser/binding-linux-x64-musl": "0.123.0",
|
||||
"@oxc-parser/binding-openharmony-arm64": "0.123.0",
|
||||
"@oxc-parser/binding-wasm32-wasi": "0.123.0",
|
||||
"@oxc-parser/binding-win32-arm64-msvc": "0.123.0",
|
||||
"@oxc-parser/binding-win32-ia32-msvc": "0.123.0",
|
||||
"@oxc-parser/binding-win32-x64-msvc": "0.123.0"
|
||||
}
|
||||
},
|
||||
"node_modules/oxlint": {
|
||||
"version": "1.64.0",
|
||||
"resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.64.0.tgz",
|
||||
"integrity": "sha512-Star3SNpWPeWFPw7kRXIhXUSn6fdiAl25q15CQzH/9WaOtG6e9CWTc25vNZOCr4PE1yEP1GtKJKIKglhj3OmEQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"oxlint": "bin/oxlint"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Boshen"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@oxlint/binding-android-arm-eabi": "1.64.0",
|
||||
"@oxlint/binding-android-arm64": "1.64.0",
|
||||
"@oxlint/binding-darwin-arm64": "1.64.0",
|
||||
"@oxlint/binding-darwin-x64": "1.64.0",
|
||||
"@oxlint/binding-freebsd-x64": "1.64.0",
|
||||
"@oxlint/binding-linux-arm-gnueabihf": "1.64.0",
|
||||
"@oxlint/binding-linux-arm-musleabihf": "1.64.0",
|
||||
"@oxlint/binding-linux-arm64-gnu": "1.64.0",
|
||||
"@oxlint/binding-linux-arm64-musl": "1.64.0",
|
||||
"@oxlint/binding-linux-ppc64-gnu": "1.64.0",
|
||||
"@oxlint/binding-linux-riscv64-gnu": "1.64.0",
|
||||
"@oxlint/binding-linux-riscv64-musl": "1.64.0",
|
||||
"@oxlint/binding-linux-s390x-gnu": "1.64.0",
|
||||
"@oxlint/binding-linux-x64-gnu": "1.64.0",
|
||||
"@oxlint/binding-linux-x64-musl": "1.64.0",
|
||||
"@oxlint/binding-openharmony-arm64": "1.64.0",
|
||||
"@oxlint/binding-win32-arm64-msvc": "1.64.0",
|
||||
"@oxlint/binding-win32-ia32-msvc": "1.64.0",
|
||||
"@oxlint/binding-win32-x64-msvc": "1.64.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"oxlint-tsgolint": ">=0.22.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"oxlint-tsgolint": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
37
studio/bun.lock
Normal file
37
studio/bun.lock
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "unsloth-studio-tauri-cli",
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.10.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@tauri-apps/cli": ["@tauri-apps/cli@2.10.1", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.10.1", "@tauri-apps/cli-darwin-x64": "2.10.1", "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.1", "@tauri-apps/cli-linux-arm64-gnu": "2.10.1", "@tauri-apps/cli-linux-arm64-musl": "2.10.1", "@tauri-apps/cli-linux-riscv64-gnu": "2.10.1", "@tauri-apps/cli-linux-x64-gnu": "2.10.1", "@tauri-apps/cli-linux-x64-musl": "2.10.1", "@tauri-apps/cli-win32-arm64-msvc": "2.10.1", "@tauri-apps/cli-win32-ia32-msvc": "2.10.1", "@tauri-apps/cli-win32-x64-msvc": "2.10.1" }, "bin": { "tauri": "tauri.js" } }, "sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g=="],
|
||||
|
||||
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.10.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ=="],
|
||||
|
||||
"@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.10.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw=="],
|
||||
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.10.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w=="],
|
||||
|
||||
"@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.10.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA=="],
|
||||
|
||||
"@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.10.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg=="],
|
||||
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.10.1", "", { "os": "linux", "cpu": "none" }, "sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw=="],
|
||||
|
||||
"@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.10.1", "", { "os": "linux", "cpu": "x64" }, "sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw=="],
|
||||
|
||||
"@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.10.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ=="],
|
||||
|
||||
"@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.10.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg=="],
|
||||
|
||||
"@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.10.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw=="],
|
||||
|
||||
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.10.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg=="],
|
||||
}
|
||||
}
|
||||
1
studio/frontend/.gitignore
vendored
1
studio/frontend/.gitignore
vendored
|
|
@ -11,7 +11,6 @@ pnpm-debug.log*
|
|||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
bun.lock
|
||||
dist
|
||||
dist-ssr
|
||||
test/
|
||||
|
|
|
|||
2273
studio/frontend/bun.lock
Normal file
2273
studio/frontend/bun.lock
Normal file
File diff suppressed because it is too large
Load diff
233
studio/package-lock.json
generated
Normal file
233
studio/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
{
|
||||
"name": "unsloth-studio-tauri-cli",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "unsloth-studio-tauri-cli",
|
||||
"version": "0.0.0",
|
||||
"license": "AGPL-3.0-only",
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.10.1.tgz",
|
||||
"integrity": "sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"bin": {
|
||||
"tauri": "tauri.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/tauri"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tauri-apps/cli-darwin-arm64": "2.10.1",
|
||||
"@tauri-apps/cli-darwin-x64": "2.10.1",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": "2.10.1",
|
||||
"@tauri-apps/cli-linux-arm64-gnu": "2.10.1",
|
||||
"@tauri-apps/cli-linux-arm64-musl": "2.10.1",
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": "2.10.1",
|
||||
"@tauri-apps/cli-linux-x64-gnu": "2.10.1",
|
||||
"@tauri-apps/cli-linux-x64-musl": "2.10.1",
|
||||
"@tauri-apps/cli-win32-arm64-msvc": "2.10.1",
|
||||
"@tauri-apps/cli-win32-ia32-msvc": "2.10.1",
|
||||
"@tauri-apps/cli-win32-x64-msvc": "2.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-arm64": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.10.1.tgz",
|
||||
"integrity": "sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-x64": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.10.1.tgz",
|
||||
"integrity": "sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.10.1.tgz",
|
||||
"integrity": "sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.10.1.tgz",
|
||||
"integrity": "sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.10.1.tgz",
|
||||
"integrity": "sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.10.1.tgz",
|
||||
"integrity": "sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.10.1.tgz",
|
||||
"integrity": "sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-musl": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.10.1.tgz",
|
||||
"integrity": "sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.10.1.tgz",
|
||||
"integrity": "sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.10.1.tgz",
|
||||
"integrity": "sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.10.1.tgz",
|
||||
"integrity": "sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
studio/package.json
Normal file
10
studio/package.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "unsloth-studio-tauri-cli",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "Lockfile holder for @tauri-apps/cli used by the desktop release workflow. Not a real npm package; `npm ci --prefix studio` resolves the pinned Tauri CLI from this directory's package-lock.json.",
|
||||
"license": "AGPL-3.0-only",
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.10.1"
|
||||
}
|
||||
}
|
||||
146
studio/setup.ps1
146
studio/setup.ps1
|
|
@ -36,6 +36,12 @@ $DefaultLlamaSource = "https://github.com/ggml-org/llama.cpp"
|
|||
$DefaultLlamaTag = "latest"
|
||||
$DefaultLlamaForceCompileRef = "master"
|
||||
|
||||
# Bun pin. Tracks the version used to generate the committed bun.lock
|
||||
# files. Auto-installed on absence; force-reinstalled only as a
|
||||
# cache-corruption recovery step (we don't overwrite a user's existing
|
||||
# bun unless their install is producing corrupt output).
|
||||
$Script:BunPinVersion = "1.3.11"
|
||||
|
||||
# Verbose can be enabled either by CLI flag or by UNSLOTH_VERBOSE=1.
|
||||
$script:UnslothVerbose = ($env:UNSLOTH_VERBOSE -eq '1')
|
||||
foreach ($a in $args) {
|
||||
|
|
@ -1147,22 +1153,31 @@ if ($IsPipInstall) {
|
|||
|
||||
step "node" "$(node -v) | npm $(npm -v)"
|
||||
|
||||
# ── bun (optional, faster package installs) ──
|
||||
# Installed via npm — Node is already guaranteed above. Works on all platforms.
|
||||
# ── Bun (optional, used for faster lockfile-strict installs) ──
|
||||
# Auto-install only when missing. We do NOT overwrite a user's
|
||||
# existing bun unless their install is producing corrupt output
|
||||
# (handled inside the frontend install block below as a cache-
|
||||
# recovery step). Pin tracks the version used to generate the
|
||||
# committed bun.lock files.
|
||||
if (-not (Get-Command bun -ErrorAction SilentlyContinue)) {
|
||||
substep "installing bun (faster frontend package installs)..."
|
||||
substep "installing bun@$Script:BunPinVersion (pinned)..."
|
||||
$prevEAP_bun = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
Invoke-SetupCommand { npm install -g bun } | Out-Null
|
||||
Invoke-SetupCommand { npm install -g "bun@$Script:BunPinVersion" } | Out-Null
|
||||
$ErrorActionPreference = $prevEAP_bun
|
||||
Refresh-Environment
|
||||
if (Get-Command bun -ErrorAction SilentlyContinue) {
|
||||
substep "bun installed ($(bun --version))"
|
||||
substep "bun $(bun --version) installed"
|
||||
} else {
|
||||
substep "bun install skipped (npm will be used instead)"
|
||||
substep "bun install skipped (npm ci will be used instead)"
|
||||
}
|
||||
} else {
|
||||
substep "bun already installed ($(bun --version))"
|
||||
$bunVer = (bun --version 2>$null)
|
||||
if ($bunVer -eq $Script:BunPinVersion) {
|
||||
substep "bun $bunVer at pin"
|
||||
} else {
|
||||
substep "bun $bunVer present (pin is $Script:BunPinVersion; not overwriting user install)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1321,65 +1336,76 @@ if ($NeedFrontendBuild -and -not $IsPipInstall) {
|
|||
$WalkDir = Split-Path $WalkDir -Parent
|
||||
}
|
||||
|
||||
# Use bun if available (faster install), fall back to npm.
|
||||
# Bun is used only as package manager; Node runs the actual build (Vite 8).
|
||||
# Frontend install: Bun --frozen-lockfile first (faster, typically
|
||||
# 5-10x) when a committed bun.lock is present, npm ci as the
|
||||
# always-available fallback. Both run in lockfile-strict mode so
|
||||
# the install is byte-reproducible from whichever lockfile the
|
||||
# chosen package manager understands. The build always runs through
|
||||
# Node (npm run build) -- avoids bun runtime quirks on some
|
||||
# platforms.
|
||||
#
|
||||
# Bun's package cache can occasionally store metadata-only entries
|
||||
# that pass exit 0 but leave binaries (tsc, vite) missing. We
|
||||
# verify both binaries after install; on failure we clear the cache
|
||||
# and let npm ci take over rather than retrying bun, since npm ci
|
||||
# is the more defensive path under cache corruption.
|
||||
$prevEAP_npm = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
Push-Location $FrontendDir
|
||||
|
||||
$UseBun = $null -ne (Get-Command bun -ErrorAction SilentlyContinue)
|
||||
|
||||
# bun's package cache can become corrupt -- packages get stored with only
|
||||
# metadata but no actual content (bin/, lib/). When this happens bun install
|
||||
# exits 0 but leaves binaries missing. We validate after install and clear
|
||||
# the cache + retry once before falling back to npm.
|
||||
# Cache-corruption recovery ladder. Bun's package cache can store
|
||||
# metadata-only entries that pass `bun install` exit 0 but leave
|
||||
# binaries (tsc, vite) missing. We verify both binaries after each
|
||||
# attempt and escalate:
|
||||
# try 1: bun install --frozen-lockfile
|
||||
# try 2: remove node_modules + bun pm cache rm, retry
|
||||
# try 3: force-reinstall bun@$Script:BunPinVersion (a corrupted
|
||||
# bun binary itself can produce empty payloads), retry
|
||||
# final: npm ci (always-available safety net)
|
||||
$InstallOk = $false
|
||||
$UseBun = (Test-Path "bun.lock" -PathType Leaf) -and ($null -ne (Get-Command bun -ErrorAction SilentlyContinue))
|
||||
if ($UseBun) {
|
||||
Write-Host " Using bun for package install (faster)" -ForegroundColor DarkGray
|
||||
$bunExit = Invoke-SetupCommand { bun install }
|
||||
# On Windows, .bin/ entries vary by package manager:
|
||||
# npm → tsc, tsc.cmd, tsc.ps1
|
||||
# bun → tsc.exe, tsc.bunx
|
||||
$hasTsc = (Test-Path "node_modules\.bin\tsc") -or (Test-Path "node_modules\.bin\tsc.cmd") -or (Test-Path "node_modules\.bin\tsc.exe") -or (Test-Path "node_modules\.bin\tsc.bunx")
|
||||
$hasVite = (Test-Path "node_modules\.bin\vite") -or (Test-Path "node_modules\.bin\vite.cmd") -or (Test-Path "node_modules\.bin\vite.exe") -or (Test-Path "node_modules\.bin\vite.bunx")
|
||||
if ($bunExit -eq 0 -and $hasTsc -and $hasVite) {
|
||||
# bun install succeeded and critical binaries are present
|
||||
} elseif ($bunExit -eq 0) {
|
||||
Write-Host " bun install exited 0 but critical binaries are missing, clearing cache and retrying..." -ForegroundColor Yellow
|
||||
if (Test-Path "node_modules") {
|
||||
Remove-Item "node_modules" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
Invoke-SetupCommand { bun pm cache rm } | Out-Null
|
||||
$bunExit = Invoke-SetupCommand { bun install }
|
||||
$bunVer = (bun --version 2>$null)
|
||||
Write-Host " Using bun $bunVer --frozen-lockfile (faster)" -ForegroundColor DarkGray
|
||||
$bunAttempt = 0
|
||||
while ($bunAttempt -lt 3 -and -not $InstallOk) {
|
||||
$bunAttempt++
|
||||
$bunExit = Invoke-SetupCommand { bun install --frozen-lockfile --no-progress }
|
||||
# On Windows, .bin/ entries vary by package manager:
|
||||
# npm -> tsc, tsc.cmd, tsc.ps1
|
||||
# bun -> tsc.exe, tsc.bunx
|
||||
$hasTsc = (Test-Path "node_modules\.bin\tsc") -or (Test-Path "node_modules\.bin\tsc.cmd") -or (Test-Path "node_modules\.bin\tsc.exe") -or (Test-Path "node_modules\.bin\tsc.bunx")
|
||||
$hasVite = (Test-Path "node_modules\.bin\vite") -or (Test-Path "node_modules\.bin\vite.cmd") -or (Test-Path "node_modules\.bin\vite.exe") -or (Test-Path "node_modules\.bin\vite.bunx")
|
||||
if ($bunExit -ne 0 -or -not $hasTsc -or -not $hasVite) {
|
||||
Write-Host " bun retry failed, falling back to npm" -ForegroundColor Yellow
|
||||
if (Test-Path "node_modules") {
|
||||
Remove-Item "node_modules" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
$UseBun = $false
|
||||
if ($bunExit -eq 0 -and $hasTsc -and $hasVite) {
|
||||
$InstallOk = $true
|
||||
break
|
||||
}
|
||||
} else {
|
||||
substep "bun install failed (exit $bunExit), falling back to npm" "Yellow"
|
||||
if (Test-Path "node_modules") {
|
||||
Remove-Item "node_modules" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
if (Test-Path "node_modules") { Remove-Item "node_modules" -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
if ($bunAttempt -eq 1) {
|
||||
substep "bun install incomplete (try 1); clearing cache + retrying" "Yellow"
|
||||
Invoke-SetupCommand { bun pm cache rm } | Out-Null
|
||||
} elseif ($bunAttempt -eq 2) {
|
||||
substep "bun install still incomplete (try 2); reinstalling bun@$Script:BunPinVersion + retrying" "Yellow"
|
||||
Invoke-SetupCommand { bun pm cache rm } | Out-Null
|
||||
Invoke-SetupCommand { npm install -g "bun@$Script:BunPinVersion" } | Out-Null
|
||||
Refresh-Environment
|
||||
}
|
||||
$UseBun = $false
|
||||
}
|
||||
}
|
||||
if (-not $UseBun) {
|
||||
$npmExit = Invoke-SetupCommand { npm install }
|
||||
if (-not $InstallOk) {
|
||||
substep "falling back to npm ci" "Yellow"
|
||||
if (Test-Path "node_modules") { Remove-Item "node_modules" -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
$npmExit = Invoke-SetupCommand { npm ci }
|
||||
if ($npmExit -ne 0) {
|
||||
Pop-Location
|
||||
$ErrorActionPreference = $prevEAP_npm
|
||||
foreach ($gi in $HiddenGitignores) { Rename-Item -Path "$gi._twbuild" -NewName (Split-Path $gi -Leaf) -Force -ErrorAction SilentlyContinue }
|
||||
Write-Host "[ERROR] npm install failed (exit code $npmExit)" -ForegroundColor Red
|
||||
Write-Host " Try running 'npm install' manually in frontend/ to see errors" -ForegroundColor Yellow
|
||||
Write-Host "[ERROR] npm ci failed (exit code $npmExit)" -ForegroundColor Red
|
||||
Write-Host " Try running 'npm ci' manually in frontend/ to see errors" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Always use npm to run the build (Node runtime — avoids bun Windows runtime issues)
|
||||
$buildExit = Invoke-SetupCommand { npm run build }
|
||||
if ($buildExit -ne 0) {
|
||||
Pop-Location
|
||||
|
|
@ -1411,12 +1437,26 @@ if (Test-Path $OxcValidatorDir) {
|
|||
$prevEAP_oxc = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
Push-Location $OxcValidatorDir
|
||||
$oxcInstallExit = Invoke-SetupCommand { npm install }
|
||||
if ($oxcInstallExit -ne 0) {
|
||||
Pop-Location
|
||||
$ErrorActionPreference = $prevEAP_oxc
|
||||
Write-Host "[ERROR] OXC validator npm install failed (exit code $oxcInstallExit)" -ForegroundColor Red
|
||||
exit 1
|
||||
# Same Bun-first / npm-fallback pattern as the frontend install
|
||||
# above; both lockfile-strict.
|
||||
$OxcInstallOk = $false
|
||||
$UseBunOxc = (Test-Path "bun.lock" -PathType Leaf) -and ($null -ne (Get-Command bun -ErrorAction SilentlyContinue))
|
||||
if ($UseBunOxc) {
|
||||
$bunOxcExit = Invoke-SetupCommand { bun install --frozen-lockfile --no-progress }
|
||||
if ($bunOxcExit -eq 0 -and (Test-Path "node_modules\oxc-parser" -PathType Container)) {
|
||||
$OxcInstallOk = $true
|
||||
} else {
|
||||
if (Test-Path "node_modules") { Remove-Item "node_modules" -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
}
|
||||
if (-not $OxcInstallOk) {
|
||||
$oxcInstallExit = Invoke-SetupCommand { npm ci --no-fund --no-audit }
|
||||
if ($oxcInstallExit -ne 0) {
|
||||
Pop-Location
|
||||
$ErrorActionPreference = $prevEAP_oxc
|
||||
Write-Host "[ERROR] OXC validator npm ci failed (exit code $oxcInstallExit)" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
Pop-Location
|
||||
$ErrorActionPreference = $prevEAP_oxc
|
||||
|
|
|
|||
142
studio/setup.sh
142
studio/setup.sh
|
|
@ -42,6 +42,12 @@ _DEFAULT_LLAMA_SOURCE="https://github.com/ggml-org/llama.cpp"
|
|||
_DEFAULT_LLAMA_TAG="latest"
|
||||
_DEFAULT_LLAMA_FORCE_COMPILE_REF="master"
|
||||
|
||||
# Bun pin. Tracks the version used to generate the committed bun.lock
|
||||
# files. Auto-installed on absence; force-reinstalled only as a
|
||||
# cache-corruption recovery step (we don't overwrite a user's existing
|
||||
# bun unless their install is producing corrupt output).
|
||||
_BUN_PIN_VERSION="1.3.11"
|
||||
|
||||
# ── Colors (same palette as startup_banner / install_python_stack) ──
|
||||
if [ -n "${NO_COLOR:-}" ]; then
|
||||
C_TITLE= C_DIM= C_OK= C_WARN= C_ERR= C_RST=
|
||||
|
|
@ -295,18 +301,29 @@ fi
|
|||
step "node" "$(node -v) | npm $(npm -v)"
|
||||
verbose_substep "node check: NEED_NODE=$NEED_NODE NODE_OK=${NODE_OK:-unknown} NPM_MAJOR=${NPM_MAJOR:-unknown}"
|
||||
|
||||
# ── Install bun (optional, faster package installs) ──
|
||||
# Uses npm to install bun globally -- Node is already guaranteed above,
|
||||
# avoids platform-specific installers, PATH issues, and admin requirements.
|
||||
if ! command -v bun &>/dev/null; then
|
||||
substep "installing bun..."
|
||||
if run_maybe_quiet npm install -g bun && command -v bun &>/dev/null; then
|
||||
substep "bun installed ($(bun --version))"
|
||||
else
|
||||
substep "bun install skipped (npm will be used instead)"
|
||||
# ── Bun (optional, used for faster lockfile-strict installs) ──
|
||||
# Auto-install only when missing. We do NOT overwrite a user's existing
|
||||
# bun unless their install is producing corrupt output (handled inside
|
||||
# the frontend install loop below as a cache-recovery step).
|
||||
_bun_at_pin() {
|
||||
command -v bun >/dev/null 2>&1 || return 1
|
||||
[ "$(bun --version 2>/dev/null)" = "$_BUN_PIN_VERSION" ]
|
||||
}
|
||||
_install_pinned_bun() {
|
||||
substep "installing bun@$_BUN_PIN_VERSION (pinned)"
|
||||
if run_maybe_quiet npm install -g "bun@$_BUN_PIN_VERSION" && command -v bun &>/dev/null; then
|
||||
substep "bun $(bun --version) installed"
|
||||
return 0
|
||||
fi
|
||||
substep "bun install skipped (npm ci will be used instead)" "$C_WARN"
|
||||
return 1
|
||||
}
|
||||
if ! command -v bun &>/dev/null; then
|
||||
_install_pinned_bun || true
|
||||
elif _bun_at_pin; then
|
||||
verbose_substep "bun $(bun --version) at pin"
|
||||
else
|
||||
substep "bun already installed ($(bun --version))"
|
||||
substep "bun $(bun --version) present (pin is $_BUN_PIN_VERSION; not overwriting user install)"
|
||||
fi
|
||||
|
||||
# ── Build frontend ──
|
||||
|
|
@ -329,59 +346,49 @@ _restore_gitignores() {
|
|||
}
|
||||
trap _restore_gitignores EXIT
|
||||
|
||||
# Use bun for install if available (faster), fall back to npm.
|
||||
# Build always uses npm (Node runtime -- avoids bun runtime issues on some platforms).
|
||||
# NOTE: We intentionally avoid run_quiet for the bun install attempt because
|
||||
# run_quiet calls exit on failure, which would kill the script before the npm
|
||||
# fallback can run. Instead we capture output manually and only show it on failure.
|
||||
# Frontend install: Bun --frozen-lockfile first (faster, typically
|
||||
# 5-10x) when a committed bun.lock is present, npm ci as the
|
||||
# always-available fallback. Both run in lockfile-strict mode so the
|
||||
# install is byte-reproducible from whichever lockfile the chosen
|
||||
# package manager understands. The build always runs through Node
|
||||
# (npm run build) -- avoids bun runtime quirks on some platforms.
|
||||
#
|
||||
# IMPORTANT: bun's package cache can become corrupt -- packages get stored
|
||||
# with only metadata (package.json, README) but no actual content (bin/,
|
||||
# lib/). When this happens bun install exits 0 but leaves binaries missing.
|
||||
# We verify critical binaries after install. If missing, we clear the cache
|
||||
# and retry once before falling back to npm.
|
||||
_try_bun_install() {
|
||||
local _log _exit_code=0
|
||||
_log=$(mktemp)
|
||||
bun install >"$_log" 2>&1 || _exit_code=$?
|
||||
|
||||
# bun may create .exe shims on Windows (Git Bash / MSYS2) instead of plain scripts
|
||||
if [ "$_exit_code" -eq 0 ] \
|
||||
&& { [ -x node_modules/.bin/tsc ] || [ -f node_modules/.bin/tsc.exe ] || [ -f node_modules/.bin/tsc.bunx ]; } \
|
||||
&& { [ -x node_modules/.bin/vite ] || [ -f node_modules/.bin/vite.exe ] || [ -f node_modules/.bin/vite.bunx ]; }; then
|
||||
rm -f "$_log"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Either bun install failed or it exited 0 but left packages missing
|
||||
if [ "$_exit_code" -ne 0 ]; then
|
||||
echo " bun install failed (exit code $_exit_code):"
|
||||
else
|
||||
echo " bun install exited 0 but critical binaries are missing:"
|
||||
fi
|
||||
sed 's/^/ | /' "$_log" >&2
|
||||
rm -f "$_log"
|
||||
rm -rf node_modules
|
||||
return 1
|
||||
}
|
||||
|
||||
# Cache-corruption recovery ladder. Bun's package cache can store
|
||||
# metadata-only entries that pass `bun install` exit 0 but leave
|
||||
# binaries (tsc, vite) missing. We verify both binaries after each
|
||||
# attempt and escalate:
|
||||
# try 1: bun install --frozen-lockfile
|
||||
# try 2: rm -rf node_modules + bun pm cache rm, retry
|
||||
# try 3: force-reinstall bun@$_BUN_PIN_VERSION (a corrupted bun
|
||||
# binary itself can produce empty payloads), retry
|
||||
# final: npm ci (always-available safety net)
|
||||
_bun_install_ok=false
|
||||
if command -v bun &>/dev/null; then
|
||||
substep "using bun for package install (faster)"
|
||||
if _try_bun_install; then
|
||||
_bun_install_ok=true
|
||||
else
|
||||
# First attempt failed, likely due to corrupt cache entries.
|
||||
# Clear the cache and retry once.
|
||||
echo " Clearing bun cache and retrying..."
|
||||
run_maybe_quiet bun pm cache rm || true
|
||||
if _try_bun_install; then
|
||||
if [ -f bun.lock ] && command -v bun &>/dev/null; then
|
||||
substep "using bun $(bun --version) --frozen-lockfile (faster)"
|
||||
_bun_attempts=0
|
||||
while [ "$_bun_attempts" -lt 3 ] && [ "$_bun_install_ok" = false ]; do
|
||||
_bun_attempts=$((_bun_attempts + 1))
|
||||
if run_quiet_no_exit "bun install --frozen-lockfile (try $_bun_attempts)" bun install --frozen-lockfile --no-progress \
|
||||
&& { [ -x node_modules/.bin/tsc ] || [ -f node_modules/.bin/tsc.exe ] || [ -f node_modules/.bin/tsc.bunx ]; } \
|
||||
&& { [ -x node_modules/.bin/vite ] || [ -f node_modules/.bin/vite.exe ] || [ -f node_modules/.bin/vite.bunx ]; }; then
|
||||
_bun_install_ok=true
|
||||
break
|
||||
fi
|
||||
fi
|
||||
rm -rf node_modules
|
||||
if [ "$_bun_attempts" -eq 1 ]; then
|
||||
substep "bun install incomplete (try 1); clearing cache + retrying" "$C_WARN"
|
||||
run_maybe_quiet bun pm cache rm || true
|
||||
elif [ "$_bun_attempts" -eq 2 ]; then
|
||||
substep "bun install still incomplete (try 2); reinstalling bun@$_BUN_PIN_VERSION + retrying" "$C_WARN"
|
||||
run_maybe_quiet bun pm cache rm || true
|
||||
_install_pinned_bun || true
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ "$_bun_install_ok" = false ]; then
|
||||
run_quiet_no_exit "npm install" npm install --no-fund --no-audit --loglevel=error
|
||||
substep "falling back to npm ci"
|
||||
rm -rf node_modules
|
||||
run_quiet_no_exit "npm ci" npm ci --no-fund --no-audit --loglevel=error
|
||||
_npm_install_rc=$?
|
||||
if [ "$_npm_install_rc" -ne 0 ]; then
|
||||
exit "$_npm_install_rc"
|
||||
|
|
@ -406,12 +413,25 @@ cd "$SCRIPT_DIR"
|
|||
fi # end frontend build check
|
||||
|
||||
# ── oxc-validator runtime ──
|
||||
# Same Bun-first / npm-fallback pattern as the frontend install above;
|
||||
# both lockfile-strict.
|
||||
if [ -d "$SCRIPT_DIR/backend/core/data_recipe/oxc-validator" ] && command -v npm &>/dev/null; then
|
||||
cd "$SCRIPT_DIR/backend/core/data_recipe/oxc-validator"
|
||||
run_quiet_no_exit "npm install (oxc validator runtime)" npm install --no-fund --no-audit --loglevel=error
|
||||
_oxc_install_rc=$?
|
||||
if [ "$_oxc_install_rc" -ne 0 ]; then
|
||||
exit "$_oxc_install_rc"
|
||||
_oxc_bun_ok=false
|
||||
if [ -f bun.lock ] && command -v bun &>/dev/null; then
|
||||
if run_quiet_no_exit "bun install --frozen-lockfile (oxc validator)" bun install --frozen-lockfile --no-progress \
|
||||
&& [ -d node_modules/oxc-parser ]; then
|
||||
_oxc_bun_ok=true
|
||||
else
|
||||
rm -rf node_modules
|
||||
fi
|
||||
fi
|
||||
if [ "$_oxc_bun_ok" = false ]; then
|
||||
run_quiet_no_exit "npm ci (oxc validator runtime)" npm ci --no-fund --no-audit --loglevel=error
|
||||
_oxc_install_rc=$?
|
||||
if [ "$_oxc_install_rc" -ne 0 ]; then
|
||||
exit "$_oxc_install_rc"
|
||||
fi
|
||||
fi
|
||||
cd "$SCRIPT_DIR"
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue