From 406e467ab35a909af272ea244b4272a17a7780c0 Mon Sep 17 00:00:00 2001 From: isamu Date: Sun, 18 Oct 2026 15:25:50 +0900 Subject: [PATCH 1/2] chore: add prettier with format and format:check Co-Authored-By: Claude Opus 5.5 --- .github/workflows/pull_request.yaml | 3 +++ .prettierignore | 4 ++++ .prettierrc | 3 +++ package.json | 5 ++++- yarn.lock | 5 +++++ 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index a7132b3..d29ae8f 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -49,6 +49,9 @@ jobs: - run: yarn install --frozen-lockfile --network-timeout 120000 - run: yarn run typecheck - run: yarn run lint + # Windows checkouts get CRLF line endings, which prettier reports as unformatted. + - run: yarn run format:check + if: runner.os == 'Linux' - run: yarn run build - run: yarn run test # Sanity-check `npm pack` only once (Linux + Node 24) to avoid diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..2e8551b --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +.scoria/ +scoria.config.json +dist/ +coverage/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..91a3517 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "printWidth": 160 +} diff --git a/package.json b/package.json index e869d2c..f8829c3 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,9 @@ "preview": "vite preview", "test": "tsx --test tests/*.test.ts", "quality": "scoria", - "test:coverage": "c8 yarn run test" + "test:coverage": "c8 yarn run test", + "format": "prettier --write \"{src,demo,tests}/**/*.{ts,tsx,vue,json,css}\" \"*.{ts,js,json}\"", + "format:check": "prettier --check \"{src,demo,tests}/**/*.{ts,tsx,vue,json,css}\" \"*.{ts,js,json}\"" }, "resolutions": { "minimatch": "^10.2.4" @@ -53,6 +55,7 @@ "eslint-plugin-vue": "^10.11.1", "globals": "^17.13.0", "gui-chat-protocol": "^2.3.0", + "prettier": "^3.9.10", "scoria": "^0.4.1", "tailwindcss": "^4.3.3", "tsx": "^4.23.15", diff --git a/yarn.lock b/yarn.lock index 872c4be..11614f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3000,6 +3000,11 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier@^3.9.10: + version "3.9.10" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.9.10.tgz#ac378e432f1a7381518f2e080816bbaefa38d585" + integrity sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA== + pretty-ms@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-7.0.1.tgz#7d903eaab281f7d8e03c66f867e239dc32fb73e8" From 335cb1d519b812eddc9b41ad8dfb671b083c13f0 Mon Sep 17 00:00:00 2001 From: isamu Date: Sun, 18 Oct 2026 15:26:00 +0900 Subject: [PATCH 2/2] style: format with prettier Co-Authored-By: Claude Opus 5.5 --- demo/App.vue | 7 +------ demo/markdownArgs.ts | 3 +-- src/core/hostResponse.ts | 28 ++++++++-------------------- src/core/plugin.ts | 30 +++++++----------------------- src/vue/View.vue | 24 ++++-------------------- src/vue/index.ts | 6 +----- tests/hostResponse.test.ts | 28 +++++----------------------- tests/plugin.test.ts | 10 ++-------- tsconfig.eslint.json | 15 ++------------- vite.config.ts | 3 +-- 10 files changed, 32 insertions(+), 122 deletions(-) diff --git a/demo/App.vue b/demo/App.vue index e05893e..dfe9989 100644 --- a/demo/App.vue +++ b/demo/App.vue @@ -36,12 +36,7 @@

View Component

