feat(frontend): AiScriptを1.0に更新

Close #16277
This commit is contained in:
syuilo 2025-08-06 13:32:59 +09:00
parent 9931fff35b
commit 998beeae59
8 changed files with 62 additions and 44 deletions

View File

@ -19,6 +19,10 @@
- Fix: Unicode絵文字に隣接する異体字セレクタ`U+FE0F`)が絵文字として認識される問題を修正 - Fix: Unicode絵文字に隣接する異体字セレクタ`U+FE0F`)が絵文字として認識される問題を修正
### Client ### Client
- Feat: AiScriptが1.0に更新されました
- プラグインは1.0に対応したものが必要です
- Playはそのまま動作しますが、新規に作られるプリセットは1.0になります
- 以前のバージョンから無効化されていた note_view_interruptor が有効になりました
- Feat: セーフモード - Feat: セーフモード
- プラグイン・テーマ・カスタムCSSの使用でクライアントの起動に問題が発生した際に、これらを無効にして起動できます - プラグイン・テーマ・カスタムCSSの使用でクライアントの起動に問題が発生した際に、これらを無効にして起動できます
- 以下の方法でセーフモードを起動できます - 以下の方法でセーフモードを起動できます

View File

@ -25,7 +25,8 @@
"@rollup/plugin-replace": "6.0.2", "@rollup/plugin-replace": "6.0.2",
"@rollup/pluginutils": "5.2.0", "@rollup/pluginutils": "5.2.0",
"@sentry/vue": "10.0.0", "@sentry/vue": "10.0.0",
"@syuilo/aiscript": "0.19.0", "@syuilo/aiscript": "1.0.0",
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
"@twemoji/parser": "16.0.0", "@twemoji/parser": "16.0.0",
"@vitejs/plugin-vue": "6.0.1", "@vitejs/plugin-vue": "6.0.1",
"@vue/compiler-sfc": "3.5.18", "@vue/compiler-sfc": "3.5.18",

View File

