Compare commits

..

31 Commits

Author SHA1 Message Date
syuilo 6d00645bc7 fix(frontend): iPadOSのPWAでアプリを切り替えた際にウィジェット表示ボタンが消滅する問題を修正 2025-12-18 20:27:12 +09:00
syuilo baeed4bc80 perf(backend): lazy load systeminformation
systeminformationを必要とする機能を有効にしていないサーバーで無駄に読み込まれることが無いように
2025-12-18 20:05:20 +09:00
syuilo dba44daf9c 🎨 and refactor 2025-12-18 15:40:40 +09:00
syuilo 46e6dd99d1 chore: remove beta label from some features 2025-12-18 15:15:07 +09:00
syuilo f48af7f73b 🎨 2025-12-18 14:55:19 +09:00
syuilo 834e8b4c24 fix(frontend): デッキUIでメニュー位置を下にしているとプロファイル削除ボタンが表示されないのを修正 2025-12-18 14:55:16 +09:00
github-actions[bot] 7ef0c96758 Bump version to 2025.12.2-beta.2 2025-12-17 03:31:55 +00:00
syuilo b10074e939 enhance(frontend): add deck tour 2025-12-17 12:27:55 +09:00
renovate[bot] 260dbd150b
fix(deps): update dependency systeminformation to v5.27.14 [security] [ci skip] (#17003)
* fix(deps): update dependency systeminformation to v5.27.14 [security]

* update whitelist to force update systeminformation package

* bump other dependencies to fix dep error

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-12-17 09:36:15 +09:00
syuilo 79cbbcfe0f Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2025-12-17 09:08:25 +09:00
syuilo c893f85864 Update example.yml 2025-12-17 09:08:22 +09:00
syuilo 24d4ffa2ec
Update CHANGELOG.md
Co-authored-by: かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>
2025-12-17 09:07:51 +09:00
github-actions[bot] 0b931daefd Bump version to 2025.12.2-beta.1 2025-12-16 14:00:25 +00:00
かっこかり cc05d93194
fix(frontend): まれに設定変更のタブ間同期に失敗する問題を修正 (#16991) 2025-12-16 22:56:57 +09:00
かっこかり 90345591bb
fix(frontend): 無限スクロールできる箇所の調整 (#17000) 2025-12-16 22:50:26 +09:00
github-actions[bot] 730227f353 Bump version to 2025.12.2-beta.0 2025-12-16 12:31:04 +00:00
syuilo 4acb37ee9d Update CHANGELOG.md 2025-12-16 21:23:51 +09:00
syuilo 7025769c69 fix(frontend): バージョン表記のないPlayが正しく動作しない問題を修正
Fix #16996
2025-12-16 21:23:23 +09:00
syuilo 1a4ef8769f
Update CHANGELOG.md 2025-12-16 20:08:01 +09:00
github-actions[bot] 055cd0c250 Bump version to 2025.12.2-alpha.0 2025-12-16 11:00:42 +00:00
syuilo d35ddc77d2 enhance(backend): request ip が localhost だった場合、レートリミットをスキップ & 警告を出すように 2025-12-16 19:56:44 +09:00
syuilo 8d871a58e3 Update CHANGELOG.md 2025-12-16 19:55:31 +09:00
syuilo 99b0b436e0 Update example.yml 2025-12-16 19:55:16 +09:00
syuilo e3d5b95672 Revert "Merge commit from fork"
This reverts commit 5512898463.

see https://github.com/misskey-dev/misskey/issues/16994
2025-12-16 14:21:39 +09:00
かっこかり 0d52145b2b
deps: update deps [ci skip] (#16997)
* update deps

* update chokidar to v5

* fix type error

* rollback serviceworker types to r74

* fix [ci skip]
2025-12-16 11:42:06 +09:00
かっこかり 467404d5bb
fix(gh): `thollander/actions-comment-pull-request@v3` の breaking change 対応漏れ 2025-12-16 09:45:26 +09:00
renovate[bot] 99e25784ad
chore(deps): update [github actions] update dependencies (major) (#16869)
* chore(deps): update [github actions] update dependencies

* migrate

* bump download-artifact to v7

* bump upload-artifact to v6

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>
2025-12-16 09:26:10 +09:00
github-actions[bot] 9e1e40d35a [skip ci] Update CHANGELOG.md (prepend template) 2025-12-14 07:27:11 +00:00
github-actions[bot] 8eb6e29d2c Release: 2025.12.1 2025-12-14 07:27:06 +00:00
Copilot 2d198a711b
Update PostgreSQL volume mount paths for PostgreSQL 18 (#16986)
* Initial plan

* Update PostgreSQL volume mount paths for PostgreSQL 18 compatibility

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-12-14 11:32:42 +09:00
syuilo e0b872dc09
Update CHANGELOG for version 2025.12.1
Removed empty section under General and retained fixes under Client.
2025-12-13 21:16:12 +09:00
76 changed files with 2012 additions and 1979 deletions

View File

@ -110,10 +110,19 @@ port: 3000
# Changes how the server interpret the origin IP of the request.
#
# Any format supported by Fastify is accepted.
# Default: do not trust any proxies (i.e. trustProxy: false)
# Default: trust all proxies (i.e. trustProxy: true)
# See: https://fastify.dev/docs/latest/reference/server/#trustproxy
# To improve security, we recommend that you configure your settings appropriately.
# Incorrect configuration can cause issues such as difficulty signing in,
# so please configure your settings carefully.
#
# trustProxy: false
#trustProxy:
# - '10.0.0.0/8'
# - '172.16.0.0/12'
# - '192.168.0.0/16'
# - '127.0.0.1/32'
# - '::1/128'
# - 'fc00::/7'
# ┌──────────────────────────┐
#───┘ PostgreSQL configuration └────────────────────────────────

View File

@ -16,13 +16,13 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Setup Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -12,9 +12,9 @@ jobs:
steps:
- name: Checkout head
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Setup Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'

View File

@ -18,7 +18,7 @@ jobs:
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
steps:
- name: checkout
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
with:
submodules: true
persist-credentials: false
@ -29,7 +29,7 @@ jobs:
- name: setup node
id: setup-node
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: pnpm
@ -53,7 +53,7 @@ jobs:
# packages/misskey-js/generator/built/autogen
- name: Upload Generated
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: generated-misskey-js
path: packages/misskey-js/generator/built/autogen
@ -66,14 +66,14 @@ jobs:
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
steps:
- name: checkout
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
with:
submodules: true
persist-credentials: false
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Upload From Merged
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: actual-misskey-js
path: packages/misskey-js/src/autogen
@ -86,13 +86,13 @@ jobs:
pull-requests: write
steps:
- name: download generated-misskey-js
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: generated-misskey-js
path: misskey-js-generated
- name: download actual-misskey-js
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: actual-misskey-js
path: misskey-js-actual
@ -113,9 +113,9 @@ jobs:
- name: send message
if: steps.check-changes.outputs.changes == 'true'
uses: thollander/actions-comment-pull-request@v2
uses: thollander/actions-comment-pull-request@v3
with:
comment_tag: check-misskey-js-autogen
comment-tag: check-misskey-js-autogen
message: |-
Thank you for sending us a great Pull Request! 👍
Please regenerate misskey-js type definitions! 🙏
@ -127,9 +127,9 @@ jobs:
- name: send message
if: steps.check-changes.outputs.changes == 'false'
uses: thollander/actions-comment-pull-request@v2
uses: thollander/actions-comment-pull-request@v3
with:
comment_tag: check-misskey-js-autogen
comment-tag: check-misskey-js-autogen
mode: delete
message: "Thank you!"
create_if_not_exists: false

View File

@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Check version
run: |
if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Check
run: |
counter=0

View File

@ -10,7 +10,7 @@ jobs:
check_copyright_year:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
- run: |
if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then
echo "Please change copyright year!"

View File

@ -28,7 +28,7 @@ jobs:
wait_time: ${{ steps.get-wait-time.outputs.wait_time }}
steps:
- name: Checkout
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Check allowed users
id: check-allowed-users

View File

@ -27,7 +27,7 @@ jobs:
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Check out the repo
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
@ -53,7 +53,7 @@ jobs:
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
@ -66,7 +66,7 @@ jobs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*

View File

@ -32,7 +32,7 @@ jobs:
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Check out the repo
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
@ -64,7 +64,7 @@ jobs:
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
@ -77,7 +77,7 @@ jobs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*

View File

@ -16,7 +16,7 @@ jobs:
DOCKLE_VERSION: 0.4.15
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
- name: Download and install dockle v${{ env.DOCKLE_VERSION }}
run: |

View File

@ -25,14 +25,14 @@ jobs:
ref: refs/pull/${{ github.event.number }}/merge
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
ref: ${{ matrix.ref }}
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -48,7 +48,7 @@ jobs:
- name: Copy API.json
run: cp packages/backend/built/api.json ${{ matrix.api-json-name }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: api-artifact-${{ matrix.api-json-name }}
path: ${{ matrix.api-json-name }}
@ -61,7 +61,7 @@ jobs:
PR_NUMBER: ${{ github.event.number }}
run: |
echo "$PR_NUMBER" > ./pr_number
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v6
with:
name: api-artifact-pr-number
path: pr_number

View File

@ -40,14 +40,14 @@ jobs:
- 56312:6379
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
ref: ${{ matrix.ref }}
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -67,7 +67,7 @@ jobs:
# Start the server and measure memory usage
node packages/backend/scripts/measure-memory.mjs > ${{ matrix.memory-json-name }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: memory-artifact-${{ matrix.memory-json-name }}
path: ${{ matrix.memory-json-name }}
@ -81,7 +81,7 @@ jobs:
PR_NUMBER: ${{ github.event.number }}
run: |
echo "$PR_NUMBER" > ./pr_number
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v6
with:
name: memory-artifact-pr-number
path: pr_number

View File

@ -11,6 +11,6 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@v6
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -36,13 +36,13 @@ jobs:
pnpm_install:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
fetch-depth: 0
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- uses: actions/setup-node@v4.4.0
- uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -69,13 +69,13 @@ jobs:
eslint-cache-version: v1
eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }}
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
fetch-depth: 0
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- uses: actions/setup-node@v4.4.0
- uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -100,13 +100,13 @@ jobs:
- sw
- misskey-js
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
fetch-depth: 0
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- uses: actions/setup-node@v4.4.0
- uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -16,13 +16,13 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
fetch-depth: 0
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- uses: actions/setup-node@v4.4.0
- uses: actions/setup-node@v6.1.0
with:
node-version-file: ".node-version"
cache: "pnpm"

View File

@ -16,13 +16,13 @@ jobs:
id-token: write
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -19,7 +19,7 @@ jobs:
edit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
- name: Get PR
run: |

View File

@ -36,7 +36,7 @@ jobs:
outputs:
pr_number: ${{ steps.get_pr.outputs.pr_number }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
- name: Get PRs
run: |

View File

@ -16,7 +16,7 @@ jobs:
# api-artifact
steps:
- name: Download artifact
uses: actions/github-script@v7.1.0
uses: actions/github-script@v8.0.0
with:
script: |
const fs = require('fs');
@ -60,7 +60,7 @@ jobs:
- name: Echo full diff
run: cat ./api-full.json.diff
- name: Upload full diff to Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: api-artifact
path: |
@ -89,16 +89,16 @@ jobs:
fi
echo "$FOOTER" >> ./output.md
- uses: thollander/actions-comment-pull-request@v2
- uses: thollander/actions-comment-pull-request@v3
with:
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
comment_tag: show_diff
filePath: ./output.md
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
comment-tag: show_diff
file-path: ./output.md
- name: Tell error to PR
uses: thollander/actions-comment-pull-request@v2
uses: thollander/actions-comment-pull-request@v3
if: failure() && steps.load-pr-num.outputs.pr-number
with:
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
comment_tag: show_diff_error
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
comment-tag: show_diff_error
message: |
api.jsonの差分作成中にエラーが発生しました。詳細は[Workflowのログ](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})を確認してください。

View File

@ -15,7 +15,7 @@ jobs:
steps:
- name: Download artifact
uses: actions/github-script@v7.1.0
uses: actions/github-script@v8.0.0
with:
script: |
const fs = require('fs');
@ -107,16 +107,16 @@ jobs:
fi
echo "$FOOTER" >> ./output.md
- uses: thollander/actions-comment-pull-request@v2
- uses: thollander/actions-comment-pull-request@v3
with:
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
comment_tag: show_memory_diff
filePath: ./output.md
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
comment-tag: show_memory_diff
file-path: ./output.md
- name: Tell error to PR
uses: thollander/actions-comment-pull-request@v2
uses: thollander/actions-comment-pull-request@v3
if: failure() && steps.load-pr-num.outputs.pr-number
with:
pr_number: ${{ steps.load-pr-num.outputs.pr-number }}
comment_tag: show_memory_diff_error
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
comment-tag: show_memory_diff_error
message: |
An error occurred while comparing backend memory usage. See [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.

View File

@ -14,7 +14,7 @@ jobs:
pull-requests: write
steps:
- name: Reply
uses: actions/github-script@v6
uses: actions/github-script@v8
with:
script: |
const body = `To dev team (@misskey-dev/dev):

View File

@ -22,12 +22,12 @@ jobs:
NODE_OPTIONS: "--max_old_space_size=7168"
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
if: github.event_name != 'pull_request_target'
with:
fetch-depth: 0
submodules: true
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
if: github.event_name == 'pull_request_target'
with:
fetch-depth: 0
@ -39,7 +39,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -90,7 +90,7 @@ jobs:
env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
- name: Notify that Chromatic detects changes
uses: actions/github-script@v7.1.0
uses: actions/github-script@v8.0.0
if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
@ -102,7 +102,7 @@ jobs:
body: 'Chromatic detects changes. Please [review the changes on Chromatic](https://www.chromatic.com/builds?appId=6428f7d7b962f0b79f97d6e4).'
})
- name: Upload Artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: storybook
path: packages/frontend/storybook-static

View File

@ -50,7 +50,7 @@ jobs:
- 56312:6379
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
- name: Setup pnpm
@ -86,7 +86,7 @@ jobs:
fi
done
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: ${{ matrix.node-version-file }}
cache: 'pnpm'
@ -129,13 +129,13 @@ jobs:
- 56312:6379
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: ${{ matrix.node-version-file }}
cache: 'pnpm'
@ -173,7 +173,7 @@ jobs:
POSTGRES_HOST_AUTH_METHOD: trust
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
- name: Setup pnpm
@ -182,7 +182,7 @@ jobs:
id: current-date
run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: ${{ matrix.node-version-file }}
cache: 'pnpm'

View File

@ -32,7 +32,7 @@ jobs:
- .node-version
- .github/min.node-version
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: true
- name: Setup pnpm
@ -68,7 +68,7 @@ jobs:
fi
done
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: ${{ matrix.node-version-file }}
cache: 'pnpm'

View File

@ -28,13 +28,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -76,7 +76,7 @@ jobs:
- 56312:6379
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
# https://github.com/cypress-io/cypress-docker-images/issues/150
@ -88,7 +88,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'
@ -113,12 +113,12 @@ jobs:
wait-on: 'http://localhost:61812'
headed: true
browser: ${{ matrix.browser }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v6
if: failure()
with:
name: ${{ matrix.browser }}-cypress-screenshots
path: cypress/screenshots
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v6
if: always()
with:
name: ${{ matrix.browser }}-cypress-videos

View File

@ -22,13 +22,13 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4.3.0
uses: actions/checkout@v6.0.1
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Setup Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -16,13 +16,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -17,13 +17,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.3.0
- uses: actions/checkout@v6.0.1
with:
submodules: true
- name: Setup pnpm
uses: pnpm/action-setup@v4.2.0
- name: Use Node.js
uses: actions/setup-node@v4.4.0
uses: actions/setup-node@v6.1.0
with:
node-version-file: '.node-version'
cache: 'pnpm'

View File

@ -1,7 +1,21 @@
## 2025.12.1
## 2025.12.2
### Note
v2025.12.0で行われた「configの`trustProxy`のデフォルト値を`false`に変更」について、正しく環境に応じた設定を行わないとサインインが困難になるといった状態を緩和するために、以前のデフォルト値に戻す暫定対応を行いました。
**セキュリティを向上させるためには適切な設定を行うことを推奨しますが、間違った設定値を入れると上述のような不具合の原因となりますので、慎重に行ってください。**
### General
-
- 依存関係の更新
### Client
- Enhance: デッキのUI説明を追加
- Fix: バージョン表記のないPlayが正しく動作しない問題を修正
バージョン表記のないものは v0.x 系として実行されます。v1.x 系で動作させたい場合は必ずバージョン表記を含めてください。
- Fix: デッキUIでメニュー位置を下にしているとプロファイル削除ボタンが表示されないのを修正
## 2025.12.1
### Client
- Fix: 特定の条件下でMisskeyが起動せず空白のページが表示されることがある問題を軽減

View File

@ -21,7 +21,7 @@ services:
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
- ./db:/var/lib/postgresql
healthcheck:
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
interval: 5s

View File

@ -43,7 +43,7 @@ services:
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
- ./db:/var/lib/postgresql
healthcheck:
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
interval: 5s

View File

@ -2890,6 +2890,15 @@ _deck:
usedAsMinWidthWhenFlexible: "「幅を自動調整」が有効の場合、これが幅の最小値となります"
flexible: "幅を自動調整"
enableSyncBetweenDevicesForProfiles: "プロファイル情報のデバイス間同期を有効にする"
showHowToUse: "UIの説明を見る"
_howToUse:
addColumn_title: "カラム追加"
addColumn_description: "カラムの種類を選んで追加できます。"
settings_title: "UI設定"
settings_description: "デッキUIの詳細設定を行えます。"
switchProfile_title: "プロファイル切り替え"
switchProfile_description: "UIのレイアウトをプロファイルとして保存し、いつでも切り替えられるようにできます。"
_columns:
main: "メイン"

View File

@ -1,12 +1,12 @@
{
"name": "misskey",
"version": "2025.12.1-alpha.1",
"version": "2025.12.2-beta.2",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/misskey-dev/misskey.git"
},
"packageManager": "pnpm@10.24.0",
"packageManager": "pnpm@10.25.0",
"workspaces": [
"packages/misskey-js",
"packages/i18n",
@ -53,13 +53,13 @@
"cleanall": "pnpm clean-all"
},
"resolutions": {
"chokidar": "4.0.3",
"chokidar": "5.0.0",
"lodash": "4.17.21"
},
"dependencies": {
"cssnano": "7.1.2",
"esbuild": "0.27.0",
"execa": "9.6.0",
"esbuild": "0.27.1",
"execa": "9.6.1",
"ignore-walk": "8.0.0",
"js-yaml": "4.1.1",
"postcss": "8.5.6",
@ -71,15 +71,15 @@
"@eslint/js": "9.39.1",
"@misskey-dev/eslint-plugin": "2.2.0",
"@types/js-yaml": "4.0.9",
"@types/node": "24.10.1",
"@typescript-eslint/eslint-plugin": "8.47.0",
"@typescript-eslint/parser": "8.47.0",
"@types/node": "24.10.2",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"cross-env": "10.1.0",
"cypress": "15.7.0",
"cypress": "15.7.1",
"eslint": "9.39.1",
"globals": "16.5.0",
"ncp": "2.0.0",
"pnpm": "10.24.0",
"pnpm": "10.25.0",
"start-server-and-test": "2.1.3"
},
"optionalDependencies": {

View File

@ -71,25 +71,25 @@
"utf-8-validate": "6.0.5"
},
"dependencies": {
"@aws-sdk/client-s3": "3.940.0",
"@aws-sdk/lib-storage": "3.940.0",
"@aws-sdk/client-s3": "3.948.0",
"@aws-sdk/lib-storage": "3.948.0",
"@discordapp/twemoji": "16.0.1",
"@fastify/accepts": "5.0.3",
"@fastify/cors": "11.1.0",
"@fastify/accepts": "5.0.4",
"@fastify/cors": "11.2.0",
"@fastify/express": "4.0.2",
"@fastify/http-proxy": "11.3.0",
"@fastify/http-proxy": "11.4.1",
"@fastify/multipart": "9.3.0",
"@fastify/static": "8.3.0",
"@kitajs/html": "4.2.11",
"@misskey-dev/sharp-read-bmp": "1.2.0",
"@misskey-dev/summaly": "5.2.5",
"@napi-rs/canvas": "0.1.83",
"@napi-rs/canvas": "0.1.84",
"@nestjs/common": "11.1.9",
"@nestjs/core": "11.1.9",
"@nestjs/testing": "11.1.9",
"@peertube/http-signature": "1.7.0",
"@sentry/node": "10.27.0",
"@sentry/profiling-node": "10.27.0",
"@sentry/node": "10.29.0",
"@sentry/profiling-node": "10.29.0",
"@simplewebauthn/server": "13.2.2",
"@sinonjs/fake-timers": "15.0.0",
"@smithy/node-http-handler": "4.4.5",
@ -104,11 +104,11 @@
"bcryptjs": "3.0.3",
"blurhash": "2.0.5",
"body-parser": "2.2.1",
"bullmq": "5.65.0",
"bullmq": "5.65.1",
"cacheable-lookup": "7.0.0",
"chalk": "5.6.2",
"chalk-template": "1.1.2",
"chokidar": "4.0.3",
"chokidar": "5.0.0",
"color-convert": "3.1.3",
"content-disposition": "1.0.1",
"date-fns": "4.1.0",
@ -166,13 +166,13 @@
"slacc": "0.0.10",
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"systeminformation": "5.27.11",
"systeminformation": "5.27.14",
"tinycolor2": "1.6.0",
"tmp": "0.2.5",
"tsc-alias": "1.8.16",
"typeorm": "0.3.27",
"typeorm": "0.3.28",
"typescript": "5.9.3",
"ulid": "3.0.1",
"ulid": "3.0.2",
"vary": "1.1.2",
"web-push": "3.6.7",
"ws": "8.18.3",
@ -182,7 +182,7 @@
"@jest/globals": "29.7.0",
"@kitajs/ts-html-plugin": "4.1.3",
"@nestjs/platform-express": "11.1.9",
"@sentry/vue": "10.27.0",
"@sentry/vue": "10.29.0",
"@simplewebauthn/types": "12.0.0",
"@swc/jest": "0.2.39",
"@types/accepts": "1.3.7",
@ -196,7 +196,7 @@
"@types/jsonld": "1.5.15",
"@types/mime-types": "3.0.1",
"@types/ms": "2.1.0",
"@types/node": "24.10.1",
"@types/node": "24.10.2",
"@types/nodemailer": "7.0.4",
"@types/oauth2orize": "1.11.5",
"@types/oauth2orize-pkce": "0.1.2",
@ -207,7 +207,7 @@
"@types/rename": "1.0.7",
"@types/sanitize-html": "2.16.0",
"@types/semver": "7.7.1",
"@types/simple-oauth2": "5.0.7",
"@types/simple-oauth2": "5.0.8",
"@types/sinonjs__fake-timers": "15.0.1",
"@types/supertest": "6.0.3",
"@types/tinycolor2": "1.4.6",
@ -215,13 +215,13 @@
"@types/vary": "1.1.3",
"@types/web-push": "3.6.4",
"@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"aws-sdk-client-mock": "4.1.0",
"cbor": "10.0.11",
"cross-env": "10.1.0",
"eslint-plugin-import": "2.32.0",
"execa": "9.6.0",
"execa": "9.6.1",
"fkill": "10.0.1",
"jest": "29.7.0",
"jest-mock": "29.7.0",
@ -230,6 +230,6 @@
"pid-port": "2.0.0",
"simple-oauth2": "5.1.0",
"supertest": "7.1.4",
"vite": "7.2.4"
"vite": "7.2.7"
}
}

View File

@ -7,7 +7,6 @@ import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import { Injectable } from '@nestjs/common';
import si from 'systeminformation';
import { Mutex } from 'async-mutex';
import fetch from 'node-fetch';
import { bindThis } from '@/decorators.js';
@ -84,6 +83,7 @@ export class AiService {
@bindThis
private async getCpuFlags(): Promise<string[]> {
const si = await import('systeminformation');
const str = await si.cpuFlags();
return str.split(/\s+/);
}

View File

@ -4,13 +4,12 @@
*/
import { Inject, Injectable } from '@nestjs/common';
import si from 'systeminformation';
import Xev from 'xev';
import * as osUtils from 'os-utils';
import { bindThis } from '@/decorators.js';
import type { OnApplicationShutdown } from '@nestjs/common';
import { MiMeta } from '@/models/_.js';
import { DI } from '@/di-symbols.js';
import type { OnApplicationShutdown } from '@nestjs/common';
const ev = new Xev();
@ -97,12 +96,14 @@ function cpuUsage(): Promise<number> {
// MEMORY STAT
async function mem() {
const si = await import('systeminformation');
const data = await si.mem();
return data;
}
// NETWORK STAT
async function net() {
const si = await import('systeminformation');
const iface = await si.networkInterfaceDefault();
const data = await si.networkStats(iface);
return data[0];
@ -110,5 +111,6 @@ async function net() {
// FS STAT
async function fs() {
const si = await import('systeminformation');
return await si.disksIO().catch(() => ({ rIO_sec: 0, wIO_sec: 0 }));
}

View File

@ -4,15 +4,11 @@
*/
import * as os from 'node:os';
import sysUtils from 'systeminformation';
import type Logger from '@/logger.js';
export async function showMachineInfo(parentLogger: Logger) {
const logger = parentLogger.createSubLogger('machine');
logger.debug(`Hostname: ${os.hostname()}`);
logger.debug(`Platform: ${process.platform} Arch: ${process.arch}`);
const mem = await sysUtils.mem();
const totalmem = (mem.total / 1024 / 1024 / 1024).toFixed(1);
const availmem = (mem.available / 1024 / 1024 / 1024).toFixed(1);
logger.debug(`CPU: ${os.cpus().length} core MEM: ${totalmem}GB (available: ${availmem}GB)`);
logger.debug(`CPU: ${os.cpus().length} core MEM: ${(os.totalmem() / 1024 / 1024 / 1024).toFixed(1)}GB (available: ${(os.freemem() / 1024 / 1024 / 1024).toFixed(1)}GB)`);
}

View File

@ -75,7 +75,7 @@ export class ServerService implements OnApplicationShutdown {
@bindThis
public async launch(): Promise<void> {
const fastify = Fastify({
trustProxy: this.config.trustProxy ?? false,
trustProxy: this.config.trustProxy ?? true,
logger: false,
});
this.#fastify = fastify;

View File

@ -313,13 +313,17 @@ export class ApiCallService implements OnApplicationShutdown {
}
if (ep.meta.limit) {
// koa will automatically load the `X-Forwarded-For` header if `proxy: true` is configured in the app.
let limitActor: string;
let limitActor: string | null;
if (user) {
limitActor = user.id;
} else {
if (request.ip === '::1' || request.ip === '127.0.0.1') {
console.warn('request ip is localhost, maybe caused by misconfiguration of trustProxy or reverse proxy');
limitActor = null;
} else {
limitActor = getIpHash(request.ip);
}
}
const limit = Object.assign({}, ep.meta.limit);
@ -330,7 +334,7 @@ export class ApiCallService implements OnApplicationShutdown {
// TODO: 毎リクエスト計算するのもあれだしキャッシュしたい
const factor = user ? (await this.roleService.getUserPolicies(user.id)).rateLimitFactor : 1;
if (factor > 0) {
if (limitActor != null && factor > 0) {
// Rate limit
const rateLimit = await this.rateLimiterService.limit(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor, factor);
if (rateLimit != null) {

View File

@ -89,6 +89,9 @@ export class SigninApiService {
return { error };
}
if (request.ip === '::1' || request.ip === '127.0.0.1') {
console.warn('request ip is localhost, maybe caused by misconfiguration of trustProxy or reverse proxy');
} else {
// not more than 1 attempt per second and not more than 10 attempts per hour
const rateLimit = await this.rateLimiterService.limit({ key: 'signin', duration: 60 * 60 * 1000, max: 10, minInterval: 1000 }, getIpHash(request.ip));
if (rateLimit != null) {
@ -101,6 +104,7 @@ export class SigninApiService {
},
};
}
}
if (typeof username !== 'string') {
reply.code(400);

View File

@ -84,6 +84,9 @@ export class SigninWithPasskeyApiService {
return error(status ?? 500, failure ?? { id: '4e30e80c-e338-45a0-8c8f-44455efa3b76' });
};
if (request.ip === '::1' || request.ip === '127.0.0.1') {
console.warn('request ip is localhost, maybe caused by misconfiguration of trustProxy or reverse proxy');
} else {
try {
// Not more than 1 API call per 250ms and not more than 100 attempts per 30min
// NOTE: 1 Sign-in require 2 API calls
@ -98,6 +101,7 @@ export class SigninWithPasskeyApiService {
},
};
}
}
// Initiate Passkey Auth challenge with context
if (!credential) {

View File

@ -4,7 +4,6 @@
*/
import * as os from 'node:os';
import si from 'systeminformation';
import { Inject, Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
import * as Redis from 'ioredis';
@ -112,6 +111,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
) {
super(meta, paramDef, async () => {
const si = await import('systeminformation');
const memStats = await si.mem();
const fsStats = await si.fsSize();
const netInterface = await si.networkInterfaceDefault();

View File

@ -4,7 +4,6 @@
*/
import * as os from 'node:os';
import si from 'systeminformation';
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { MiMeta } from '@/models/_.js';
@ -93,6 +92,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
},
};
const si = await import('systeminformation');
const memStats = await si.mem();
const fsStats = await si.fsSize();

View File

@ -50,7 +50,7 @@ services:
volumes:
- type: bind
source: ./volumes/db.a
target: /var/lib/postgresql/data
target: /var/lib/postgresql
bind:
create_host_path: true

View File

@ -50,7 +50,7 @@ services:
volumes:
- type: bind
source: ./volumes/db.b
target: /var/lib/postgresql/data
target: /var/lib/postgresql
bind:
create_host_path: true

View File

@ -11,9 +11,9 @@
},
"devDependencies": {
"@types/estree": "1.0.8",
"@types/node": "24.10.1",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0",
"@types/node": "24.10.2",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"rollup": "4.53.3",
"typescript": "5.9.3"
},
@ -21,6 +21,6 @@
"i18n": "workspace:*",
"estree-walker": "3.0.3",
"magic-string": "0.30.21",
"vite": "7.2.4"
"vite": "7.2.7"
}
}

View File

@ -26,11 +26,11 @@
"misskey-js": "workspace:*",
"punycode.js": "2.3.1",
"rollup": "4.53.3",
"sass": "1.94.2",
"shiki": "3.17.0",
"sass": "1.95.1",
"shiki": "3.19.0",
"tinycolor2": "1.6.0",
"uuid": "13.0.0",
"vite": "7.2.4",
"vite": "7.2.7",
"vue": "3.5.25"
},
"devDependencies": {
@ -39,13 +39,13 @@
"@testing-library/vue": "8.1.0",
"@types/estree": "1.0.8",
"@types/micromatch": "4.0.10",
"@types/node": "24.10.1",
"@types/node": "24.10.2",
"@types/punycode.js": "npm:@types/punycode@2.1.4",
"@types/tinycolor2": "1.4.6",
"@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0",
"@vitest/coverage-v8": "4.0.14",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"@vitest/coverage-v8": "4.0.15",
"@vue/runtime-core": "3.5.25",
"acorn": "8.15.0",
"cross-env": "10.1.0",
@ -54,15 +54,15 @@
"happy-dom": "20.0.11",
"intersection-observer": "0.12.2",
"micromatch": "4.0.8",
"msw": "2.12.3",
"msw": "2.12.4",
"nodemon": "3.1.11",
"prettier": "3.7.1",
"prettier": "3.7.4",
"start-server-and-test": "2.1.3",
"tsx": "4.20.6",
"tsx": "4.21.0",
"typescript": "5.9.3",
"vite-plugin-turbosnap": "1.0.3",
"vue-component-type-helpers": "3.1.5",
"vue-component-type-helpers": "3.1.8",
"vue-eslint-parser": "10.2.0",
"vue-tsc": "3.1.5"
"vue-tsc": "3.1.8"
}
}

View File

@ -21,10 +21,10 @@
"lint": "pnpm typecheck && pnpm eslint"
},
"devDependencies": {
"@types/node": "24.10.1",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0",
"esbuild": "0.27.0",
"@types/node": "24.10.2",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"esbuild": "0.27.1",
"eslint-plugin-vue": "10.6.2",
"nodemon": "3.1.11",
"typescript": "5.9.3",

View File

@ -19,18 +19,18 @@
"@analytics/google-analytics": "1.1.0",
"@discordapp/twemoji": "16.0.1",
"@github/webauthn-json": "2.1.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@mcaptcha/vanilla-glue": "0.1.0-rc2",
"i18n": "workspace:*",
"@misskey-dev/browser-image-resizer": "2024.1.0",
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-replace": "6.0.3",
"@rollup/pluginutils": "5.3.0",
"@sentry/vue": "10.27.0",
"@sentry/vue": "10.29.0",
"@syuilo/aiscript": "1.2.0",
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
"@twemoji/parser": "16.0.0",
"@vitejs/plugin-vue": "6.0.2",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.16",
"analytics": "0.8.19",
"broadcast-channel": "7.2.0",
"buraha": "0.0.1",
@ -45,8 +45,8 @@
"cropperjs": "2.1.0",
"date-fns": "4.1.0",
"eventemitter3": "5.0.1",
"execa": "9.6.0",
"exifreader": "4.32.0",
"execa": "9.6.1",
"exifreader": "4.33.1",
"frontend-shared": "workspace:*",
"icons-subsetter": "workspace:*",
"idb-keyval": "6.2.2",
@ -55,7 +55,7 @@
"is-file-animated": "1.0.2",
"json5": "2.2.3",
"matter-js": "0.20.0",
"mediabunny": "1.25.3",
"mediabunny": "1.25.8",
"mfm-js": "0.25.0",
"misskey-bubble-game": "workspace:*",
"misskey-js": "workspace:*",
@ -66,14 +66,14 @@
"qr-scanner": "1.4.2",
"rollup": "4.53.3",
"sanitize-html": "2.17.0",
"sass": "1.94.2",
"shiki": "3.17.0",
"sass": "1.95.1",
"shiki": "3.19.0",
"textarea-caret": "3.1.0",
"three": "0.181.2",
"throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0",
"v-code-diff": "1.13.1",
"vite": "7.2.4",
"vite": "7.2.7",
"vue": "3.5.25",
"vuedraggable": "next",
"wanakana": "5.3.1"
@ -82,7 +82,7 @@
"@misskey-dev/summaly": "5.2.5",
"@storybook/addon-essentials": "8.6.14",
"@storybook/addon-interactions": "8.6.14",
"@storybook/addon-links": "10.1.0",
"@storybook/addon-links": "10.1.5",
"@storybook/addon-mdx-gfm": "8.6.14",
"@storybook/addon-storysource": "8.6.14",
"@storybook/blocks": "8.6.14",
@ -90,33 +90,33 @@
"@storybook/core-events": "8.6.14",
"@storybook/manager-api": "8.6.14",
"@storybook/preview-api": "8.6.14",
"@storybook/react": "10.1.0",
"@storybook/react-vite": "10.1.0",
"@storybook/react": "10.1.5",
"@storybook/react-vite": "10.1.5",
"@storybook/test": "8.6.14",
"@storybook/theming": "8.6.14",
"@storybook/types": "8.6.14",
"@storybook/vue3": "10.1.0",
"@storybook/vue3-vite": "10.1.0",
"@storybook/vue3": "10.1.5",
"@storybook/vue3-vite": "10.1.5",
"@tabler/icons-webfont": "3.35.0",
"@testing-library/vue": "8.1.0",
"@types/canvas-confetti": "1.9.0",
"@types/estree": "1.0.8",
"@types/matter-js": "0.20.2",
"@types/micromatch": "4.0.10",
"@types/node": "24.10.1",
"@types/node": "24.10.2",
"@types/punycode.js": "npm:@types/punycode@2.1.4",
"@types/sanitize-html": "2.16.0",
"@types/seedrandom": "3.0.8",
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0",
"@vitest/coverage-v8": "4.0.14",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"@vitest/coverage-v8": "4.0.15",
"@vue/compiler-core": "3.5.25",
"acorn": "8.15.0",
"astring": "1.9.0",
"cross-env": "10.1.0",
"cypress": "15.7.0",
"cypress": "15.7.1",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-vue": "10.6.2",
"estree-walker": "3.0.3",
@ -125,24 +125,24 @@
"magic-string": "0.30.21",
"micromatch": "4.0.8",
"minimatch": "10.1.1",
"msw": "2.12.3",
"msw": "2.12.4",
"msw-storybook-addon": "2.0.6",
"nodemon": "3.1.11",
"prettier": "3.7.1",
"react": "19.2.0",
"react-dom": "19.2.0",
"prettier": "3.7.4",
"react": "19.2.1",
"react-dom": "19.2.1",
"seedrandom": "3.0.5",
"start-server-and-test": "2.1.3",
"storybook": "10.1.0",
"storybook": "10.1.5",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"tsx": "4.20.6",
"tsx": "4.21.0",
"typescript": "5.9.3",
"vite-plugin-glsl": "1.5.4",
"vite-plugin-glsl": "1.5.5",
"vite-plugin-turbosnap": "1.0.3",
"vitest": "4.0.14",
"vitest": "4.0.15",
"vitest-fetch-mock": "0.4.5",
"vue-component-type-helpers": "3.1.5",
"vue-component-type-helpers": "3.1.8",
"vue-eslint-parser": "10.2.0",
"vue-tsc": "3.1.5"
"vue-tsc": "3.1.8"
}
}

View File

@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkModalWindow>
</template>
<script lang="ts" setup>
import { defineProps, ref } from 'vue';
import { ref } from 'vue';
import MkModalWindow from './MkModalWindow.vue';
import type * as Misskey from 'misskey-js';

View File

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div
:class="[$style.root, { [$style.modal]: modal, _popup: modal }]"
:class="[$style.root]"
@dragover.stop="onDragover"
@dragenter="onDragenter"
@dragleave="onDragleave"
@ -114,7 +114,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide, shallowRef, ref, computed, useTemplateRef, onUnmounted } from 'vue';
import { watch, nextTick, onMounted, defineAsyncComponent, provide, shallowRef, ref, computed, useTemplateRef, onUnmounted } from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
import insertTextAtCursor from 'insert-text-at-cursor';
@ -161,8 +161,6 @@ import { closeTip } from '@/tips.js';
const $i = ensureSignin();
const modal = inject(DI.inModal, false);
const props = withDefaults(defineProps<PostFormProps & {
fixed?: boolean;
autofocus?: boolean;
@ -1447,13 +1445,6 @@ defineExpose({
.root {
position: relative;
container-type: inline-size;
&.modal {
width: 100%;
max-width: 520px;
overflow-x: clip;
overflow-y: auto;
}
}
//#region header
@ -1722,7 +1713,8 @@ html[data-color-scheme=light] .preview {
min-width: 100%;
width: 100%;
min-height: 90px;
height: 100%;
max-height: 500px;
field-sizing: content;
}
.textCount {

View File

@ -14,6 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPostForm
ref="form"
:class="$style.form"
class="_popup"
v-bind="props"
autofocus
freezeAfterPosted
@ -73,7 +74,8 @@ function onModalClosed() {
<style lang="scss" module>
.form {
max-height: 100%;
width: 100%;
max-width: 520px;
margin: 0 auto auto auto;
}
</style>

View File

@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template v-if="showDecoration">
<img
v-for="decoration in decorations ?? user.avatarDecorations"
:class="[$style.decoration, { [$style.decorationBlink]: decoration.blink }]"
:class="[$style.decoration, { [$style.decorationBlink]: getDecorationIsBrink(decoration) }]"
:src="getDecorationUrl(decoration)"
:style="{
rotate: getDecorationAngle(decoration),
@ -56,13 +56,16 @@ import { prefer } from '@/preferences.js';
const animation = ref(prefer.s.animation);
const squareAvatars = ref(prefer.s.squareAvatars);
type Decoration = Misskey.entities.UserDetailed['avatarDecorations'][number];
type DecorationEditorDecoration = Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'> & { blink?: boolean; };
const props = withDefaults(defineProps<{
user: Misskey.entities.User;
target?: string | null;
link?: boolean;
preview?: boolean;
indicator?: boolean;
decorations?: (Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'> & { blink?: boolean; })[];
decorations?: DecorationEditorDecoration[];
forceShowDecoration?: boolean;
}>(), {
target: null,
@ -93,27 +96,31 @@ function onClick(ev: MouseEvent): void {
emit('click', ev);
}
function getDecorationUrl(decoration: Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'>) {
function getDecorationUrl(decoration: Decoration | DecorationEditorDecoration) {
if (prefer.s.disableShowingAnimatedImages || prefer.s.dataSaver.avatar) return getStaticImageUrl(decoration.url);
return decoration.url;
}
function getDecorationAngle(decoration: Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'>) {
function getDecorationAngle(decoration: Decoration | DecorationEditorDecoration) {
const angle = decoration.angle ?? 0;
return angle === 0 ? undefined : `${angle * 360}deg`;
}
function getDecorationScale(decoration: Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'>) {
function getDecorationScale(decoration: Decoration | DecorationEditorDecoration) {
const scaleX = decoration.flipH ? -1 : 1;
return scaleX === 1 ? undefined : `${scaleX} 1`;
}
function getDecorationOffset(decoration: Omit<Misskey.entities.UserDetailed['avatarDecorations'][number], 'id'>) {
function getDecorationOffset(decoration: Decoration | DecorationEditorDecoration) {
const offsetX = decoration.offsetX ?? 0;
const offsetY = decoration.offsetY ?? 0;
return offsetX === 0 && offsetY === 0 ? undefined : `${offsetX * 100}% ${offsetY * 100}%`;
}
function getDecorationIsBrink(decoration: Decoration | DecorationEditorDecoration) {
return 'blink' in decoration && decoration.blink === true;
}
const color = ref<string | undefined>();
watch(() => props.user.avatarBlurhash, () => {

View File

@ -122,7 +122,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<SearchMarker>
<MkFolder :defaultOpen="true">
<template #icon><SearchIcon><i class="ti ti-bolt"></i></SearchIcon></template>
<template #label><SearchLabel>Misskey® Reactions Boost Technology (RBT)</SearchLabel><span class="_beta">{{ i18n.ts.beta }}</span></template>
<template #label><SearchLabel>Misskey® Reactions Boost Technology (RBT)</SearchLabel></template>
<template v-if="rbtForm.savedState.enableReactionsBuffering" #suffix>Enabled</template>
<template v-else #suffix>Disabled</template>
<template v-if="rbtForm.modified.value" #footer>

View File

@ -193,7 +193,7 @@ function start() {
}
function getIsLegacy(version: string | null): boolean {
if (version == null) return false;
if (version == null) return true;
try {
return compareVersions(version, '1.0.0') < 0;
} catch {
@ -206,7 +206,7 @@ async function run() {
if (!flash.value) return;
const version = utils.getLangVersion(flash.value.script);
const isLegacy = version != null && getIsLegacy(version);
const isLegacy = getIsLegacy(version);
const { Interpreter, Parser, values } = isLegacy ? (await import('@syuilo/aiscript-0-19-0') as any) : await import('@syuilo/aiscript');

View File

@ -90,7 +90,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<SearchMarker :keywords="['lockdown']">
<FormSection>
<template #label><SearchLabel>{{ i18n.ts.lockdown }}</SearchLabel><span class="_beta">{{ i18n.ts.beta }}</span></template>
<template #label><SearchLabel>{{ i18n.ts.lockdown }}</SearchLabel></template>
<div class="_gaps_m">
<SearchMarker :keywords="['login', 'signin']">
@ -213,9 +213,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref, computed, watch } from 'vue';
import type { MkSelectItem } from '@/components/MkSelect.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkSelect from '@/components/MkSelect.vue';
import type { MkSelectItem } from '@/components/MkSelect.vue';
import FormSection from '@/components/form/section.vue';
import { misskeyApi } from '@/utility/misskey-api.js';
import { i18n } from '@/i18n.js';

View File

@ -107,7 +107,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<SearchMarker :keywords="['follow', 'message']">
<MkInput v-model="profile.followedMessage" :max="200" manualSave :mfmPreview="false">
<template #label><SearchLabel>{{ i18n.ts._profile.followedMessage }}</SearchLabel><span class="_beta">{{ i18n.ts.beta }}</span></template>
<template #label><SearchLabel>{{ i18n.ts._profile.followedMessage }}</SearchLabel></template>
<template #caption>
<div><SearchText>{{ i18n.ts._profile.followedMessageDescription }}</SearchText></div>
<div>{{ i18n.ts._profile.followedMessageDescriptionForLockedAccount }}</div>

View File

@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<SearchMarker :keywords="['signin', 'login', 'history', 'log']">
<FormSection>
<template #label><SearchLabel>{{ i18n.ts.signinHistory }}</SearchLabel></template>
<MkPagination :paginator="paginator" withControl>
<MkPagination :paginator="paginator" withControl :forceDisableInfiniteScroll="true">
<template #default="{items}">
<div>
<div v-for="item in items" :key="item.id" v-panel class="timnmucd">

View File

@ -257,20 +257,23 @@ export class PreferencesManager extends EventEmitter<PreferencesManagerEvents> {
this.rewriteRawState(key, v);
const record = this.getMatchedRecordOf(key);
const _save = () => {
this.save();
this.emit('committed', {
key,
value: v,
oldValue: this.s[key],
});
const record = this.getMatchedRecordOf(key);
};
if (parseScope(record[0]).account == null && isAccountDependentKey(key) && currentAccount != null) {
this.profile.preferences[key].push([makeScope({
server: host,
account: currentAccount.id,
}), v, {}]);
this.save();
_save();
return;
}
@ -278,12 +281,12 @@ export class PreferencesManager extends EventEmitter<PreferencesManagerEvents> {
this.profile.preferences[key].push([makeScope({
server: host,
}), v, {}]);
this.save();
_save();
return;
}
record[1] = v;
this.save();
_save();
if (record[2].sync) {
// awaitの必要なし

View File

@ -12,6 +12,7 @@ export const TIPS = [
'clips',
'userLists',
'postForm',
'deck',
'tl.home',
'tl.local',
'tl.social',

View File

@ -14,6 +14,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<i v-if="store.r.realtimeMode.value" class="ti ti-bolt ti-fw"></i>
<i v-else class="ti ti-bolt-off ti-fw"></i>
</button>
<button v-if="!iconOnly && showWidgetButton" v-tooltip.noDelay.right="i18n.ts.widgets" class="_button" :class="[$style.widget]" @click="() => emit('widgetButtonClick')">
<i class="ti ti-apps ti-fw"></i>
</button>
</div>
<div :class="$style.middle">
<MkA v-tooltip.noDelay.right="i18n.ts.timeline" :class="$style.item" :activeClass="$style.active" to="/" exact>
@ -51,7 +54,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkA>
</div>
<div :class="$style.bottom">
<button v-if="showWidgetButton" v-tooltip.noDelay.right="i18n.ts.widgets" class="_button" :class="[$style.widget]" @click="() => emit('widgetButtonClick')">
<button v-if="iconOnly && showWidgetButton" v-tooltip.noDelay.right="i18n.ts.widgets" class="_button" :class="[$style.widget]" @click="() => emit('widgetButtonClick')">
<i class="ti ti-apps ti-fw"></i>
</button>
<button v-if="iconOnly" v-tooltip.noDelay.right="i18n.ts.realtimeMode" class="_button" :class="[$style.realtimeMode, store.r.realtimeMode.value ? $style.on : null]" @click="toggleRealtimeMode">
@ -436,6 +439,12 @@ function menuEdit() {
}
}
.widget {
display: inline-block;
width: var(--top-height);
margin-left: auto;
}
.bottom {
position: sticky;
bottom: 0;

View File

@ -38,36 +38,39 @@ SPDX-License-Identifier: AGPL-3.0-only
@headerWheel="onWheel"
/>
</section>
<div v-if="layout.length === 0" class="_panel" :class="$style.onboarding">
<div v-if="layout.length === 0" class="_panel _gaps" :class="$style.onboarding">
<div>{{ i18n.ts._deck.introduction }}</div>
<div>{{ i18n.ts._deck.introduction2 }}</div>
<MkInfo v-if="!store.r.tips.value.deck" closable @close="closeTip('deck')">
<button class="_textButton" @click="showTour">{{ i18n.ts._deck.showHowToUse }}</button>
</MkInfo>
</div>
</div>
<div v-if="prefer.r['deck.menuPosition'].value === 'right'" :class="$style.sideMenu">
<div :class="$style.sideMenuTop">
<button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.sideMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
<button ref="swicthProfileButtonEl" v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.sideMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
<button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.sideMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
</div>
<div :class="$style.sideMenuMiddle">
<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
<button ref="addColumnButtonEl" v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
</div>
<div :class="$style.sideMenuBottom">
<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
<button ref="settingsButtonEl" v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
</div>
</div>
</div>
<div v-if="prefer.r['deck.menuPosition'].value === 'bottom'" :class="$style.bottomMenu">
<div :class="$style.bottomMenuLeft">
<button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.bottomMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
<button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.bottomMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
<button ref="swicthProfileButtonEl" v-tooltip.noDelay.top="`${i18n.ts._deck.profile}: ${prefer.s['deck.profile']}`" :class="$style.bottomMenuButton" class="_button" @click="switchProfileMenu"><i class="ti ti-caret-down"></i></button>
<button v-tooltip.noDelay.top="i18n.ts._deck.deleteProfile" :class="$style.bottomMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
</div>
<div :class="$style.bottomMenuMiddle">
<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.bottomMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
<button ref="addColumnButtonEl" v-tooltip.noDelay.top="i18n.ts._deck.addColumn" :class="$style.bottomMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
</div>
<div :class="$style.bottomMenuRight">
<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.bottomMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
<button ref="settingsButtonEl" v-tooltip.noDelay.top="i18n.ts.settings" :class="$style.bottomMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings-2"></i></button>
</div>
</div>
@ -96,6 +99,7 @@ import { $i } from '@/i.js';
import { i18n } from '@/i18n.js';
import { deviceKind } from '@/utility/device-kind.js';
import { prefer } from '@/preferences.js';
import { store } from '@/store.js';
import XMainColumn from '@/ui/deck/main-column.vue';
import XTlColumn from '@/ui/deck/tl-column.vue';
import XAntennaColumn from '@/ui/deck/antenna-column.vue';
@ -107,10 +111,13 @@ import XMentionsColumn from '@/ui/deck/mentions-column.vue';
import XDirectColumn from '@/ui/deck/direct-column.vue';
import XRoleTimelineColumn from '@/ui/deck/role-timeline-column.vue';
import XChatColumn from '@/ui/deck/chat-column.vue';
import MkInfo from '@/components/MkInfo.vue';
import { mainRouter } from '@/router.js';
import { columns, layout, columnTypes, switchProfileMenu, addColumn as addColumnToStore, deleteProfile as deleteProfile_ } from '@/deck.js';
import { shouldSuggestRestoreBackup } from '@/preferences/utility.js';
import { shouldSuggestReload } from '@/utility/reload-suggest.js';
import { startTour } from '@/utility/tour.js';
import { closeTip } from '@/tips.js';
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
const XAnnouncements = defineAsyncComponent(() => import('@/ui/_common_/announcements.vue'));
@ -163,6 +170,9 @@ function showSettings() {
}
const columnsEl = useTemplateRef('columnsEl');
const addColumnButtonEl = useTemplateRef('addColumnButtonEl');
const settingsButtonEl = useTemplateRef('settingsButtonEl');
const swicthProfileButtonEl = useTemplateRef('swicthProfileButtonEl');
const addColumn = async (ev) => {
const { canceled, result: column } = await os.select({
@ -218,6 +228,30 @@ async function deleteProfile() {
os.success();
}
function showTour() {
if (addColumnButtonEl.value == null ||
settingsButtonEl.value == null ||
swicthProfileButtonEl.value == null) {
return;
}
startTour([{
element: addColumnButtonEl.value,
title: i18n.ts._deck._howToUse.addColumn_title,
description: i18n.ts._deck._howToUse.addColumn_description,
}, {
element: settingsButtonEl.value,
title: i18n.ts._deck._howToUse.settings_title,
description: i18n.ts._deck._howToUse.settings_description,
}, {
element: swicthProfileButtonEl.value,
title: i18n.ts._deck._howToUse.switchProfile_title,
description: i18n.ts._deck._howToUse.switchProfile_description,
}]).then(() => {
closeTip('deck');
});
}
window.document.documentElement.style.overflowY = 'hidden';
window.document.documentElement.style.scrollBehavior = 'auto';
</script>
@ -345,7 +379,7 @@ window.document.documentElement.style.scrollBehavior = 'auto';
}
.bottomMenuButton {
display: block;
display: inline-block;
height: 100%;
aspect-ratio: 1;
}

View File

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<XTitlebar v-if="prefer.r.showTitlebar.value" style="flex-shrink: 0;"/>
<div :class="$style.nonTitlebarArea">
<XSidebar v-if="!isMobile" :class="$style.sidebar" :showWidgetButton="!isDesktop" @widgetButtonClick="widgetsShowing = true"/>
<XSidebar v-if="!isMobile" :class="$style.sidebar" :showWidgetButton="!showWidgetsSide" @widgetButtonClick="widgetsShowing = true"/>
<div :class="[$style.contents, !isMobile && prefer.r.showTitlebar.value ? $style.withSidebarAndTitlebar : null]" @contextmenu.stop="onContextmenu">
<div>
@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<XMobileFooterMenu v-if="isMobile" ref="navFooter" v-model:drawerMenuShowing="drawerMenuShowing" v-model:widgetsShowing="widgetsShowing"/>
</div>
<div v-if="isDesktop && !pageMetadata?.needWideArea" :class="$style.widgets">
<div v-if="showWidgetsSide && !pageMetadata?.needWideArea" :class="$style.widgets">
<XWidgets/>
</div>
</div>
@ -64,7 +64,8 @@ const DESKTOP_THRESHOLD = 1100;
const MOBILE_THRESHOLD = 500;
// UI deviceKind === 'desktop'
const isDesktop = ref(window.innerWidth >= DESKTOP_THRESHOLD);
const showWidgetsSide = window.innerWidth >= DESKTOP_THRESHOLD;
const isMobile = ref(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD);
window.addEventListener('resize', () => {
isMobile.value = deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD;
@ -102,14 +103,6 @@ if (window.innerWidth > 1024) {
}
}
onMounted(() => {
if (!isDesktop.value) {
window.addEventListener('resize', () => {
if (window.innerWidth >= DESKTOP_THRESHOLD) isDesktop.value = true;
}, { passive: true });
}
});
const onContextmenu = (ev) => {
if (isLink(ev.target)) return;
if (['INPUT', 'TEXTAREA', 'IMG', 'VIDEO', 'CANVAS'].includes(ev.target.tagName) || ev.target.attributes['contenteditable']) return;

View File

@ -29,14 +29,14 @@
],
"devDependencies": {
"@types/js-yaml": "4.0.9",
"@types/node": "24.10.1",
"@typescript-eslint/eslint-plugin": "8.47.0",
"@typescript-eslint/parser": "8.47.0",
"chokidar": "4.0.3",
"esbuild": "0.27.0",
"execa": "9.6.0",
"@types/node": "24.10.2",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"chokidar": "5.0.0",
"esbuild": "0.27.1",
"execa": "9.6.1",
"nodemon": "3.1.11",
"tsx": "4.20.6",
"tsx": "4.21.0",
"typescript": "5.9.3"
},
"dependencies": {

View File

@ -10936,6 +10936,36 @@ export interface Locale extends ILocale {
*
*/
"enableSyncBetweenDevicesForProfiles": string;
/**
* UIの説明を見る
*/
"showHowToUse": string;
"_howToUse": {
/**
*
*/
"addColumn_title": string;
/**
*
*/
"addColumn_description": string;
/**
* UI設定
*/
"settings_title": string;
/**
* UIの詳細設定を行えます
*/
"settings_description": string;
/**
*
*/
"switchProfile_title": string;
/**
* UIのレイアウトをプロファイルとして保存し
*/
"switchProfile_description": string;
};
"_columns": {
/**
*

View File

@ -11,15 +11,15 @@
"lint": "pnpm typecheck && pnpm eslint"
},
"devDependencies": {
"@types/node": "24.10.1",
"@types/node": "24.10.2",
"@types/wawoff2": "1.0.2",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0"
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0"
},
"dependencies": {
"@tabler/icons-webfont": "3.35.0",
"harfbuzzjs": "0.4.13",
"tsx": "4.20.6",
"tsx": "4.21.0",
"typescript": "5.9.3",
"wawoff2": "2.0.1"
},

View File

@ -25,12 +25,12 @@
},
"devDependencies": {
"@types/matter-js": "0.20.2",
"@types/node": "24.10.1",
"@types/node": "24.10.2",
"@types/seedrandom": "3.0.8",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0",
"esbuild": "0.27.0",
"execa": "9.6.0",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"esbuild": "0.27.1",
"execa": "9.6.1",
"nodemon": "3.1.11",
"typescript": "5.9.3"
},

View File

@ -8,13 +8,13 @@
},
"devDependencies": {
"@readme/openapi-parser": "5.2.1",
"@types/node": "24.10.1",
"@typescript-eslint/eslint-plugin": "8.47.0",
"@typescript-eslint/parser": "8.47.0",
"@types/node": "24.10.2",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"openapi-types": "12.1.3",
"openapi-typescript": "7.10.1",
"ts-case-convert": "2.1.0",
"tsx": "4.20.6",
"tsx": "4.21.0",
"typescript": "5.9.3",
"eslint": "9.39.1"
},

View File

@ -1,7 +1,7 @@
{
"type": "module",
"name": "misskey-js",
"version": "2025.12.1-alpha.1",
"version": "2025.12.2-beta.2",
"description": "Misskey SDK for JavaScript",
"license": "MIT",
"main": "./built/index.js",
@ -37,18 +37,18 @@
"directory": "packages/misskey-js"
},
"devDependencies": {
"@microsoft/api-extractor": "7.55.1",
"@types/node": "24.10.1",
"@typescript-eslint/eslint-plugin": "8.47.0",
"@typescript-eslint/parser": "8.47.0",
"@vitest/coverage-v8": "4.0.13",
"esbuild": "0.27.0",
"execa": "9.6.0",
"@microsoft/api-extractor": "7.55.2",
"@types/node": "24.10.2",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"@vitest/coverage-v8": "4.0.15",
"esbuild": "0.27.1",
"execa": "9.6.1",
"ncp": "2.0.0",
"nodemon": "3.1.11",
"tsd": "0.33.0",
"typescript": "5.9.3",
"vitest": "4.0.13",
"vitest": "4.0.15",
"vitest-websocket-mock": "0.5.0"
},
"files": [

View File

@ -24,11 +24,11 @@
"lint": "pnpm typecheck && pnpm eslint"
},
"devDependencies": {
"@types/node": "24.10.1",
"@typescript-eslint/eslint-plugin": "8.48.0",
"@typescript-eslint/parser": "8.48.0",
"esbuild": "0.27.0",
"execa": "9.6.0",
"@types/node": "24.10.2",
"@typescript-eslint/eslint-plugin": "8.49.0",
"@typescript-eslint/parser": "8.49.0",
"esbuild": "0.27.1",
"execa": "9.6.1",
"nodemon": "3.1.11",
"typescript": "5.9.3"
},

View File

@ -10,12 +10,12 @@
},
"dependencies": {
"i18n": "workspace:*",
"esbuild": "0.27.0",
"esbuild": "0.27.1",
"idb-keyval": "6.2.2",
"misskey-js": "workspace:*"
},
"devDependencies": {
"@typescript-eslint/parser": "8.48.0",
"@typescript-eslint/parser": "8.49.0",
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.74",
"eslint-plugin-import": "2.32.0",
"nodemon": "3.1.11",

File diff suppressed because it is too large Load Diff

View File

@ -35,3 +35,4 @@ ignorePatchFailures: false
minimumReleaseAge: 10080 # delay 7days to mitigate supply-chain attack
minimumReleaseAgeExclude:
- '@syuilo/aiscript'
- systeminformation # 脆弱性対応。そのうち消すこと

View File

@ -9,16 +9,16 @@
"version": "1.0.0",
"devDependencies": {
"@types/mdast": "4.0.4",
"@types/node": "24.10.1",
"@vitest/coverage-v8": "4.0.14",
"@types/node": "24.10.2",
"@vitest/coverage-v8": "4.0.15",
"mdast-util-to-string": "4.0.0",
"remark": "15.0.1",
"remark-parse": "11.0.0",
"typescript": "5.9.3",
"unified": "11.0.5",
"vite": "7.2.4",
"vite": "7.2.7",
"vite-node": "5.2.0",
"vitest": "4.0.14"
"vitest": "4.0.15"
}
},
"node_modules/@babel/helper-string-parser": {
@ -842,20 +842,21 @@
]
},
"node_modules/@standard-schema/spec": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/chai": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
"integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
"integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/deep-eql": "*"
"@types/deep-eql": "*",
"assertion-error": "^2.0.1"
}
},
"node_modules/@types/debug": {
@ -898,12 +899,11 @@
"dev": true
},
"node_modules/@types/node": {
"version": "24.10.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
"integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
"version": "24.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.2.tgz",
"integrity": "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@ -915,14 +915,14 @@
"dev": true
},
"node_modules/@vitest/coverage-v8": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.14.tgz",
"integrity": "sha512-EYHLqN/BY6b47qHH7gtMxAg++saoGmsjWmAq9MlXxAz4M0NcHh9iOyKhBZyU4yxZqOd8Xnqp80/5saeitz4Cng==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.15.tgz",
"integrity": "sha512-FUJ+1RkpTFW7rQITdgTi93qOCWJobWhBirEPCeXh2SW2wsTlFxy51apDz5gzG+ZEYt/THvWeNmhdAoS9DTwpCw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@bcoe/v8-coverage": "^1.0.2",
"@vitest/utils": "4.0.14",
"@vitest/utils": "4.0.15",
"ast-v8-to-istanbul": "^0.3.8",
"istanbul-lib-coverage": "^3.2.2",
"istanbul-lib-report": "^3.0.1",
@ -937,8 +937,8 @@
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
"@vitest/browser": "4.0.14",
"vitest": "4.0.14"
"@vitest/browser": "4.0.15",
"vitest": "4.0.15"
},
"peerDependenciesMeta": {
"@vitest/browser": {
@ -947,16 +947,16 @@
}
},
"node_modules/@vitest/expect": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.14.tgz",
"integrity": "sha512-RHk63V3zvRiYOWAV0rGEBRO820ce17hz7cI2kDmEdfQsBjT2luEKB5tCOc91u1oSQoUOZkSv3ZyzkdkSLD7lKw==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.15.tgz",
"integrity": "sha512-Gfyva9/GxPAWXIWjyGDli9O+waHDC0Q0jaLdFP1qPAUUfo1FEXPXUfUkp3eZA0sSq340vPycSyOlYUeM15Ft1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.0.0",
"@types/chai": "^5.2.2",
"@vitest/spy": "4.0.14",
"@vitest/utils": "4.0.14",
"@vitest/spy": "4.0.15",
"@vitest/utils": "4.0.15",
"chai": "^6.2.1",
"tinyrainbow": "^3.0.3"
},
@ -965,13 +965,13 @@
}
},
"node_modules/@vitest/mocker": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.14.tgz",
"integrity": "sha512-RzS5NujlCzeRPF1MK7MXLiEFpkIXeMdQ+rN3Kk3tDI9j0mtbr7Nmuq67tpkOJQpgyClbOltCXMjLZicJHsH5Cg==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.15.tgz",
"integrity": "sha512-CZ28GLfOEIFkvCFngN8Sfx5h+Se0zN+h4B7yOsPVCcgtiO7t5jt9xQh2E1UkFep+eb9fjyMfuC5gBypwb07fvQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "4.0.14",
"@vitest/spy": "4.0.15",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.21"
},
@ -992,9 +992,9 @@
}
},
"node_modules/@vitest/pretty-format": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.14.tgz",
"integrity": "sha512-SOYPgujB6TITcJxgd3wmsLl+wZv+fy3av2PpiPpsWPZ6J1ySUYfScfpIt2Yv56ShJXR2MOA6q2KjKHN4EpdyRQ==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.15.tgz",
"integrity": "sha512-SWdqR8vEv83WtZcrfLNqlqeQXlQLh2iilO1Wk1gv4eiHKjEzvgHb2OVc3mIPyhZE6F+CtfYjNlDJwP5MN6Km7A==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1005,13 +1005,13 @@
}
},
"node_modules/@vitest/runner": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.14.tgz",
"integrity": "sha512-BsAIk3FAqxICqREbX8SetIteT8PiaUL/tgJjmhxJhCsigmzzH8xeadtp7LRnTpCVzvf0ib9BgAfKJHuhNllKLw==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.15.tgz",
"integrity": "sha512-+A+yMY8dGixUhHmNdPUxOh0la6uVzun86vAbuMT3hIDxMrAOmn5ILBHm8ajrqHE0t8R9T1dGnde1A5DTnmi3qw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/utils": "4.0.14",
"@vitest/utils": "4.0.15",
"pathe": "^2.0.3"
},
"funding": {
@ -1019,13 +1019,13 @@
}
},
"node_modules/@vitest/snapshot": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.14.tgz",
"integrity": "sha512-aQVBfT1PMzDSA16Y3Fp45a0q8nKexx6N5Amw3MX55BeTeZpoC08fGqEZqVmPcqN0ueZsuUQ9rriPMhZ3Mu19Ag==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.15.tgz",
"integrity": "sha512-A7Ob8EdFZJIBjLjeO0DZF4lqR6U7Ydi5/5LIZ0xcI+23lYlsYJAfGn8PrIWTYdZQRNnSRlzhg0zyGu37mVdy5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "4.0.14",
"@vitest/pretty-format": "4.0.15",
"magic-string": "^0.30.21",
"pathe": "^2.0.3"
},
@ -1034,9 +1034,9 @@
}
},
"node_modules/@vitest/spy": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.14.tgz",
"integrity": "sha512-JmAZT1UtZooO0tpY3GRyiC/8W7dCs05UOq9rfsUUgEZEdq+DuHLmWhPsrTt0TiW7WYeL/hXpaE07AZ2RCk44hg==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.15.tgz",
"integrity": "sha512-+EIjOJmnY6mIfdXtE/bnozKEvTC4Uczg19yeZ2vtCz5Yyb0QQ31QWVQ8hswJ3Ysx/K2EqaNsVanjr//2+P3FHw==",
"dev": true,
"license": "MIT",
"funding": {
@ -1044,19 +1044,29 @@
}
},
"node_modules/@vitest/utils": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.14.tgz",
"integrity": "sha512-hLqXZKAWNg8pI+SQXyXxWCTOpA3MvsqcbVeNgSi8x/CSN2wi26dSzn1wrOhmCmFjEvN9p8/kLFRHa6PI8jHazw==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.15.tgz",
"integrity": "sha512-HXjPW2w5dxhTD0dLwtYHDnelK3j8sR8cWIaLxr22evTyY6q8pRCjZSmhRWVjBaOVXChQd6AwMzi9pucorXCPZA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "4.0.14",
"@vitest/pretty-format": "4.0.15",
"tinyrainbow": "^3.0.3"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/assertion-error": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
"integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/ast-v8-to-istanbul": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.8.tgz",
@ -1220,9 +1230,9 @@
}
},
"node_modules/expect-type": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz",
"integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
"integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@ -1983,7 +1993,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@ -2128,7 +2137,8 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
"integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
"dev": true
"dev": true,
"license": "ISC"
},
"node_modules/source-map-js": {
"version": "1.2.1",
@ -2143,7 +2153,8 @@
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
"integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
"dev": true
"dev": true,
"license": "MIT"
},
"node_modules/std-env": {
"version": "3.10.0",
@ -2172,11 +2183,14 @@
"license": "MIT"
},
"node_modules/tinyexec": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
"integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
"integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
"dev": true,
"license": "MIT"
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/tinyglobby": {
"version": "0.2.15",
@ -2341,9 +2355,9 @@
}
},
"node_modules/vite": {
"version": "7.2.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz",
"integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
"version": "7.2.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.7.tgz",
"integrity": "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2439,20 +2453,19 @@
}
},
"node_modules/vitest": {
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.14.tgz",
"integrity": "sha512-d9B2J9Cm9dN9+6nxMnnNJKJCtcyKfnHj15N6YNJfaFHRLua/d3sRKU9RuKmO9mB0XdFtUizlxfz/VPbd3OxGhw==",
"version": "4.0.15",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.15.tgz",
"integrity": "sha512-n1RxDp8UJm6N0IbJLQo+yzLZ2sQCDyl1o0LeugbPWf8+8Fttp29GghsQBjYJVmWq3gBFfe9Hs1spR44vovn2wA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vitest/expect": "4.0.14",
"@vitest/mocker": "4.0.14",
"@vitest/pretty-format": "4.0.14",
"@vitest/runner": "4.0.14",
"@vitest/snapshot": "4.0.14",
"@vitest/spy": "4.0.14",
"@vitest/utils": "4.0.14",
"@vitest/expect": "4.0.15",
"@vitest/mocker": "4.0.15",
"@vitest/pretty-format": "4.0.15",
"@vitest/runner": "4.0.15",
"@vitest/snapshot": "4.0.15",
"@vitest/spy": "4.0.15",
"@vitest/utils": "4.0.15",
"es-module-lexer": "^1.7.0",
"expect-type": "^1.2.2",
"magic-string": "^0.30.21",
@ -2461,7 +2474,7 @@
"picomatch": "^4.0.3",
"std-env": "^3.10.0",
"tinybench": "^2.9.0",
"tinyexec": "^0.3.2",
"tinyexec": "^1.0.2",
"tinyglobby": "^0.2.15",
"tinyrainbow": "^3.0.3",
"vite": "^6.0.0 || ^7.0.0",
@ -2480,10 +2493,10 @@
"@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
"@vitest/browser-playwright": "4.0.14",
"@vitest/browser-preview": "4.0.14",
"@vitest/browser-webdriverio": "4.0.14",
"@vitest/ui": "4.0.14",
"@vitest/browser-playwright": "4.0.15",
"@vitest/browser-preview": "4.0.15",
"@vitest/browser-webdriverio": "4.0.15",
"@vitest/ui": "4.0.15",
"happy-dom": "*",
"jsdom": "*"
},

View File

@ -10,15 +10,15 @@
},
"devDependencies": {
"@types/mdast": "4.0.4",
"@types/node": "24.10.1",
"@vitest/coverage-v8": "4.0.14",
"@types/node": "24.10.2",
"@vitest/coverage-v8": "4.0.15",
"mdast-util-to-string": "4.0.0",
"remark": "15.0.1",
"remark-parse": "11.0.0",
"typescript": "5.9.3",
"unified": "11.0.5",
"vite": "7.2.4",
"vite": "7.2.7",
"vite-node": "5.2.0",
"vitest": "4.0.14"
"vitest": "4.0.15"
}
}