- +
Sent Message: diff --git a/demo/markdownArgs.ts b/demo/markdownArgs.ts index 06a89fa..21fb257 100644 --- a/demo/markdownArgs.ts +++ b/demo/markdownArgs.ts @@ -1,7 +1,6 @@ import type { MarkdownArgs } from "../src/core/types"; -const isRecord = (value: unknown): value is Record => - typeof value === "object" && value !== null && !Array.isArray(value); +const isRecord = (value: unknown): value is Record => typeof value === "object" && value !== null && !Array.isArray(value); export const isMarkdownArgs = (value: unknown): value is MarkdownArgs => isRecord(value) && diff --git a/src/core/hostResponse.ts b/src/core/hostResponse.ts index fd7412a..dd45986 100644 --- a/src/core/hostResponse.ts +++ b/src/core/hostResponse.ts @@ -7,29 +7,17 @@ export interface SaveImagesResponse { imageUrls?: Record; } -const isRecord = (value: unknown): value is Record => - typeof value === "object" && value !== null; +const isRecord = (value: unknown): value is Record => typeof value === "object" && value !== null; -const isOptionalString = (value: unknown): value is string | undefined => - value === undefined || typeof value === "string"; +const isOptionalString = (value: unknown): value is string | undefined => value === undefined || typeof value === "string"; -const isStringRecord = (value: unknown): value is Record => - isRecord(value) && - Object.values(value).every((item) => typeof item === "string"); +const isStringRecord = (value: unknown): value is Record => isRecord(value) && Object.values(value).every((item) => typeof item === "string"); -export const isGeneratedImageResponse = ( - value: unknown, -): value is GeneratedImageResponse => - isRecord(value) && - typeof value.success === "boolean" && - isOptionalString(value.imageData); +export const isGeneratedImageResponse = (value: unknown): value is GeneratedImageResponse => + isRecord(value) && typeof value.success === "boolean" && isOptionalString(value.imageData); -export const isSaveImagesResponse = ( - value: unknown, -): value is SaveImagesResponse => - isRecord(value) && - (value.imageUrls === undefined || isStringRecord(value.imageUrls)); +export const isSaveImagesResponse = (value: unknown): value is SaveImagesResponse => + isRecord(value) && (value.imageUrls === undefined || isStringRecord(value.imageUrls)); /** `loadBlankImageBase64` returns the reference image; anything else is "no reference". */ -export const readBlankImageBase64 = (value: unknown): string => - typeof value === "string" ? value : ""; +export const readBlankImageBase64 = (value: unknown): string => (typeof value === "string" ? value : ""); diff --git a/src/core/plugin.ts b/src/core/plugin.ts index 5cc87fa..d530cb4 100644 --- a/src/core/plugin.ts +++ b/src/core/plugin.ts @@ -1,19 +1,12 @@ import type { ToolContext, ToolPluginCore } from "gui-chat-protocol"; import type { MarkdownArgs, MarkdownToolData, MarkdownResult } from "./types"; -import { - isGeneratedImageResponse, - isSaveImagesResponse, - readBlankImageBase64, -} from "./hostResponse"; +import { isGeneratedImageResponse, isSaveImagesResponse, readBlankImageBase64 } from "./hostResponse"; import { TOOL_NAME, TOOL_DEFINITION } from "./definition"; // context is nullable on purpose: hosts that run the plugin without client-side // state (MulmoClaude's server bridge) pass an empty or missing context, and // reading through it unguarded threw a TypeError instead of returning a result. -export const presentDocument = async ( - context: ToolContext | null | undefined, - args: MarkdownArgs, -): Promise => { +export const presentDocument = async (context: ToolContext | null | undefined, args: MarkdownArgs): Promise => { let { markdown } = args; const { title, filenameHint } = args; const app = context?.app; @@ -34,9 +27,7 @@ export const presentDocument = async ( const images: Record = {}; // Load blank image for aspect ratio reference - const blankImageBase64 = app.loadBlankImageBase64 - ? readBlankImageBase64(await app.loadBlankImageBase64()) - : ""; + const blankImageBase64 = app.loadBlankImageBase64 ? readBlankImageBase64(await app.loadBlankImageBase64()) : ""; // Generate images for each placeholder in parallel const imagePromises = matches.map(async (match, i) => { @@ -44,11 +35,7 @@ export const presentDocument = async ( const imageId = `image_${i}`; try { - const result = await app!.generateImageWithBackend!( - prompt, - blankImageBase64 ? [blankImageBase64] : [], - context, - ); + const result = await app!.generateImageWithBackend!(prompt, blankImageBase64 ? [blankImageBase64] : [], context); if (isGeneratedImageResponse(result) && result.success && result.imageData) { images[imageId] = `data:image/png;base64,${result.imageData}`; @@ -87,8 +74,7 @@ export const presentDocument = async ( title, data: { markdown, filenameHint }, uuid: docUuid, - instructions: - "Acknowledge that the document has been created and is displayed to the user.", + instructions: "Acknowledge that the document has been created and is displayed to the user.", }; } @@ -96,8 +82,7 @@ export const presentDocument = async ( message: `Created markdown document: ${title}`, title, data: { markdown, filenameHint }, - instructions: - "Acknowledge that the document has been created and is displayed to the user.", + instructions: "Acknowledge that the document has been created and is displayed to the user.", }; }; @@ -105,8 +90,7 @@ export const pluginCore: ToolPluginCore toolDefinition: TOOL_DEFINITION, execute: presentDocument, generatingMessage: "Creating document...", - waitingMessage: - "Tell the user that the document was created, will be presented to the user shortly.", + waitingMessage: "Tell the user that the document was created, will be presented to the user shortly.", isEnabled: () => true, backends: ["imageGen"], }; diff --git a/src/vue/View.vue b/src/vue/View.vue index b50a8fa..ec0d50e 100644 --- a/src/vue/View.vue +++ b/src/vue/View.vue @@ -1,9 +1,6 @@