@ -265,21 +265,19 @@ const currentClip = inject<Ref<Misskey.entities.Clip> | null>('currentClip', nul
let note = deepClone(props.note); let note = deepClone(props.note);
// Transition // plugin
// https://github.com/aiscript-dev/aiscript/issues/937 const noteViewInterruptors = getPluginHandlers('note_view_interruptor');
//// plugin if (noteViewInterruptors.length > 0) {
//const noteViewInterruptors = getPluginHandlers('note_view_interruptor'); let result: Misskey.entities.Note | null = deepClone(note);
//if (noteViewInterruptors.length > 0) { for (const interruptor of noteViewInterruptors) {
// let result: Misskey.entities.Note | null = deepClone(note); try {
// for (const interruptor of noteViewInterruptors) { result = interruptor.handler(result!) as Misskey.entities.Note | null;
// try { } catch (err) {
// result = await interruptor.handler(result!) as Misskey.entities.Note | null; console.error(err);
// } catch (err) { }
// console.error(err); }
// } note = result as Misskey.entities.Note;
// } }
// note = result as Misskey.entities.Note;
//}
const isRenote = Misskey.note.isPureRenote(note); const isRenote = Misskey.note.isPureRenote(note);
const appearNote = getAppearNote(note) ?? note; const appearNote = getAppearNote(note) ?? note;

View File

@ -287,20 +287,19 @@ const inChannel = inject('inChannel', null);
let note = deepClone(props.note); let note = deepClone(props.note);
// Transition // plugin
//// plugin const noteViewInterruptors = getPluginHandlers('note_view_interruptor');
//const noteViewInterruptors = getPluginHandlers('note_view_interruptor'); if (noteViewInterruptors.length > 0) {
//if (noteViewInterruptors.length > 0) { let result: Misskey.entities.Note | null = deepClone(note);
// let result: Misskey.entities.Note | null = deepClone(note); for (const interruptor of noteViewInterruptors) {
// for (const interruptor of noteViewInterruptors) { try {
// try { result = interruptor.handler(result!) as Misskey.entities.Note | null;
// result = await interruptor.handler(result!) as Misskey.entities.Note | null; } catch (err) {
// } catch (err) { console.error(err);
// console.error(err); }
// } }
// } note = result as Misskey.entities.Note;
// note = result as Misskey.entities.Note; }
//}
const isRenote = Misskey.note.isPureRenote(note); const isRenote = Misskey.note.isPureRenote(note);
const appearNote = getAppearNote(note); const appearNote = getAppearNote(note);

View File

@ -88,7 +88,7 @@ let choices = [
] ]
// PlayID+ID+ // PlayID+ID+
let random = Math:gen_rng(\`{THIS_ID}{USER_ID}{Date:year()}{Date:month()}{Date:day()}\`) let random = Math:gen_rng(\`{THIS_ID}{USER_ID}{Date:year()}{Date:month()}{Date:day()}\`, { algorithm: 'rc4_legacy' })
// //
let chosen = choices[random(0, (choices.len - 1))] let chosen = choices[random(0, (choices.len - 1))]
@ -127,7 +127,7 @@ var results = []
// //
var cursor = 0 var cursor = 0
@do() { @main() {
if (cursor != 0) { if (cursor != 0) {
results = results.slice(0, (cursor + 1)) results = results.slice(0, (cursor + 1))
cursor = 0 cursor = 0
@ -175,7 +175,7 @@ var cursor = 0
onClick: forward onClick: forward
}, { }, {
text: "引き直す" text: "引き直す"
onClick: do onClick: main
}] }]
}) })
Ui:C:postFormButton({ Ui:C:postFormButton({
@ -191,7 +191,7 @@ var cursor = 0
]) ])
} }
do() main()
`; `;
const PRESET_QUIZ = `/// @ ${AISCRIPT_VERSION} const PRESET_QUIZ = `/// @ ${AISCRIPT_VERSION}

View File

@ -63,11 +63,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onDeactivated, onUnmounted, ref, watch, shallowRef, defineAsyncComponent } from 'vue'; import { computed, onDeactivated, onUnmounted, ref, watch, shallowRef, defineAsyncComponent } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { Interpreter, Parser, values } from '@syuilo/aiscript';
import { url } from '@@/js/config.js'; import { url } from '@@/js/config.js';
import type { Ref } from 'vue'; import type { Ref } from 'vue';
import type { AsUiComponent, AsUiRoot } from '@/aiscript/ui.js'; import type { AsUiComponent, AsUiRoot } from '@/aiscript/ui.js';
import type { MenuItem } from '@/types/menu.js'; import type { MenuItem } from '@/types/menu.js';
import type { Interpreter } from '@syuilo/aiscript';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { misskeyApi } from '@/utility/misskey-api.js'; import { misskeyApi } from '@/utility/misskey-api.js';
@ -180,8 +180,6 @@ async function unlike() {
watch(() => props.id, fetchFlash, { immediate: true }); watch(() => props.id, fetchFlash, { immediate: true });
const parser = new Parser();
const started = ref(false); const started = ref(false);
const aiscript = shallowRef<Interpreter | null>(null); const aiscript = shallowRef<Interpreter | null>(null);
const root = ref<AsUiRoot>(); const root = ref<AsUiRoot>();
@ -196,6 +194,12 @@ async function run() {
if (aiscript.value) aiscript.value.abort(); if (aiscript.value) aiscript.value.abort();
if (!flash.value) return; if (!flash.value) return;
const isLegacy = !flash.value.script.replaceAll(' ', '').startsWith('///@1.0.0');
const { Interpreter, Parser, values } = isLegacy ? await import('@syuilo/aiscript-0-19-0') : await import('@syuilo/aiscript');
const parser = new Parser();
components.value = []; components.value = [];
aiscript.value = new Interpreter({ aiscript.value = new Interpreter({

View File

@ -7,15 +7,15 @@ import { ref, defineAsyncComponent } from 'vue';
import { Interpreter, Parser, utils, values } from '@syuilo/aiscript'; import { Interpreter, Parser, utils, values } from '@syuilo/aiscript';
import { compareVersions } from 'compare-versions'; import { compareVersions } from 'compare-versions';
import { isSafeMode } from '@@/js/config.js'; import { isSafeMode } from '@@/js/config.js';
import { genId } from '@/utility/id.js';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import type { FormWithDefault } from '@/utility/form.js';
import { genId } from '@/utility/id.js';
import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js'; import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js';
import { store } from '@/store.js'; import { store } from '@/store.js';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { misskeyApi } from '@/utility/misskey-api.js'; import { misskeyApi } from '@/utility/misskey-api.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { prefer } from '@/preferences.js'; import { prefer } from '@/preferences.js';
import type { FormWithDefault } from '@/utility/form.js';
export type Plugin = { export type Plugin = {
installId: string; installId: string;
@ -394,8 +394,8 @@ function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Record<s
'Plugin:register:note_view_interruptor': values.FN_NATIVE(([handler]) => { 'Plugin:register:note_view_interruptor': values.FN_NATIVE(([handler]) => {
utils.assertFunction(handler); utils.assertFunction(handler);
addPluginHandler(id, 'note_view_interruptor', { addPluginHandler(id, 'note_view_interruptor', {
handler: withContext(ctx => async (note) => { handler: withContext(ctx => (note) => {
return utils.valToJs(await ctx.execFn(handler, [utils.jsToVal(note)])); return utils.valToJs(ctx.execFnSync(handler, [utils.jsToVal(note)]));
}), }),
}); });
}), }),

View File

@ -731,8 +731,11 @@ importers:
specifier: 10.0.0 specifier: 10.0.0
version: 10.0.0(vue@3.5.18(typescript@5.9.2)) version: 10.0.0(vue@3.5.18(typescript@5.9.2))
'@syuilo/aiscript': '@syuilo/aiscript':
specifier: 0.19.0 specifier: 1.0.0
version: 0.19.0 version: 1.0.0
'@syuilo/aiscript-0-19-0':
specifier: npm:@syuilo/aiscript@^0.19.0
version: '@syuilo/aiscript@0.19.0'
'@twemoji/parser': '@twemoji/parser':
specifier: 16.0.0 specifier: 16.0.0
version: 16.0.0 version: 16.0.0
@ -4302,6 +4305,9 @@ packages:
'@syuilo/aiscript@0.19.0': '@syuilo/aiscript@0.19.0':
resolution: {integrity: sha512-ZWG4s1m6RrFjE7NeIMaxFz769YO1jW5ReTrOROrEO4IHheOrjxxJ/Ffe2TUNqX9/XxDloMwfWplKhfSzx8LGMA==} resolution: {integrity: sha512-ZWG4s1m6RrFjE7NeIMaxFz769YO1jW5ReTrOROrEO4IHheOrjxxJ/Ffe2TUNqX9/XxDloMwfWplKhfSzx8LGMA==}
'@syuilo/aiscript@1.0.0':
resolution: {integrity: sha512-m+Dxx0g2pDI198OCj/OJgiJnE4ajlbOFAMyh84FmbY1S8ss/MHytxY82dCnMZj5WVt7VE7a1rtW7biuRRfuyaA==}
'@szmarczak/http-timer@5.0.1': '@szmarczak/http-timer@5.0.1':
resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==}
engines: {node: '>=14.16'} engines: {node: '>=14.16'}
@ -14637,7 +14643,7 @@ snapshots:
eslint-visitor-keys: 4.2.1 eslint-visitor-keys: 4.2.1
espree: 10.4.0 espree: 10.4.0
estraverse: 5.3.0 estraverse: 5.3.0
picomatch: 4.0.2 picomatch: 4.0.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
- typescript - typescript
@ -14735,6 +14741,12 @@ snapshots:
stringz: 2.1.0 stringz: 2.1.0
uuid: 9.0.1 uuid: 9.0.1
'@syuilo/aiscript@1.0.0':
dependencies:
seedrandom: 3.0.5
stringz: 2.1.0
uuid: 11.1.0
'@szmarczak/http-timer@5.0.1': '@szmarczak/http-timer@5.0.1':
dependencies: dependencies:
defer-to-connect: 2.0.1 defer-to-connect: 2.0.1