Compare commits

...

9 Commits

Author SHA1 Message Date
かっこかり 10da789e82
Merge e10d3d15c3 into 5e2b041f84 2026-01-28 23:43:58 +09:00
kakkokari-gtyih e10d3d15c3 Merge branch 'develop' into enh-remove-v-code-diff 2026-01-24 02:46:33 +09:00
kakkokari-gtyih 54f76a767f fix 2026-01-22 10:38:09 +09:00
kakkokari-gtyih 3e4cc32e51 refactor: split mkcodediff to isolate concerns 2026-01-22 10:36:57 +09:00
kakkokari-gtyih 327f41bace Merge remote-tracking branch 'msky/develop' into enh-remove-v-code-diff 2026-01-22 10:32:53 +09:00
kakkokari-gtyih 67b88808db fix(deps): resolve version mismatch in shiki 2026-01-22 10:09:23 +09:00
kakkokari-gtyih 020e75feb5 remove v-code-diff 2026-01-22 10:06:10 +09:00
kakkokari-gtyih 6a151cdd80 run pnpm dedupe 2026-01-21 21:42:02 +09:00
kakkokari-gtyih 3f5240a254 enhance(frontend): remove v-code-diff 2026-01-21 21:41:51 +09:00
8 changed files with 272 additions and 110 deletions

View File

@ -25,6 +25,7 @@
"@rollup/plugin-replace": "6.0.3", "@rollup/plugin-replace": "6.0.3",
"@rollup/pluginutils": "5.3.0", "@rollup/pluginutils": "5.3.0",
"@sentry/vue": "10.34.0", "@sentry/vue": "10.34.0",
"@shikijs/transformers": "3.21.0",
"@syuilo/aiscript": "1.2.1", "@syuilo/aiscript": "1.2.1",
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0", "@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
"@twemoji/parser": "16.0.0", "@twemoji/parser": "16.0.0",
@ -43,6 +44,7 @@
"compare-versions": "6.1.1", "compare-versions": "6.1.1",
"cropperjs": "2.1.0", "cropperjs": "2.1.0",
"date-fns": "4.1.0", "date-fns": "4.1.0",
"diff": "8.0.3",
"eventemitter3": "5.0.1", "eventemitter3": "5.0.1",
"execa": "9.6.1", "execa": "9.6.1",
"exifreader": "4.36.0", "exifreader": "4.36.0",
@ -72,7 +74,6 @@
"three": "0.182.0", "three": "0.182.0",
"throttle-debounce": "5.0.2", "throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",
"v-code-diff": "1.13.1",
"vite": "7.3.1", "vite": "7.3.1",
"vue": "3.5.26", "vue": "3.5.26",
"wanakana": "5.3.1" "wanakana": "5.3.1"

View File

@ -9,29 +9,40 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="[$style.codeBlockRoot, { :class="[$style.codeBlockRoot, {
[$style.codeEditor]: codeEditor, [$style.codeEditor]: codeEditor,
[$style.outerStyle]: !codeEditor && withOuterStyle, [$style.outerStyle]: !codeEditor && withOuterStyle,
[$style.withMaxHeight]: maxHeight != null,
[$style.dark]: darkMode, [$style.dark]: darkMode,
[$style.light]: !darkMode, [$style.light]: !darkMode,
}]" v-html="html"></div> }]" v-html="html"></div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref, watch } from 'vue'; import { computed, ref, shallowRef, watch } from 'vue';
import { bundledLanguagesInfo } from 'shiki/langs'; import { bundledLanguagesInfo } from 'shiki/langs';
import type { transformerNotationDiff as transformerNotationDiff_typeReferenceOnly } from '@shikijs/transformers';
import type { diffLines as diffLines_typeReferenceOnly } from 'diff';
import type { BundledLanguage } from 'shiki/langs'; import type { BundledLanguage } from 'shiki/langs';
import { getHighlighter, getTheme } from '@/utility/code-highlighter.js'; import { getHighlighter, getTheme } from '@/utility/code-highlighter.js';
import { store } from '@/store.js'; import { store } from '@/store.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
code: string; code: string;
diffBase?: string;
lang?: string; lang?: string;
codeEditor?: boolean; codeEditor?: boolean;
withOuterStyle?: boolean; withOuterStyle?: boolean;
maxHeight?: number | null;
}>(), { }>(), {
codeEditor: false, codeEditor: false,
withOuterStyle: true, withOuterStyle: true,
maxHeight: null,
}); });
const maxHeight = computed(() => props.maxHeight != null ? `${props.maxHeight}px` : null);
const highlighter = await getHighlighter(); const highlighter = await getHighlighter();
const transformerNotationDiff = shallowRef<typeof transformerNotationDiff_typeReferenceOnly | null>(null);
const diffLines = shallowRef<typeof diffLines_typeReferenceOnly | null>(null);
const darkMode = store.r.darkMode; const darkMode = store.r.darkMode;
const codeLang = ref<BundledLanguage | 'aiscript'>('js'); const codeLang = ref<BundledLanguage | 'aiscript'>('js');
@ -40,13 +51,34 @@ const [lightThemeName, darkThemeName] = await Promise.all([
getTheme('dark', true), getTheme('dark', true),
]); ]);
const html = computed(() => highlighter.codeToHtml(props.code, { const code = computed(() => {
if (props.diffBase != null && diffLines.value != null) {
const diffedLines = diffLines.value(props.diffBase, props.code);
const diffed = diffedLines.map((part) => {
if (part.added) {
return part.value.split('\n').map(line => line ? `${line} // [!code ++]` : line).join('\n');
} else if (part.removed) {
return part.value.split('\n').map(line => line ? `${line} // [!code --]` : line).join('\n');
} else {
return part.value;
}
}).join('');
return diffed;
} else {
return props.code;
}
});
const html = computed(() => highlighter.codeToHtml(code.value, {
lang: codeLang.value, lang: codeLang.value,
themes: { themes: {
fallback: 'dark-plus', fallback: 'dark-plus',
light: lightThemeName, light: lightThemeName,
dark: darkThemeName, dark: darkThemeName,
}, },
transformers: props.diffBase != null && transformerNotationDiff.value != null
? [transformerNotationDiff.value({})]
: [],
defaultColor: false, defaultColor: false,
cssVariablePrefix: '--shiki-', cssVariablePrefix: '--shiki-',
})); }));
@ -73,6 +105,19 @@ async function fetchLanguage(to: string): Promise<void> {
} }
} }
watch(() => props.diffBase, async (to) => {
if (to != null) {
if (transformerNotationDiff.value == null) {
const { transformerNotationDiff: tf } = await import('@shikijs/transformers');
transformerNotationDiff.value = tf;
}
if (diffLines.value == null) {
const { diffLines: dl } = await import('diff');
diffLines.value = dl;
}
}
}, { immediate: true });
watch(() => props.lang, (to) => { watch(() => props.lang, (to) => {
if (codeLang.value === to || !to) return; if (codeLang.value === to || !to) return;
return new Promise((resolve) => { return new Promise((resolve) => {
@ -96,6 +141,33 @@ watch(() => props.lang, (to) => {
& code { & code {
font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
} }
&>code {
display: block;
min-width: fit-content;
}
& :global(.line) {
display: inline-block;
width: 100%;
}
}
.codeBlockRoot :global(.shiki.has-diff) {
& :global(.line.diff.remove) {
background-color: rgba(244, 63, 94, .14);
text-decoration: line-through;
}
& :global(.line.diff.add) {
background-color: rgba(75, 192, 107, .14);
}
}
.codeBlockRoot.withMaxHeight :global(.shiki) {
max-height: v-bind(maxHeight);
scrollbar-color: var(--MI_THEME-scrollbarHandle) transparent;
scrollbar-width: thin;
} }
.outerStyle.codeBlockRoot :global(.shiki) { .outerStyle.codeBlockRoot :global(.shiki) {

View File

@ -21,14 +21,17 @@ SPDX-License-Identifier: AGPL-3.0-only
v-if="show && lang" v-if="show && lang"
class="_selectable" class="_selectable"
:code="code" :code="code"
:diffBase="diffBase"
:lang="lang" :lang="lang"
:withOuterStyle="withOuterStyle" :withOuterStyle="withOuterStyle"
:maxHeight="props.maxHeight"
/> />
<pre <pre
v-else-if="show" v-else-if="show"
class="_selectable" class="_selectable"
:class="[$style.codeBlockFallbackRoot, { :class="[$style.codeBlockFallbackRoot, {
[$style.outerStyle]: withOuterStyle, [$style.outerStyle]: withOuterStyle,
[$style.withMaxHeight]: maxHeight != null,
}]" }]"
><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre> ><code :class="$style.codeBlockFallbackCode">{{ code }}</code></pre>
<button v-else :class="$style.codePlaceholderRoot" @click="show = true"> <button v-else :class="$style.codePlaceholderRoot" @click="show = true">
@ -41,25 +44,33 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts">
import { defineAsyncComponent, ref } from 'vue'; export type MkCodeProps = {
import { i18n } from '@/i18n.js';
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
import { prefer } from '@/preferences.js';
const props = withDefaults(defineProps<{
code: string; code: string;
diffBase?: string;
forceShow?: boolean; forceShow?: boolean;
copyButton?: boolean; copyButton?: boolean;
withOuterStyle?: boolean; withOuterStyle?: boolean;
lang?: string; lang?: string;
}>(), { maxHeight?: number | null;
};
</script>
<script lang="ts" setup>
import { defineAsyncComponent, ref, computed } from 'vue';
import { i18n } from '@/i18n.js';
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
import { prefer } from '@/preferences.js';
const props = withDefaults(defineProps<MkCodeProps>(), {
copyButton: true, copyButton: true,
forceShow: false, forceShow: false,
withOuterStyle: true, withOuterStyle: true,
maxHeight: null,
}); });
const show = ref(props.forceShow === true ? true : !prefer.s.dataSaver.code); const show = ref(props.forceShow === true ? true : !prefer.s.dataSaver.code);
const maxHeight = computed(() => props.maxHeight != null ? `${props.maxHeight}px` : null);
const XCode = defineAsyncComponent(() => import('@/components/MkCode.core.vue')); const XCode = defineAsyncComponent(() => import('@/components/MkCode.core.vue'));
@ -94,6 +105,12 @@ function copy() {
display: block; display: block;
overflow-wrap: anywhere; overflow-wrap: anywhere;
overflow: auto; overflow: auto;
&.withMaxHeight {
scrollbar-color: var(--MI_THEME-scrollbarHandle) transparent;
scrollbar-width: thin;
max-height: v-bind(maxHeight);
}
} }
.outerStyle.codeBlockFallbackRoot { .outerStyle.codeBlockFallbackRoot {

View File

@ -0,0 +1,50 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import type { StoryObj } from '@storybook/vue3';
import MkCodeDiff from './MkCodeDiff.vue';
const code = `for (let i, 100) {
<: if (i % 15 == 0) "FizzBuzz"
elif (i % 3 == 0) "Fizz"
elif (i % 5 == 0) "Buzz"
else i
}`;
const diffBase = `for (let i, 100) {
<: if (i % 3 == 0) "Fizz"
elif (i % 5 == 0) "Buzz"
else i
}`;
export const Default = {
render(args) {
return {
components: {
MkCodeDiff,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkCodeDiff v-bind="props" />',
};
},
args: {
code,
diffBase,
lang: 'is',
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkCode>;

View File

@ -0,0 +1,14 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkCode v-bind="props" />
</template>
<script lang="ts" setup>
import MkCode from '@/components/MkCode.vue';
import type { MkCodeProps } from '@/components/MkCode.vue';
const props = defineProps<MkCodeProps & { diffBase: string }>();
</script>

View File

@ -131,22 +131,29 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkTime :time="log.createdAt"/> <MkTime :time="log.createdAt"/>
</template> </template>
<div> <div class="_gaps_s">
<div style="display: flex; gap: var(--MI-margin); flex-wrap: wrap;"> <div style="display: flex; gap: var(--MI-margin); flex-wrap: wrap;">
<div style="flex: 1;">{{ i18n.ts.moderator }}: <MkA :to="`/admin/user/${log.userId}`" class="_link">@{{ log.user?.username }}</MkA></div> <div style="flex: 1;">{{ i18n.ts.moderator }}: <MkA :to="`/admin/user/${log.userId}`" class="_link">@{{ log.user?.username }}</MkA></div>
<div style="flex: 1;">{{ i18n.ts.dateAndTime }}: <MkTime :time="log.createdAt" mode="detail"/></div> <div style="flex: 1;">{{ i18n.ts.dateAndTime }}: <MkTime :time="log.createdAt" mode="detail"/></div>
</div> </div>
<template v-if="log.type === 'updateServerSettings'"> <template v-if="log.type === 'updateServerSettings'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateUserNote'"> <template v-else-if="log.type === 'updateUserNote'">
<div>{{ i18n.ts.user }}: {{ log.info.userId }}</div> <div>{{ i18n.ts.user }}: {{ log.info.userId }}</div>
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="log.info.before ?? ''" :newString="log.info.after ?? ''" maxHeight="300px"/> forceShow
</div> :code="log.info.after ?? ''"
:diffBase="log.info.before ?? ''"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'suspend'"> <template v-else-if="log.type === 'suspend'">
<div>{{ i18n.ts.user }}: <MkA :to="`/admin/user/${log.info.userId}`" class="_link">@{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</MkA></div> <div>{{ i18n.ts.user }}: <MkA :to="`/admin/user/${log.info.userId}`" class="_link">@{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</MkA></div>
@ -155,9 +162,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<div>{{ i18n.ts.user }}: <MkA :to="`/admin/user/${log.info.userId}`" class="_link">@{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</MkA></div> <div>{{ i18n.ts.user }}: <MkA :to="`/admin/user/${log.info.userId}`" class="_link">@{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</MkA></div>
</template> </template>
<template v-else-if="log.type === 'updateRole'"> <template v-else-if="log.type === 'updateRole'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'assignRole'"> <template v-else-if="log.type === 'assignRole'">
<div>{{ i18n.ts.user }}: {{ log.info.userId }}</div> <div>{{ i18n.ts.user }}: {{ log.info.userId }}</div>
@ -169,54 +180,91 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<template v-else-if="log.type === 'updateCustomEmoji'"> <template v-else-if="log.type === 'updateCustomEmoji'">
<div>{{ i18n.ts.emoji }}: {{ log.info.emojiId }}</div> <div>{{ i18n.ts.emoji }}: {{ log.info.emojiId }}</div>
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateAd'"> <template v-else-if="log.type === 'updateAd'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateGlobalAnnouncement'"> <template v-else-if="log.type === 'updateGlobalAnnouncement'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateUserAnnouncement'"> <template v-else-if="log.type === 'updateUserAnnouncement'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateAvatarDecoration'"> <template v-else-if="log.type === 'updateAvatarDecoration'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateRemoteInstanceNote'"> <template v-else-if="log.type === 'updateRemoteInstanceNote'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="log.info.before ?? ''" :newString="log.info.after ?? ''" maxHeight="300px"/> forceShow
</div> :code="log.info.after ?? ''"
:diffBase="log.info.before ?? ''"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateSystemWebhook'"> <template v-else-if="log.type === 'updateSystemWebhook'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateAbuseReportNotificationRecipient'"> <template v-else-if="log.type === 'updateAbuseReportNotificationRecipient'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/> lang="js"
</div> forceShow
:code="JSON5.stringify(log.info.after, null, '\t')"
:diffBase="JSON5.stringify(log.info.before, null, '\t')"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateAbuseReportNote'"> <template v-else-if="log.type === 'updateAbuseReportNote'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="log.info.before ?? ''" :newString="log.info.after ?? ''" maxHeight="300px"/> forceShow
</div> :code="log.info.after ?? ''"
:diffBase="log.info.before ?? ''"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<template v-else-if="log.type === 'updateProxyAccountDescription'"> <template v-else-if="log.type === 'updateProxyAccountDescription'">
<div :class="$style.diff"> <MkCodeDiff
<CodeDiff :context="5" :hideHeader="true" :oldString="log.info.before ?? ''" :newString="log.info.after ?? ''" maxHeight="300px"/> forceShow
</div> :code="log.info.after ?? ''"
:diffBase="log.info.before ?? ''"
:maxHeight="300"
></MkCodeDiff>
</template> </template>
<details> <details>
@ -229,7 +277,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { CodeDiff } from 'v-code-diff'; import MkCodeDiff from '@/components/MkCodeDiff.vue';
import JSON5 from 'json5'; import JSON5 from 'json5';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import MkFolder from '@/components/MkFolder.vue'; import MkFolder from '@/components/MkFolder.vue';
@ -240,13 +288,6 @@ const props = defineProps<{
</script> </script>
<style lang="scss" module> <style lang="scss" module>
.diff {
background: #fff;
color: #000;
border-radius: 6px;
overflow: clip;
}
.logYellow { .logYellow {
color: var(--MI_THEME-warn); color: var(--MI_THEME-warn);
} }

View File

@ -677,6 +677,9 @@ importers:
'@sentry/vue': '@sentry/vue':
specifier: 10.34.0 specifier: 10.34.0
version: 10.34.0(vue@3.5.26(typescript@5.9.3)) version: 10.34.0(vue@3.5.26(typescript@5.9.3))
'@shikijs/transformers':
specifier: 3.21.0
version: 3.21.0
'@syuilo/aiscript': '@syuilo/aiscript':
specifier: 1.2.1 specifier: 1.2.1
version: 1.2.1 version: 1.2.1
@ -731,6 +734,9 @@ importers:
date-fns: date-fns:
specifier: 4.1.0 specifier: 4.1.0
version: 4.1.0 version: 4.1.0
diff:
specifier: 8.0.3
version: 8.0.3
eventemitter3: eventemitter3:
specifier: 5.0.1 specifier: 5.0.1
version: 5.0.1 version: 5.0.1
@ -818,9 +824,6 @@ importers:
tinycolor2: tinycolor2:
specifier: 1.6.0 specifier: 1.6.0
version: 1.6.0 version: 1.6.0
v-code-diff:
specifier: 1.13.1
version: 1.13.1(vue@3.5.26(typescript@5.9.3))
vite: vite:
specifier: 7.3.1 specifier: 7.3.1
version: 7.3.1(@types/node@24.10.9)(sass@1.97.2)(terser@5.46.0)(tsx@4.21.0) version: 7.3.1(@types/node@24.10.9)(sass@1.97.2)(terser@5.46.0)(tsx@4.21.0)
@ -3726,6 +3729,9 @@ packages:
'@shikijs/themes@3.21.0': '@shikijs/themes@3.21.0':
resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==} resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==}
'@shikijs/transformers@3.21.0':
resolution: {integrity: sha512-CZwvCWWIiRRiFk9/JKzdEooakAP8mQDtBOQ1TKiCaS2E1bYtyBCOkUzS8akO34/7ufICQ29oeSfkb3tT5KtrhA==}
'@shikijs/types@3.21.0': '@shikijs/types@3.21.0':
resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==} resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==}
@ -6244,9 +6250,6 @@ packages:
dezalgo@1.0.4: dezalgo@1.0.4:
resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
diff-match-patch@1.0.5:
resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==}
diff-sequences@29.6.3: diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@ -6255,8 +6258,8 @@ packages:
resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
engines: {node: '>=0.3.1'} engines: {node: '>=0.3.1'}
diff@8.0.2: diff@8.0.3:
resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==}
engines: {node: '>=0.3.1'} engines: {node: '>=0.3.1'}
dijkstrajs@1.0.3: dijkstrajs@1.0.3:
@ -7117,10 +7120,6 @@ packages:
headers-polyfill@4.0.3: headers-polyfill@4.0.3:
resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==}
highlight.js@11.11.1:
resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
engines: {node: '>=12.0.0'}
hosted-git-info@2.8.9: hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@ -10660,15 +10659,6 @@ packages:
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
hasBin: true hasBin: true
v-code-diff@1.13.1:
resolution: {integrity: sha512-9LTV1dZhC1oYTntyB94vfumGgsfIX5u0fEDSI2Txx4vCE5sI5LkgeLJRRy2SsTVZmDcV+R73sBr0GpPn0TJxMw==}
peerDependencies:
'@vue/composition-api': ^1.4.9
vue: ^2.6.0 || >=3.0.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
v8-to-istanbul@9.3.0: v8-to-istanbul@9.3.0:
resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==}
engines: {node: '>=10.12.0'} engines: {node: '>=10.12.0'}
@ -10830,17 +10820,6 @@ packages:
vue-component-type-helpers@3.2.2: vue-component-type-helpers@3.2.2:
resolution: {integrity: sha512-x8C2nx5XlUNM0WirgfTkHjJGO/ABBxlANZDtHw2HclHtQnn+RFPTnbjMJn8jHZW4TlUam0asHcA14lf1C6Jb+A==} resolution: {integrity: sha512-x8C2nx5XlUNM0WirgfTkHjJGO/ABBxlANZDtHw2HclHtQnn+RFPTnbjMJn8jHZW4TlUam0asHcA14lf1C6Jb+A==}
vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
hasBin: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue-docgen-api@4.79.2: vue-docgen-api@4.79.2:
resolution: {integrity: sha512-n9ENAcs+40awPZMsas7STqjkZiVlIjxIKgiJr5rSohDP0/JCrD9VtlzNojafsA1MChm/hz2h3PDtUedx3lbgfA==} resolution: {integrity: sha512-n9ENAcs+40awPZMsas7STqjkZiVlIjxIKgiJr5rSohDP0/JCrD9VtlzNojafsA1MChm/hz2h3PDtUedx3lbgfA==}
peerDependencies: peerDependencies:
@ -13106,7 +13085,7 @@ snapshots:
'@rushstack/rig-package': 0.6.0 '@rushstack/rig-package': 0.6.0
'@rushstack/terminal': 0.21.0(@types/node@24.10.9) '@rushstack/terminal': 0.21.0(@types/node@24.10.9)
'@rushstack/ts-command-line': 5.1.7(@types/node@24.10.9) '@rushstack/ts-command-line': 5.1.7(@types/node@24.10.9)
diff: 8.0.2 diff: 8.0.3
lodash: 4.17.23 lodash: 4.17.23
minimatch: 10.0.3 minimatch: 10.0.3
resolve: 1.22.11 resolve: 1.22.11
@ -14123,6 +14102,11 @@ snapshots:
dependencies: dependencies:
'@shikijs/types': 3.21.0 '@shikijs/types': 3.21.0
'@shikijs/transformers@3.21.0':
dependencies:
'@shikijs/core': 3.21.0
'@shikijs/types': 3.21.0
'@shikijs/types@3.21.0': '@shikijs/types@3.21.0':
dependencies: dependencies:
'@shikijs/vscode-textmate': 10.0.2 '@shikijs/vscode-textmate': 10.0.2
@ -17213,13 +17197,11 @@ snapshots:
asap: 2.0.6 asap: 2.0.6
wrappy: 1.0.2 wrappy: 1.0.2
diff-match-patch@1.0.5: {}
diff-sequences@29.6.3: {} diff-sequences@29.6.3: {}
diff@5.2.0: {} diff@5.2.0: {}
diff@8.0.2: {} diff@8.0.3: {}
dijkstrajs@1.0.3: {} dijkstrajs@1.0.3: {}
@ -18375,8 +18357,6 @@ snapshots:
headers-polyfill@4.0.3: {} headers-polyfill@4.0.3: {}
highlight.js@11.11.1: {}
hosted-git-info@2.8.9: {} hosted-git-info@2.8.9: {}
hosted-git-info@4.1.0: hosted-git-info@4.1.0:
@ -22416,14 +22396,6 @@ snapshots:
uuid@9.0.1: {} uuid@9.0.1: {}
v-code-diff@1.13.1(vue@3.5.26(typescript@5.9.3)):
dependencies:
diff: 5.2.0
diff-match-patch: 1.0.5
highlight.js: 11.11.1
vue: 3.5.26(typescript@5.9.3)
vue-demi: 0.14.10(vue@3.5.26(typescript@5.9.3))
v8-to-istanbul@9.3.0: v8-to-istanbul@9.3.0:
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.31 '@jridgewell/trace-mapping': 0.3.31
@ -22561,10 +22533,6 @@ snapshots:
vue-component-type-helpers@3.2.2: {} vue-component-type-helpers@3.2.2: {}
vue-demi@0.14.10(vue@3.5.26(typescript@5.9.3)):
dependencies:
vue: 3.5.26(typescript@5.9.3)
vue-docgen-api@4.79.2(vue@3.5.26(typescript@5.9.3)): vue-docgen-api@4.79.2(vue@3.5.26(typescript@5.9.3)):
dependencies: dependencies:
'@babel/parser': 7.28.5 '@babel/parser': 7.28.5

View File

@ -29,7 +29,6 @@ onlyBuiltDependencies:
- re2 - re2
- sharp - sharp
- utf-8-validate - utf-8-validate
- v-code-diff
- vue-demi - vue-demi
ignorePatchFailures: false ignorePatchFailures: false
minimumReleaseAge: 10080 # delay 7days to mitigate supply-chain attack minimumReleaseAge: 10080 # delay 7days to mitigate supply-chain attack