From d6a0f439ec63d706345a662e7dd65ec7e74471c0 Mon Sep 17 00:00:00 2001 From: Gilad S Date: Sun, 19 May 2024 02:15:02 +0300 Subject: [PATCH] feat: `init` command to scaffold a new project from a template (#217) * feat: `init` command to scaffold a project from a template * feat: `node-typescript` project template * feat: `electron-typescript-react` project template * feat: debug mode * feat: load LoRA adapters * feat: link to CLI command docs from the CLI help * feat: improve Electron support * fix: improve binary compatibility detection on Linux * docs: CLI commands syntax highlighting --- .eslintrc.json | 11 +- .github/ISSUE_TEMPLATE/bug-report.yml | 2 +- .github/workflows/build.yml | 27 + .gitignore | 1 + .husky/commit-msg | 2 +- .vitepress/config.ts | 1 + .vitepress/theme/style.css | 23 + .vitepress/tsconfig.json | 5 +- .vitepress/utils/getCommandHtmlDoc.ts | 22 +- .vitepress/utils/getInlineCodeBlockHtml.ts | 20 + README.md | 2 +- docs/guide/chat-prompt-wrapper.md | 4 +- docs/guide/chat-session.md | 4 +- docs/guide/cli/build.md | 4 +- docs/guide/cli/chat.md | 4 +- docs/guide/cli/clear.md | 4 +- docs/guide/cli/cli.data.ts | 26 +- docs/guide/cli/complete.md | 4 +- docs/guide/cli/download.md | 4 +- docs/guide/cli/index.md | 4 +- docs/guide/cli/infill.md | 4 +- docs/guide/cli/init.md | 22 + docs/guide/cli/inspect.md | 4 +- docs/guide/cli/inspect/gguf.md | 4 +- docs/guide/cli/inspect/gpu.md | 4 +- docs/guide/cli/inspect/measure.md | 4 +- docs/guide/cli/pull.md | 4 +- docs/guide/index.md | 2 +- llama/addon.cpp | 92 + package-lock.json | 4486 ++++++++--------- package.json | 25 +- packages/create-node-llama-cpp/.gitignore | 1 + packages/create-node-llama-cpp/LICENSE | 21 + packages/create-node-llama-cpp/README.md | 12 + .../create-node-llama-cpp/package-lock.json | 138 + packages/create-node-llama-cpp/package.json | 56 + packages/create-node-llama-cpp/src/cli.ts | 19 + packages/create-node-llama-cpp/src/index.ts | 1 + packages/create-node-llama-cpp/tsconfig.json | 34 + scripts/packTemplates.ts | 111 + ...epareCreateNodeLlamaCppModuleForPublish.ts | 27 + src/bindings/AddonTypes.ts | 1 + src/bindings/Llama.ts | 27 +- src/bindings/getLlama.ts | 75 +- .../utils/detectAvailableComputeLayers.ts | 4 + src/bindings/utils/detectGlibc.ts | 14 +- src/cli/cli.ts | 20 +- src/cli/commands/BuildCommand.ts | 9 +- src/cli/commands/ChatCommand.ts | 8 +- src/cli/commands/ClearCommand.ts | 8 +- src/cli/commands/CompleteCommand.ts | 7 +- src/cli/commands/DownloadCommand.ts | 8 +- src/cli/commands/InfillCommand.ts | 7 +- src/cli/commands/InitCommand.ts | 245 + src/cli/commands/PullCommand.ts | 31 +- src/cli/commands/inspect/InspectCommand.ts | 7 +- .../inspect/commands/InspectGgufCommand.ts | 10 +- .../inspect/commands/InspectGpuCommand.ts | 7 +- .../inspect/commands/InspectMeasureCommand.ts | 7 +- src/cli/projectTemplates.ts | 15 + src/cli/startCreateCli.ts | 38 + src/cli/utils/consolePromptQuestion.ts | 11 +- src/cli/utils/interactivelyAskForModel.ts | 595 +++ src/cli/utils/projectTemplates.ts | 81 + src/cli/utils/resolveCommandGgufPath.ts | 572 +-- src/cli/utils/splitAnsiToLines.ts | 28 +- .../utils/withCliCommandDescriptionDocsUrl.ts | 28 + src/commands.ts | 4 + src/config.ts | 31 +- src/evaluator/LlamaContext/LlamaContext.ts | 1 - src/evaluator/LlamaModel.ts | 106 +- src/utils/createModelDownloader.ts | 5 + templates/.gitignore | 1 + .../electron-typescript-react/.editorconfig | 14 + .../electron-typescript-react/.eslintrc.json | 160 + .../electron-typescript-react/.gitignore | 9 + templates/electron-typescript-react/README.md | 13 + .../electron-builder.json5 | 51 + .../electron/electron-env.d.ts | 27 + .../electron/index.ts | 67 + .../electron/preload.ts | 24 + .../electron/rpc/llmRpc.ts | 78 + .../electron/state/llmState.ts | 413 ++ .../electron/utils/createElectronSideBirpc.ts | 22 + .../electron-typescript-react/package.json | 45 + .../electron-typescript-react/public/vite.svg | 18 + .../electron-typescript-react/src/App/App.css | 40 + .../electron-typescript-react/src/App/App.tsx | 129 + .../components/ChatHistory/ChatHistory.css | 61 + .../components/ChatHistory/ChatHistory.tsx | 39 + .../src/App/components/Header/Header.css | 89 + .../src/App/components/Header/Header.tsx | 48 + .../src/App/components/InputRow/InputRow.css | 73 + .../src/App/components/InputRow/InputRow.tsx | 79 + .../src/hooks/useExternalState.ts | 24 + .../src/icons/AbortIconSVG.tsx | 7 + .../src/icons/AddMessageIconSVG.tsx | 7 + .../src/icons/DeleteIconSVG.tsx | 7 + .../src/icons/LoadFileIconSVG.tsx | 7 + .../electron-typescript-react/src/index.css | 82 + .../electron-typescript-react/src/index.html | 13 + .../electron-typescript-react/src/index.tsx | 15 + .../src/rpc/llmRpc.ts | 22 + .../src/state/llmState.ts | 23 + .../src/utils/createRendererSideBirpc.ts | 20 + .../src/vite-env.d.ts | 1 + .../electron-typescript-react/tsconfig.json | 33 + .../tsconfig.node.json | 29 + .../electron-typescript-react/vite.config.ts | 67 + templates/node-typescript/.editorconfig | 14 + templates/node-typescript/.eslintrc.json | 153 + templates/node-typescript/.gitignore | 7 + templates/node-typescript/README.md | 13 + templates/node-typescript/package.json | 53 + templates/node-typescript/src/index.ts | 83 + templates/node-typescript/tsconfig.json | 33 + templates/package-lock.json | 1255 +++++ templates/package.json | 10 + tsconfig.json | 5 +- 119 files changed, 7528 insertions(+), 3210 deletions(-) create mode 100644 .vitepress/utils/getInlineCodeBlockHtml.ts create mode 100644 docs/guide/cli/init.md create mode 100644 packages/create-node-llama-cpp/.gitignore create mode 100644 packages/create-node-llama-cpp/LICENSE create mode 100644 packages/create-node-llama-cpp/README.md create mode 100644 packages/create-node-llama-cpp/package-lock.json create mode 100644 packages/create-node-llama-cpp/package.json create mode 100755 packages/create-node-llama-cpp/src/cli.ts create mode 100644 packages/create-node-llama-cpp/src/index.ts create mode 100644 packages/create-node-llama-cpp/tsconfig.json create mode 100644 scripts/packTemplates.ts create mode 100644 scripts/prepareCreateNodeLlamaCppModuleForPublish.ts create mode 100644 src/cli/commands/InitCommand.ts create mode 100644 src/cli/projectTemplates.ts create mode 100644 src/cli/startCreateCli.ts create mode 100644 src/cli/utils/interactivelyAskForModel.ts create mode 100644 src/cli/utils/projectTemplates.ts create mode 100644 src/cli/utils/withCliCommandDescriptionDocsUrl.ts create mode 100644 templates/.gitignore create mode 100644 templates/electron-typescript-react/.editorconfig create mode 100644 templates/electron-typescript-react/.eslintrc.json create mode 100644 templates/electron-typescript-react/.gitignore create mode 100644 templates/electron-typescript-react/README.md create mode 100644 templates/electron-typescript-react/electron-builder.json5 create mode 100644 templates/electron-typescript-react/electron/electron-env.d.ts create mode 100644 templates/electron-typescript-react/electron/index.ts create mode 100644 templates/electron-typescript-react/electron/preload.ts create mode 100644 templates/electron-typescript-react/electron/rpc/llmRpc.ts create mode 100644 templates/electron-typescript-react/electron/state/llmState.ts create mode 100644 templates/electron-typescript-react/electron/utils/createElectronSideBirpc.ts create mode 100644 templates/electron-typescript-react/package.json create mode 100644 templates/electron-typescript-react/public/vite.svg create mode 100644 templates/electron-typescript-react/src/App/App.css create mode 100644 templates/electron-typescript-react/src/App/App.tsx create mode 100644 templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.css create mode 100644 templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.tsx create mode 100644 templates/electron-typescript-react/src/App/components/Header/Header.css create mode 100644 templates/electron-typescript-react/src/App/components/Header/Header.tsx create mode 100644 templates/electron-typescript-react/src/App/components/InputRow/InputRow.css create mode 100644 templates/electron-typescript-react/src/App/components/InputRow/InputRow.tsx create mode 100644 templates/electron-typescript-react/src/hooks/useExternalState.ts create mode 100644 templates/electron-typescript-react/src/icons/AbortIconSVG.tsx create mode 100644 templates/electron-typescript-react/src/icons/AddMessageIconSVG.tsx create mode 100644 templates/electron-typescript-react/src/icons/DeleteIconSVG.tsx create mode 100644 templates/electron-typescript-react/src/icons/LoadFileIconSVG.tsx create mode 100644 templates/electron-typescript-react/src/index.css create mode 100644 templates/electron-typescript-react/src/index.html create mode 100644 templates/electron-typescript-react/src/index.tsx create mode 100644 templates/electron-typescript-react/src/rpc/llmRpc.ts create mode 100644 templates/electron-typescript-react/src/state/llmState.ts create mode 100644 templates/electron-typescript-react/src/utils/createRendererSideBirpc.ts create mode 100644 templates/electron-typescript-react/src/vite-env.d.ts create mode 100644 templates/electron-typescript-react/tsconfig.json create mode 100644 templates/electron-typescript-react/tsconfig.node.json create mode 100644 templates/electron-typescript-react/vite.config.ts create mode 100644 templates/node-typescript/.editorconfig create mode 100644 templates/node-typescript/.eslintrc.json create mode 100644 templates/node-typescript/.gitignore create mode 100644 templates/node-typescript/README.md create mode 100644 templates/node-typescript/package.json create mode 100644 templates/node-typescript/src/index.ts create mode 100644 templates/node-typescript/tsconfig.json create mode 100644 templates/package-lock.json create mode 100644 templates/package.json diff --git a/.eslintrc.json b/.eslintrc.json index 71fe0a95..b6e2476a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,7 +5,7 @@ "browser": false, "es6": true }, - "ignorePatterns": ["/dist", "/llama", "/docs-site"], + "ignorePatterns": ["/dist", "/llama", "/docs-site", "/packages/create-node-llama-cpp/dist"], "extends": [ "eslint:recommended", "plugin:jsdoc/recommended" @@ -15,10 +15,7 @@ "SharedArrayBuffer": "readonly" }, "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module" }, "overrides": [{ @@ -148,7 +145,9 @@ }], "keyword-spacing": ["warn"], "space-infix-ops": ["warn"], - "spaced-comment": ["warn", "always"], + "spaced-comment": ["warn", "always", { + "markers": ["/"] + }], "eol-last": ["warn", "always"], "max-len": ["warn", { "code": 140, diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index a8542990..2c2c588d 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -39,7 +39,7 @@ body: Your bug can be investigated much faster if your code can be run without any dependencies other than `node-llama-cpp`. Issues without reproduction steps or code examples may be closed as not actionable. Please try to provide a Minimal, Complete, and Verifiable example ([link](http://stackoverflow.com/help/mcve)). - Also, please enable enable debug logs by using `getLlama({logLevel: LlamaLogLevel.debug})` to get more information. + Also, please enable enable debug logs by using `getLlama({debug: true})` to get more information. placeholder: >- Please try to provide a Minimal, Complete, and Verifiable example. http://stackoverflow.com/help/mcve diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 64d961dc..3c028eb5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -334,6 +334,7 @@ jobs: contents: write issues: write pull-requests: write + discussions: write needs: - build - build-binaries @@ -381,6 +382,32 @@ jobs: if [ -f .semanticRelease.npmPackage.deployedVersion.txt ]; then echo "npm-url=https://www.npmjs.com/package/node-llama-cpp/v/$(cat .semanticRelease.npmPackage.deployedVersion.txt)" >> $GITHUB_OUTPUT fi + - name: Prepare `create-node-llama-cpp` module + if: steps.set-npm-url.outputs.npm-url != '' + run: | + export DEPLOYED_PACKAGE_VERSION=$(cat .semanticRelease.npmPackage.deployedVersion.txt) + + pushd packages/create-node-llama-cpp + npm ci --ignore-scripts + popd + + npx --no vite-node ./scripts/prepareCreateNodeLlamaCppModuleForPublish.ts --packageVersion "$DEPLOYED_PACKAGE_VERSION" + + pushd packages/create-node-llama-cpp + npm run build + - name: Release `create-node-llama-cpp` module + if: steps.set-npm-url.outputs.npm-url != '' + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GH_RELEASE_REF: ${{ github.ref }} + run: | + cd packages/create-node-llama-cpp + + if [ "$GH_RELEASE_REF" == "refs/heads/beta" ]; then + npm publish --tag beta + else + npm publish + fi - name: Generate docs with updated version if: steps.set-npm-url.outputs.npm-url != '' && github.ref == 'refs/heads/master' env: diff --git a/.gitignore b/.gitignore index d6a148e0..21416bd4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules /dist /docs-site /docs/api +/templates/packed /.env /.eslintcache diff --git a/.husky/commit-msg b/.husky/commit-msg index e8105222..b5676766 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npx --no -- commitlint --edit $1 +npx --no -- commitlint --edit "$1" diff --git a/.vitepress/config.ts b/.vitepress/config.ts index da48849e..1eb1fc5a 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -226,6 +226,7 @@ export default defineConfig({ items: [ {text: "Pull", link: "/pull"}, {text: "Chat", link: "/chat"}, + {text: "Init", link: "/init"}, {text: "Download", link: "/download"}, {text: "Complete", link: "/complete"}, {text: "Infill", link: "/infill"}, diff --git a/.vitepress/theme/style.css b/.vitepress/theme/style.css index 78557e34..83a5523b 100644 --- a/.vitepress/theme/style.css +++ b/.vitepress/theme/style.css @@ -50,6 +50,7 @@ transition: opacity 0.5s; opacity: 0; pointer-events: none; + z-index: -1; } .VPNavBar:not(.home) .divider-line[class] { @@ -84,6 +85,7 @@ content: ""; transition: opacity 0.5s; pointer-events: none; + z-index: -1; } .main-badges>p { @@ -94,6 +96,27 @@ gap: 4px; } +.VPSidebarItem .text { + word-break: break-word; + line-height: 20px; + padding: 6px 0px; +} + +a.inlineCodeLink { + /*text-decoration: none;*/ + text-underline-offset: 4px; + color: transparent; +} +a.inlineCodeLink:hover { + color: inherit; +} + +a.inlineCodeLink pre>code { + border-radius: 4px; + padding: 3px 6px; + background-color: var(--vp-code-bg); +} + img[src$="assets/logo.roundEdges.png"], img[src$="assets/logo.png"] { box-shadow: 0px 4px 12px 0px rgb(0 0 0 / 16%), 0px 8px 64px 0px rgb(0 0 0 / 24%); diff --git a/.vitepress/tsconfig.json b/.vitepress/tsconfig.json index 6148ec1e..59d419cd 100644 --- a/.vitepress/tsconfig.json +++ b/.vitepress/tsconfig.json @@ -32,8 +32,5 @@ "./config.ts", "./utils", "../docs" - ], - "ts-node": { - "esm": true - } + ] } diff --git a/.vitepress/utils/getCommandHtmlDoc.ts b/.vitepress/utils/getCommandHtmlDoc.ts index 732ae8d4..ceac4de4 100644 --- a/.vitepress/utils/getCommandHtmlDoc.ts +++ b/.vitepress/utils/getCommandHtmlDoc.ts @@ -1,9 +1,12 @@ import {Argv, CommandModule, Options} from "yargs"; +import {createMarkdownRenderer} from "vitepress"; import {htmlEscape} from "./htmlEscape.js"; -import {cliBinName, npxRunPrefix} from "../../src/config.js"; import {buildHtmlTable} from "./buildHtmlTable.js"; import {buildHtmlHeading} from "./buildHtmlHeading.js"; import {htmlEscapeWithCodeMarkdown} from "./htmlEscapeWithCodeMarkdown.js"; +import {getInlineCodeBlockHtml} from "./getInlineCodeBlockHtml.js"; +import {cliBinName, npxRunPrefix} from "../../src/config.js"; +import {withoutCliCommandDescriptionDocsUrl} from "../../src/cli/utils/withCliCommandDescriptionDocsUrl.js"; export async function getCommandHtmlDoc(command: CommandModule, { cliName = cliBinName, @@ -19,6 +22,7 @@ export async function getCommandHtmlDoc(command: CommandModule, { const title = cliName + " " + (resolvedParentCommandCliCommand ?? "").replace("", currentCommandCliCommand ?? ""); const description = command.describe ?? ""; const {subCommands, optionGroups} = await parseCommandDefinition(command); + const markdownRenderer = await createMarkdownRenderer(process.cwd()); let res = ""; @@ -45,8 +49,17 @@ export async function getCommandHtmlDoc(command: CommandModule, { cliCommand = (resolvedParentCommandCliCommand ?? "").replace("", cliCommand); return [ - `` + htmlEscape(cliName + " " + cliCommand) + "", - htmlEscapeWithCodeMarkdown(String(subCommand.describe ?? "")) + getInlineCodeBlockHtml( + markdownRenderer, + cliName + " " + cliCommand, + "shell", + ( + subCommandsParentPageLink != null + ? (subCommandsParentPageLink + "/") + : "" + ) + commandPageLink + ), + htmlEscapeWithCodeMarkdown(withoutCliCommandDescriptionDocsUrl(String(subCommand.describe ?? ""))) ]; }) .filter((row): row is string[] => row != null) @@ -72,8 +85,9 @@ export async function getCommandHtmlDoc(command: CommandModule, { return { title, - description, + description: withoutCliCommandDescriptionDocsUrl(description), usage: npxRunPrefix + title, + usageHtml: markdownRenderer.render("```shell\n" + npxRunPrefix + title + "\n```"), options: res }; } diff --git a/.vitepress/utils/getInlineCodeBlockHtml.ts b/.vitepress/utils/getInlineCodeBlockHtml.ts new file mode 100644 index 00000000..8db8114b --- /dev/null +++ b/.vitepress/utils/getInlineCodeBlockHtml.ts @@ -0,0 +1,20 @@ +import {createMarkdownRenderer} from "vitepress"; +import {htmlEscape} from "./htmlEscape.js"; + +export function getInlineCodeBlockHtml( + markdownRenderer: Awaited>, code: string, lang: string, link?: string +) { + if (markdownRenderer.options.highlight != null) { + const codeBlock = markdownRenderer.options.highlight(code, lang, ""); + + if (link != null && link !== "") + return `${codeBlock}`; + + return `${codeBlock}`; + } + + if (link != null && link !== "") + return `${htmlEscape(code)}`; + + return `${htmlEscape(code)}`; +} diff --git a/README.md b/README.md index 1329a4a3..f4006c6e 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ const a1 = await session.prompt(q1); console.log("AI: " + a1); -const q2 = "Summerize what you said"; +const q2 = "Summarize what you said"; console.log("User: " + q2); const a2 = await session.prompt(q2); diff --git a/docs/guide/chat-prompt-wrapper.md b/docs/guide/chat-prompt-wrapper.md index ac043140..cacb222b 100644 --- a/docs/guide/chat-prompt-wrapper.md +++ b/docs/guide/chat-prompt-wrapper.md @@ -68,7 +68,7 @@ const a1 = await session.prompt(q1); console.log("AI: " + a1); -const q2 = "Summerize what you said"; +const q2 = "Summarize what you said"; console.log("User: " + q2); const a2 = await session.prompt(q2); @@ -124,7 +124,7 @@ const a1 = await session.prompt(q1); console.log("AI: " + a1); -const q2 = "Summerize what you said"; +const q2 = "Summarize what you said"; console.log("User: " + q2); const a2 = await session.prompt(q2); diff --git a/docs/guide/chat-session.md b/docs/guide/chat-session.md index b8f28bb5..3f923b96 100644 --- a/docs/guide/chat-session.md +++ b/docs/guide/chat-session.md @@ -26,7 +26,7 @@ const a1 = await session.prompt(q1); console.log("AI: " + a1); -const q2 = "Summerize what you said"; +const q2 = "Summarize what you said"; console.log("User: " + q2); const a2 = await session.prompt(q2); @@ -59,7 +59,7 @@ const a1 = await session.prompt(q1); console.log("AI: " + a1); -const q2 = "Summerize what you said"; +const q2 = "Summarize what you said"; console.log("User: " + q2); const a2 = await session.prompt(q2); diff --git a/docs/guide/cli/build.md b/docs/guide/cli/build.md index e64276a0..2ff33233 100644 --- a/docs/guide/cli/build.md +++ b/docs/guide/cli/build.md @@ -15,9 +15,7 @@ If the build fails on macOS with the error `"/usr/bin/cc" is not able to compile ::: ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/chat.md b/docs/guide/cli/chat.md index e84b6bde..95a589f3 100644 --- a/docs/guide/cli/chat.md +++ b/docs/guide/cli/chat.md @@ -11,7 +11,5 @@ const commandDoc = docs.chat; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/clear.md b/docs/guide/cli/clear.md index 43bf2056..e4945477 100644 --- a/docs/guide/cli/clear.md +++ b/docs/guide/cli/clear.md @@ -11,7 +11,5 @@ const commandDoc = docs.clear; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/cli.data.ts b/docs/guide/cli/cli.data.ts index 2bcc7340..af2b7a41 100644 --- a/docs/guide/cli/cli.data.ts +++ b/docs/guide/cli/cli.data.ts @@ -1,5 +1,5 @@ import {CommandModule} from "yargs"; -import {getCommandHtmlDoc} from "../../../.vitepress/utils/getCommandHtmlDoc.js"; +import {createMarkdownRenderer} from "vitepress"; import {PullCommand} from "../../../src/cli/commands/PullCommand.js"; import {BuildCommand} from "../../../src/cli/commands/BuildCommand.js"; import {ChatCommand} from "../../../src/cli/commands/ChatCommand.js"; @@ -10,22 +10,27 @@ import {InspectGpuCommand} from "../../../src/cli/commands/inspect/commands/Insp import {InspectGgufCommand} from "../../../src/cli/commands/inspect/commands/InspectGgufCommand.js"; import {DownloadCommand} from "../../../src/cli/commands/DownloadCommand.js"; import {ClearCommand} from "../../../src/cli/commands/ClearCommand.js"; -import {htmlEscape} from "../../../.vitepress/utils/htmlEscape.js"; +import {InspectMeasureCommand} from "../../../src/cli/commands/inspect/commands/InspectMeasureCommand.js"; +import {InitCommand} from "../../../src/cli/commands/InitCommand.js"; import {cliBinName, npxRunPrefix} from "../../../src/config.js"; +import {htmlEscape} from "../../../.vitepress/utils/htmlEscape.js"; +import {getCommandHtmlDoc} from "../../../.vitepress/utils/getCommandHtmlDoc.js"; import {buildHtmlHeading} from "../../../.vitepress/utils/buildHtmlHeading.js"; import {buildHtmlTable} from "../../../.vitepress/utils/buildHtmlTable.js"; import {setIsInDocumentationMode} from "../../../src/state.js"; -import {InspectMeasureCommand} from "../../../src/cli/commands/inspect/commands/InspectMeasureCommand.js"; import {htmlEscapeWithCodeMarkdown} from "../../../.vitepress/utils/htmlEscapeWithCodeMarkdown.js"; +import {getInlineCodeBlockHtml} from "../../../.vitepress/utils/getInlineCodeBlockHtml.js"; +import {withoutCliCommandDescriptionDocsUrl} from "../../../src/cli/utils/withCliCommandDescriptionDocsUrl.js"; export default { async load() { setIsInDocumentationMode(true); return { - index: buildIndexTable([ + index: await buildIndexTable([ ["pull", PullCommand], ["chat", ChatCommand], + ["init", InitCommand], ["complete", CompleteCommand], ["infill", InfillCommand], ["inspect", InspectCommand], @@ -36,6 +41,7 @@ export default { pull: await getCommandHtmlDoc(PullCommand), chat: await getCommandHtmlDoc(ChatCommand), + init: await getCommandHtmlDoc(InitCommand), complete: await getCommandHtmlDoc(CompleteCommand), infill: await getCommandHtmlDoc(InfillCommand), inspect: { @@ -59,8 +65,9 @@ export default { } }; -function buildIndexTable(commands: [pageLink: string, command: CommandModule][], cliName: string = cliBinName) { +async function buildIndexTable(commands: [pageLink: string, command: CommandModule][], cliName: string = cliBinName) { let res = ""; + const markdownRenderer = await createMarkdownRenderer(process.cwd()); res += buildHtmlHeading("h2", htmlEscape("Commands"), "commands"); res += buildHtmlTable( @@ -74,8 +81,8 @@ function buildIndexTable(commands: [pageLink: string, command: CommandModule` + htmlEscape(cliName + " " + command.command) + "", - htmlEscapeWithCodeMarkdown(String(command.describe ?? "")) + getInlineCodeBlockHtml(markdownRenderer, cliName + " " + command.command, "shell", pageLink), + htmlEscapeWithCodeMarkdown(withoutCliCommandDescriptionDocsUrl(String(command.describe ?? ""))) ]; }) .filter((row): row is string[] => row != null) @@ -105,10 +112,13 @@ function buildIndexTable(commands: [pageLink: string, command: CommandModule [options]"; + return { title: "CLI", description: null, - usage: npxRunPrefix + cliName + " [options]", + usage, + usageHtml: markdownRenderer.render("```shell\n" + usage + "\n```"), options: res }; } diff --git a/docs/guide/cli/complete.md b/docs/guide/cli/complete.md index 7c779049..0cec5154 100644 --- a/docs/guide/cli/complete.md +++ b/docs/guide/cli/complete.md @@ -11,7 +11,5 @@ const commandDoc = docs.complete; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/download.md b/docs/guide/cli/download.md index 2a37316e..45dd2824 100644 --- a/docs/guide/cli/download.md +++ b/docs/guide/cli/download.md @@ -25,9 +25,7 @@ If the build fails on macOS with the error `"/usr/bin/cc" is not able to compile ::: ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
> To set custom cmake options that are supported by `llama.cpp`'s cmake build, diff --git a/docs/guide/cli/index.md b/docs/guide/cli/index.md index 2ef693b5..ad899b90 100644 --- a/docs/guide/cli/index.md +++ b/docs/guide/cli/index.md @@ -11,7 +11,5 @@ const commandDoc = docs.index; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/infill.md b/docs/guide/cli/infill.md index 2bdcad2a..beb64184 100644 --- a/docs/guide/cli/infill.md +++ b/docs/guide/cli/infill.md @@ -11,7 +11,5 @@ const commandDoc = docs.infill; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/init.md b/docs/guide/cli/init.md new file mode 100644 index 00000000..509913aa --- /dev/null +++ b/docs/guide/cli/init.md @@ -0,0 +1,22 @@ +--- +outline: deep +--- +# `init` command + + + +{{commandDoc.description}} + +::: info +This command is also available via: +```shell +npm create node-llama-cpp@latest [name] +``` +::: + +## Usage +
+
diff --git a/docs/guide/cli/inspect.md b/docs/guide/cli/inspect.md index c55d6bc3..b7da1b1b 100644 --- a/docs/guide/cli/inspect.md +++ b/docs/guide/cli/inspect.md @@ -11,7 +11,5 @@ const commandDoc = docs.inspect.index; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/inspect/gguf.md b/docs/guide/cli/inspect/gguf.md index 5fd2b097..53941c7c 100644 --- a/docs/guide/cli/inspect/gguf.md +++ b/docs/guide/cli/inspect/gguf.md @@ -11,7 +11,5 @@ const commandDoc = docs.inspect.gguf; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/inspect/gpu.md b/docs/guide/cli/inspect/gpu.md index a397187d..8c285f72 100644 --- a/docs/guide/cli/inspect/gpu.md +++ b/docs/guide/cli/inspect/gpu.md @@ -11,7 +11,5 @@ const commandDoc = docs.inspect.gpu; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/inspect/measure.md b/docs/guide/cli/inspect/measure.md index 737a0067..a54c80d3 100644 --- a/docs/guide/cli/inspect/measure.md +++ b/docs/guide/cli/inspect/measure.md @@ -11,7 +11,5 @@ const commandDoc = docs.inspect.measure; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/cli/pull.md b/docs/guide/cli/pull.md index 48c75398..3df97313 100644 --- a/docs/guide/cli/pull.md +++ b/docs/guide/cli/pull.md @@ -11,7 +11,5 @@ const commandDoc = docs.pull; {{commandDoc.description}} ## Usage -```shell-vue -{{commandDoc.usage}} -``` +
diff --git a/docs/guide/index.md b/docs/guide/index.md index d6f516a5..e8aeb467 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -74,7 +74,7 @@ const a1 = await session.prompt(q1); console.log("AI: " + a1); -const q2 = "Summerize what you said"; +const q2 = "Summarize what you said"; console.log("User: " + q2); const a2 = await session.prompt(q2); diff --git a/llama/addon.cpp b/llama/addon.cpp index b40745fc..419ed698 100644 --- a/llama/addon.cpp +++ b/llama/addon.cpp @@ -218,6 +218,10 @@ Napi::Value getGpuType(const Napi::CallbackInfo& info) { } static Napi::Value getNapiToken(const Napi::CallbackInfo& info, llama_model* model, llama_token token) { + if (token < 0) { + return Napi::Number::From(info.Env(), -1); + } + auto tokenType = llama_token_get_type(model, token); if (tokenType == LLAMA_TOKEN_TYPE_UNDEFINED || tokenType == LLAMA_TOKEN_TYPE_UNKNOWN) { @@ -228,6 +232,10 @@ static Napi::Value getNapiToken(const Napi::CallbackInfo& info, llama_model* mod } static Napi::Value getNapiControlToken(const Napi::CallbackInfo& info, llama_model* model, llama_token token) { + if (token < 0) { + return Napi::Number::From(info.Env(), -1); + } + auto tokenType = llama_token_get_type(model, token); if (tokenType != LLAMA_TOKEN_TYPE_CONTROL && tokenType != LLAMA_TOKEN_TYPE_USER_DEFINED) { @@ -351,6 +359,7 @@ class AddonModel : public Napi::ObjectWrap { } Napi::Value Init(const Napi::CallbackInfo& info); + Napi::Value LoadLora(const Napi::CallbackInfo& info); Napi::Value AbortActiveModelLoad(const Napi::CallbackInfo& info) { abortModelLoad = true; return info.Env().Undefined(); @@ -585,6 +594,7 @@ class AddonModel : public Napi::ObjectWrap { "AddonModel", { InstanceMethod("init", &AddonModel::Init), + InstanceMethod("loadLora", &AddonModel::LoadLora), InstanceMethod("abortActiveModelLoad", &AddonModel::AbortActiveModelLoad), InstanceMethod("tokenize", &AddonModel::Tokenize), InstanceMethod("detokenize", &AddonModel::Detokenize), @@ -737,6 +747,76 @@ class AddonModelUnloadModelWorker : public Napi::AsyncWorker { deferred.Reject(err.Value()); } }; +class AddonModelLoadLoraWorker : public Napi::AsyncWorker { + public: + AddonModel* model; + std::string loraFilePath; + float loraScale; + int32_t loraThreads; + std::string baseModelPath; + + AddonModelLoadLoraWorker( + const Napi::Env& env, + AddonModel* model, + std::string loraFilePath, + float loraScale, + int32_t loraThreads, + std::string baseModelPath + ) + : Napi::AsyncWorker(env, "AddonModelLoadLoraWorker"), + model(model), + loraFilePath(loraFilePath), + loraScale(loraScale), + loraThreads(loraThreads), + baseModelPath(baseModelPath), + deferred(Napi::Promise::Deferred::New(env)) { + model->Ref(); + } + ~AddonModelLoadLoraWorker() { + model->Unref(); + } + + Napi::Promise GetPromise() { + return deferred.Promise(); + } + + protected: + Napi::Promise::Deferred deferred; + + void Execute() { + try { + const auto res = llama_model_apply_lora_from_file( + model->model, + loraFilePath.c_str(), + loraScale, + baseModelPath.empty() ? NULL : baseModelPath.c_str(), + loraThreads + ); + + if (res != 0) { + SetError( + std::string( + std::string("Failed to apply LoRA \"") + loraFilePath + std::string("\"") + ( + baseModelPath.empty() + ? std::string("") + : (std::string(" with base model \"") + baseModelPath + std::string("\"")) + ) + ) + ); + } + } catch (const std::exception& e) { + SetError(e.what()); + } catch(...) { + SetError("Unknown error when calling \"llama_model_apply_lora_from_file\""); + } + } + void OnOK() { + deferred.Resolve(Env().Undefined()); + } + void OnError(const Napi::Error& err) { + deferred.Reject(err.Value()); + } +}; Napi::Value AddonModel::Init(const Napi::CallbackInfo& info) { if (disposed) { @@ -748,6 +828,18 @@ Napi::Value AddonModel::Init(const Napi::CallbackInfo& info) { worker->Queue(); return worker->GetPromise(); } +Napi::Value AddonModel::LoadLora(const Napi::CallbackInfo& info) { + std::string loraFilePath = info[0].As().Utf8Value(); + float scale = info[1].As().FloatValue(); + int32_t threads = info[2].As().Int32Value(); + std::string baseModelPath = (info.Length() > 3 && info[3].IsString()) ? info[3].As().Utf8Value() : std::string(""); + + int32_t resolvedThreads = threads == 0 ? std::thread::hardware_concurrency() : threads; + + AddonModelLoadLoraWorker* worker = new AddonModelLoadLoraWorker(this->Env(), this, loraFilePath, scale, threads, baseModelPath); + worker->Queue(); + return worker->GetPromise(); +} Napi::Value AddonModel::Dispose(const Napi::CallbackInfo& info) { if (disposed) { return info.Env().Undefined(); diff --git a/package-lock.json b/package-lock.json index 5eb0528a..a1a91e9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "node-llama-cpp", "version": "0.1.0", + "hasInstallScript": true, "license": "MIT", "dependencies": { "@huggingface/jinja": "^0.2.2", @@ -20,10 +21,12 @@ "env-var": "^7.3.1", "filenamify": "^6.0.0", "fs-extra": "^11.2.0", + "ignore": "^5.3.1", "ipull": "^3.1.1", "is-unicode-supported": "^2.0.0", "lifecycle-utils": "^1.4.1", "log-symbols": "^5.1.0", + "nanoid": "^5.0.7", "node-addon-api": "^7.0.0", "octokit": "^3.1.0", "ora": "^7.0.1", @@ -34,7 +37,7 @@ "slice-ansi": "^7.1.0", "stdout-update": "^4.0.1", "strip-ansi": "^7.1.0", - "uuid": "^9.0.0", + "validate-npm-package-name": "^5.0.1", "which": "^4.0.0", "yargs": "^17.7.2" }, @@ -42,8 +45,8 @@ "node-llama-cpp": "dist/cli/cli.js" }, "devDependencies": { - "@commitlint/cli": "^17.7.1", - "@commitlint/config-conventional": "^17.7.0", + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", "@semantic-release/exec": "^6.0.3", "@shikijs/vitepress-twoslash": "^1.3.0", "@types/async-retry": "^1.4.8", @@ -53,7 +56,7 @@ "@types/node": "^20.11.29", "@types/proper-lockfile": "^4.1.4", "@types/semver": "^7.5.8", - "@types/uuid": "^9.0.2", + "@types/validate-npm-package-name": "^4.0.2", "@types/which": "^3.0.0", "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^6.3.0", @@ -67,10 +70,10 @@ "eslint-plugin-n": "^16.3.1", "husky": "^8.0.3", "rimraf": "^5.0.1", - "semantic-release": "^22.0.8", + "semantic-release": "^23.1.1", "tslib": "^2.6.1", "typedoc": "^0.25.13", - "typedoc-plugin-markdown": "4.0.0-next.55", + "typedoc-plugin-markdown": "^4.0.0-next.55", "typedoc-plugin-mdn-links": "^3.1.24", "typedoc-vitepress-theme": "1.0.0-next.10", "typescript": "^5.2.2", @@ -510,439 +513,729 @@ } }, "node_modules/@commitlint/cli": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz", - "integrity": "sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", + "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", "dev": true, "dependencies": { - "@commitlint/format": "^17.8.1", - "@commitlint/lint": "^17.8.1", - "@commitlint/load": "^17.8.1", - "@commitlint/read": "^17.8.1", - "@commitlint/types": "^17.8.1", - "execa": "^5.0.0", - "lodash.isfunction": "^3.0.9", - "resolve-from": "5.0.0", - "resolve-global": "1.0.0", + "@commitlint/format": "^19.3.0", + "@commitlint/lint": "^19.2.2", + "@commitlint/load": "^19.2.0", + "@commitlint/read": "^19.2.1", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", "yargs": "^17.0.0" }, "bin": { "commitlint": "cli.js" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/config-conventional": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.8.1.tgz", - "integrity": "sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg==", + "node_modules/@commitlint/cli/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "conventional-changelog-conventionalcommits": "^6.1.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=v14" - } - }, - "node_modules/@commitlint/config-validator": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.8.1.tgz", - "integrity": "sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==", - "dev": true, - "dependencies": { - "@commitlint/types": "^17.8.1", - "ajv": "^8.11.0" + "node": ">=16.17" }, - "engines": { - "node": ">=v14" + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@commitlint/ensure": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.8.1.tgz", - "integrity": "sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==", + "node_modules/@commitlint/cli/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "dependencies": { - "@commitlint/types": "^17.8.1", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.startcase": "^4.4.0", - "lodash.upperfirst": "^4.3.1" - }, "engines": { - "node": ">=v14" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/execute-rule": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.8.1.tgz", - "integrity": "sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==", + "node_modules/@commitlint/cli/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=16.17.0" } }, - "node_modules/@commitlint/format": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.8.1.tgz", - "integrity": "sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==", + "node_modules/@commitlint/cli/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "dependencies": { - "@commitlint/types": "^17.8.1", - "chalk": "^4.1.0" - }, "engines": { - "node": ">=v14" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/format/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@commitlint/cli/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/format/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@commitlint/cli/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@commitlint/cli/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@commitlint/is-ignored": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.8.1.tgz", - "integrity": "sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==", + "node_modules/@commitlint/cli/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "dependencies": { - "@commitlint/types": "^17.8.1", - "semver": "7.5.4" - }, "engines": { - "node": ">=v14" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/is-ignored/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/@commitlint/cli/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@commitlint/lint": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.8.1.tgz", - "integrity": "sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==", + "node_modules/@commitlint/cli/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "dependencies": { - "@commitlint/is-ignored": "^17.8.1", - "@commitlint/parse": "^17.8.1", - "@commitlint/rules": "^17.8.1", - "@commitlint/types": "^17.8.1" - }, "engines": { - "node": ">=v14" - } - }, - "node_modules/@commitlint/load": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.8.1.tgz", - "integrity": "sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==", - "dev": true, - "dependencies": { - "@commitlint/config-validator": "^17.8.1", - "@commitlint/execute-rule": "^17.8.1", - "@commitlint/resolve-extends": "^17.8.1", - "@commitlint/types": "^17.8.1", - "@types/node": "20.5.1", - "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4 || ^5.2.2" + "node": ">=12" }, - "engines": { - "node": ">=v14" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/load/node_modules/@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", - "dev": true - }, - "node_modules/@commitlint/load/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@commitlint/config-conventional": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", + "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@commitlint/types": "^19.0.3", + "conventional-changelog-conventionalcommits": "^7.0.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=v18" } }, - "node_modules/@commitlint/load/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@commitlint/config-validator": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.3.tgz", + "integrity": "sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@commitlint/types": "^19.0.3", + "ajv": "^8.11.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=v18" } }, - "node_modules/@commitlint/load/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@commitlint/ensure": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.0.3.tgz", + "integrity": "sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "@commitlint/types": "^19.0.3", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" }, "engines": { - "node": ">=7.0.0" + "node": ">=v18" } }, - "node_modules/@commitlint/load/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@commitlint/message": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.8.1.tgz", - "integrity": "sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==", + "node_modules/@commitlint/execute-rule": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz", + "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/parse": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.8.1.tgz", - "integrity": "sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==", + "node_modules/@commitlint/format": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", + "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.8.1", - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-parser": "^4.0.0" + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/read": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.8.1.tgz", - "integrity": "sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==", + "node_modules/@commitlint/is-ignored": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", + "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", "dev": true, "dependencies": { - "@commitlint/top-level": "^17.8.1", - "@commitlint/types": "^17.8.1", - "fs-extra": "^11.0.0", - "git-raw-commits": "^2.0.11", - "minimist": "^1.2.6" + "@commitlint/types": "^19.0.3", + "semver": "^7.6.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/resolve-extends": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz", - "integrity": "sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==", + "node_modules/@commitlint/lint": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", + "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.8.1", - "@commitlint/types": "^17.8.1", - "import-fresh": "^3.0.0", - "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" + "@commitlint/is-ignored": "^19.2.2", + "@commitlint/parse": "^19.0.3", + "@commitlint/rules": "^19.0.3", + "@commitlint/types": "^19.0.3" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/rules": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.8.1.tgz", - "integrity": "sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==", + "node_modules/@commitlint/load": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.2.0.tgz", + "integrity": "sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==", "dev": true, "dependencies": { - "@commitlint/ensure": "^17.8.1", - "@commitlint/message": "^17.8.1", - "@commitlint/to-lines": "^17.8.1", - "@commitlint/types": "^17.8.1", - "execa": "^5.0.0" + "@commitlint/config-validator": "^19.0.3", + "@commitlint/execute-rule": "^19.0.0", + "@commitlint/resolve-extends": "^19.1.0", + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^5.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/to-lines": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.8.1.tgz", - "integrity": "sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==", + "node_modules/@commitlint/message": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.0.0.tgz", + "integrity": "sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/top-level": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.8.1.tgz", - "integrity": "sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==", + "node_modules/@commitlint/parse": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.0.3.tgz", + "integrity": "sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==", "dev": true, "dependencies": { - "find-up": "^5.0.0" + "@commitlint/types": "^19.0.3", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/types": { - "version": "17.8.1", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.8.1.tgz", - "integrity": "sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==", + "node_modules/@commitlint/read": { + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.2.1.tgz", + "integrity": "sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==", "dev": true, "dependencies": { - "chalk": "^4.1.0" + "@commitlint/top-level": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@commitlint/read/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.17" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@commitlint/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@commitlint/read/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@commitlint/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@commitlint/read/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">=16.17.0" } }, - "node_modules/@commitlint/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@commitlint/read/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" }, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "node_modules/@commitlint/read/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/read/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.1.0.tgz", + "integrity": "sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==", + "dev": true, + "dependencies": { + "@commitlint/config-validator": "^19.0.3", + "@commitlint/types": "^19.0.3", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.3.tgz", + "integrity": "sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==", + "dev": true, + "dependencies": { + "@commitlint/ensure": "^19.0.3", + "@commitlint/message": "^19.0.0", + "@commitlint/to-lines": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/rules/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@commitlint/rules/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/rules/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.0.0.tgz", + "integrity": "sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==", + "dev": true, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.0.0.tgz", + "integrity": "sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==", + "dev": true, + "dependencies": { + "find-up": "^7.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@commitlint/top-level/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/types": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.3.tgz", + "integrity": "sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==", + "dev": true, + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" } }, "node_modules/@docsearch/css": { @@ -2264,531 +2557,293 @@ "integrity": "sha512-ve+D8t1prRSRnF2S3pyDtTXDlvW1Pngbz76tjgYFQW1jxVSysmQCZfPoDAo4WP+Ano8zeYp85LsArZBI12HfwQ==", "cpu": [ "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@semantic-release/commit-analyzer": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz", - "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==", - "dev": true, - "dependencies": { - "conventional-changelog-angular": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "import-from-esm": "^1.0.3", - "lodash-es": "^4.17.21", - "micromatch": "^4.0.2" - }, - "engines": { - "node": "^18.17 || >=20.6.1" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" - } - }, - "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-changelog-angular": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", - "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", - "dev": true, - "dependencies": { - "is-text-path": "^2.0.0", - "JSONStream": "^1.3.5", - "meow": "^12.0.1", - "split2": "^4.0.0" - }, - "bin": { - "conventional-commits-parser": "cli.mjs" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@semantic-release/commit-analyzer/node_modules/is-text-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", - "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", - "dev": true, - "dependencies": { - "text-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@semantic-release/commit-analyzer/node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", - "dev": true, - "engines": { - "node": ">=16.10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/commit-analyzer/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/@semantic-release/commit-analyzer/node_modules/text-extensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", - "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", - "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", - "dev": true, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/@semantic-release/exec": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/exec/-/exec-6.0.3.tgz", - "integrity": "sha512-bxAq8vLOw76aV89vxxICecEa8jfaWwYITw6X74zzlO0mc/Bgieqx9kBRz9z96pHectiTAtsCwsQcUyLYWnp3VQ==", - "dev": true, - "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "execa": "^5.0.0", - "lodash": "^4.17.4", - "parse-json": "^5.0.0" - }, - "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0" - } - }, - "node_modules/@semantic-release/github": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.3.tgz", - "integrity": "sha512-FAjXb1F84CVI6IG8fWi+XS9ErYD+s3MHkP03zBa3+GyUrV4kqwYu/WPppIciHxujGFR51SAWPkOY5rnH6ZlrxA==", - "dev": true, - "dependencies": { - "@octokit/core": "^5.0.0", - "@octokit/plugin-paginate-rest": "^9.0.0", - "@octokit/plugin-retry": "^6.0.0", - "@octokit/plugin-throttling": "^8.0.0", - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "debug": "^4.3.4", - "dir-glob": "^3.0.1", - "globby": "^14.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "issue-parser": "^6.0.0", - "lodash-es": "^4.17.21", - "mime": "^3.0.0", - "p-filter": "^3.0.0", - "url-join": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" - } - }, - "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@semantic-release/github/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + ], "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@semantic-release/github/node_modules/globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true + }, + "node_modules/@semantic-release/commit-analyzer": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-12.0.0.tgz", + "integrity": "sha512-qG+md5gdes+xa8zP7lIo1fWE17zRdO8yMCaxh9lyL65TQleoSv8WHHOqRURfghTytUh+NpkSyBprQ5hrkxOKVQ==", "dev": true, "dependencies": { - "@sindresorhus/merge-streams": "^1.0.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "import-from-esm": "^1.0.3", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" }, "engines": { - "node": ">=18" + "node": ">=20.8.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@semantic-release/github/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=14.17" } }, - "node_modules/@semantic-release/github/node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "node_modules/@semantic-release/exec": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/exec/-/exec-6.0.3.tgz", + "integrity": "sha512-bxAq8vLOw76aV89vxxICecEa8jfaWwYITw6X74zzlO0mc/Bgieqx9kBRz9z96pHectiTAtsCwsQcUyLYWnp3VQ==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "parse-json": "^5.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, "engines": { - "node": ">=14.16" + "node": ">=14.17" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/url-join": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", - "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/@semantic-release/npm": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.1.tgz", - "integrity": "sha512-nFcT0pgVwpXsPkzjqP3ObH+pILeN1AbYscCDuYwgZEPZukL+RsGhrtdT4HA1Gjb/y1bVbE90JNtMIcgRi5z/Fg==", + "node_modules/@semantic-release/github": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-10.0.3.tgz", + "integrity": "sha512-nSJQboKrG4xBn7hHpRMrK8lt5DgqJg50ZMz9UbrsfTxuRk55XVoQEadbGZ2L9M0xZAC6hkuwkDhQJKqfPU35Fw==", "dev": true, "dependencies": { + "@octokit/core": "^6.0.0", + "@octokit/plugin-paginate-rest": "^11.0.0", + "@octokit/plugin-retry": "^7.0.0", + "@octokit/plugin-throttling": "^9.0.0", "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", - "execa": "^8.0.0", - "fs-extra": "^11.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^14.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^7.0.0", "lodash-es": "^4.17.21", - "nerf-dart": "^1.0.0", - "normalize-url": "^8.0.0", - "npm": "^10.0.0", - "rc": "^1.2.8", - "read-pkg": "^9.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^3.0.0" + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "url-join": "^5.0.0" }, "engines": { - "node": "^18.17 || >=20" + "node": ">=20.8.1" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, - "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "node_modules/@semantic-release/github/node_modules/@octokit/auth-token": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz", + "integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==", "dev": true, "engines": { - "node": ">=18" + "node": ">= 18" } }, - "node_modules/@semantic-release/npm/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "node_modules/@semantic-release/github/node_modules/@octokit/core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz", + "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==", "dev": true, "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" + "@octokit/auth-token": "^5.0.0", + "@octokit/graphql": "^8.0.0", + "@octokit/request": "^9.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^3.0.2", + "universal-user-agent": "^7.0.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 18" } }, - "node_modules/@semantic-release/npm/node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "node_modules/@semantic-release/github/node_modules/@octokit/endpoint": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", + "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", "dev": true, "dependencies": { - "escape-string-regexp": "5.0.0" + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.2" }, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 18" } }, - "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "node_modules/@semantic-release/github/node_modules/@octokit/graphql": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.1.tgz", + "integrity": "sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "@octokit/request": "^9.0.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 18" } }, - "node_modules/@semantic-release/npm/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/@semantic-release/github/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "dev": true + }, + "node_modules/@semantic-release/github/node_modules/@octokit/plugin-paginate-rest": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.0.tgz", + "integrity": "sha512-n4znWfRinnUQF6TPyxs7EctSAA3yVSP4qlJP2YgI3g9d4Ae2n5F3XDOjbUluKRxPU3rfsgpOboI4O4VtPc6Ilg==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "@octokit/types": "^13.5.0" }, "engines": { - "node": ">=16.17" + "node": ">= 18" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "peerDependencies": { + "@octokit/core": ">=6" } }, - "node_modules/@semantic-release/npm/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "node_modules/@semantic-release/github/node_modules/@octokit/plugin-retry": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.1.tgz", + "integrity": "sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==", "dev": true, + "dependencies": { + "@octokit/request-error": "^6.0.0", + "@octokit/types": "^13.0.0", + "bottleneck": "^2.15.3" + }, "engines": { - "node": ">=16" + "node": ">= 18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@octokit/core": ">=6" } }, - "node_modules/@semantic-release/npm/node_modules/hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", + "node_modules/@semantic-release/github/node_modules/@octokit/plugin-throttling": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.0.tgz", + "integrity": "sha512-B5YTToSRTzNSeEyssnrT7WwGhpIdbpV9NKIs3KyTWHX6PhpYn7gqF/+lL3BvsASBM3Sg5BAUYk7KZx5p/Ec77w==", "dev": true, "dependencies": { - "lru-cache": "^10.0.1" + "@octokit/types": "^13.0.0", + "bottleneck": "^2.15.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "engines": { - "node": ">=12" + "node": ">= 18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@octokit/core": "^6.0.0" } }, - "node_modules/@semantic-release/npm/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/@semantic-release/github/node_modules/@octokit/request": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.1.tgz", + "integrity": "sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw==", "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^7.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/npm/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true, "engines": { - "node": "14 || >=16.14" + "node": ">= 18" } }, - "node_modules/@semantic-release/npm/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/@semantic-release/github/node_modules/@octokit/request-error": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.1.tgz", + "integrity": "sha512-1mw1gqT3fR/WFvnoVpY/zUM2o/XkMs/2AszUUG9I69xn0JFLv6PGkPhNk5lbfvROs79wiS0bqiJNxfCZcRJJdg==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "@octokit/types": "^13.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 18" } }, - "node_modules/@semantic-release/npm/node_modules/normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", + "node_modules/@semantic-release/github/node_modules/@octokit/types": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", + "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", "dev": true, "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "@octokit/openapi-types": "^22.2.0" } }, - "node_modules/@semantic-release/npm/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@semantic-release/npm/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/@semantic-release/github/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "dependencies": { - "mimic-fn": "^4.0.0" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/parse-json": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", - "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "node_modules/@semantic-release/github/node_modules/before-after-hook": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", + "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==", + "dev": true + }, + "node_modules/@semantic-release/github/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "index-to-position": "^0.1.2", - "type-fest": "^4.7.1" + "escape-string-regexp": "5.0.0" }, "engines": { - "node": ">=18" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/@semantic-release/github/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "engines": { "node": ">=12" @@ -2797,16 +2852,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/read-pkg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", - "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "node_modules/@semantic-release/github/node_modules/globby": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.3", - "normalize-package-data": "^6.0.0", - "parse-json": "^8.0.0", - "type-fest": "^4.6.0", + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", "unicorn-magic": "^0.1.0" }, "engines": { @@ -2816,22 +2872,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/@semantic-release/github/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, "engines": { - "node": ">=14" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "node_modules/@semantic-release/github/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, "engines": { "node": ">=12" @@ -2840,191 +2896,243 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", + "node_modules/@semantic-release/github/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "engines": { - "node": ">=16" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz", - "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==", + "node_modules/@semantic-release/github/node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", + "dev": true + }, + "node_modules/@semantic-release/github/node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@semantic-release/npm": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.1.tgz", + "integrity": "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==", "dev": true, "dependencies": { - "conventional-changelog-angular": "^7.0.0", - "conventional-changelog-writer": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "get-stream": "^7.0.0", - "import-from-esm": "^1.0.3", - "into-stream": "^7.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^9.0.0", + "fs-extra": "^11.0.0", "lodash-es": "^4.17.21", - "read-pkg-up": "^11.0.0" + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.5.0", + "rc": "^1.2.8", + "read-pkg": "^9.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" }, "engines": { - "node": "^18.17 || >=20.6.1" + "node": ">=20.8.1" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-changelog-angular": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", - "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, "engines": { - "node": ">=16" + "node": ">=18" + } + }, + "node_modules/@semantic-release/npm/node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-commits-parser": { + "node_modules/@semantic-release/npm/node_modules/aggregate-error": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "dependencies": { - "is-text-path": "^2.0.0", - "JSONStream": "^1.3.5", - "meow": "^12.0.1", - "split2": "^4.0.0" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, - "bin": { - "conventional-commits-parser": "cli.mjs" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "5.0.0" }, "engines": { - "node": ">=16" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", - "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "engines": { - "node": ">=16" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", + "node_modules/@semantic-release/npm/node_modules/execa": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.0.2.tgz", + "integrity": "sha512-oO281GF7ksH/Ogv1xyDf1prvFta/6/XkGKxRUvA3IB2MU1rCJGlFs86HRZhdooow1ISkR0Np0rOxUCIJVw36Rg==", "dev": true, "dependencies": { - "lru-cache": "^10.0.1" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.3", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^7.0.0", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^5.2.0", + "pretty-ms": "^9.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/is-text-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", - "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "node_modules/@semantic-release/npm/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, "dependencies": { - "text-extensions": "^2.0.0" + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "node_modules/@semantic-release/npm/node_modules/human-signals": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-7.0.0.tgz", + "integrity": "sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==", "dev": true, "engines": { - "node": "14 || >=16.14" + "node": ">=18.18.0" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "node_modules/@semantic-release/npm/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, "engines": { - "node": ">=16.10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", + "node_modules/@semantic-release/npm/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/parse-json": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", - "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "node_modules/@semantic-release/npm/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "index-to-position": "^0.1.2", - "type-fest": "^4.7.1" + "path-key": "^4.0.0" }, "engines": { - "node": ">=18" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", - "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "node_modules/@semantic-release/npm/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.3", - "normalize-package-data": "^6.0.0", - "parse-json": "^8.0.0", - "type-fest": "^4.6.0", - "unicorn-magic": "^0.1.0" + "engines": { + "node": ">=12" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { - "node": ">=18" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg-up": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", - "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", - "deprecated": "Renamed to read-package-up", + "node_modules/@semantic-release/npm/node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "dev": true, - "dependencies": { - "find-up-simple": "^1.0.0", - "read-pkg": "^9.0.0", - "type-fest": "^4.6.0" - }, "engines": { "node": ">=18" }, @@ -3032,31 +3140,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/@semantic-release/release-notes-generator/node_modules/text-extensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", - "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "node_modules/@semantic-release/release-notes-generator": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-13.0.0.tgz", + "integrity": "sha512-LEeZWb340keMYuREMyxrODPXJJ0JOL8D/mCl74B4LdzbxhtXV2LrPN2QBEcGJrlQhoqLO0RhxQb6masHytKw+A==", "dev": true, + "dependencies": { + "conventional-changelog-angular": "^7.0.0", + "conventional-changelog-writer": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from-esm": "^1.0.3", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-pkg-up": "^11.0.0" + }, "engines": { - "node": ">=8" + "node": ">=20.8.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", + "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", "dev": true, "engines": { "node": ">=16" @@ -3144,9 +3255,9 @@ } }, "node_modules/@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true, "engines": { "node": ">=18" @@ -3167,30 +3278,6 @@ "url": "https://github.com/tinyhttp/tinyhttp?sponsor=1" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@types/async-retry": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.4.8.tgz", @@ -3216,6 +3303,15 @@ "integrity": "sha512-A0uYgOj3zNc4hNjHc5lYUfJQ/HVyBXiUMKdXd7ysclaE6k9oJdavQzODHuwjpUu2/boCP8afjQYi8z/GtvNCWA==", "dev": true }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/cross-spawn": { "version": "6.0.6", "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz", @@ -3384,10 +3480,10 @@ "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", "dev": true }, - "node_modules/@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", + "node_modules/@types/validate-npm-package-name": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/validate-npm-package-name/-/validate-npm-package-name-4.0.2.tgz", + "integrity": "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==", "dev": true }, "node_modules/@types/web-bluetooth": { @@ -4199,9 +4295,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "dependencies": { "debug": "^4.3.4" @@ -4223,15 +4319,15 @@ } }, "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -4312,10 +4408,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "dev": true }, "node_modules/aproba": { @@ -4344,12 +4440,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -4485,15 +4575,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -4707,45 +4788,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", - "dev": true, - "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - }, - "bin": { - "cdl": "bin/cdl.js" - } - }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -4851,6 +4893,134 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-highlight/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cli-highlight/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cli-highlight/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cli-highlight/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-highlight/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/cli-spinners": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", @@ -4863,9 +5033,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dev": true, "dependencies": { "string-width": "^4.2.0" @@ -5081,27 +5251,27 @@ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, "dependencies": { "compare-func": "^2.0.0" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/conventional-changelog-conventionalcommits": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", "dev": true, "dependencies": { "compare-func": "^2.0.0" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/conventional-changelog-writer": { @@ -5109,40 +5279,19 @@ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", "dev": true, - "dependencies": { - "conventional-commits-filter": "^4.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^12.0.1", - "semver": "^7.5.2", - "split2": "^4.0.0" - }, - "bin": { - "conventional-changelog-writer": "cli.mjs" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/conventional-changelog-writer/node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", - "dev": true, - "engines": { - "node": ">=16.10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/conventional-changelog-writer/node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, + "dependencies": { + "conventional-commits-filter": "^4.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^12.0.1", + "semver": "^7.5.2", + "split2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.mjs" + }, "engines": { - "node": ">= 10.x" + "node": ">=16" } }, "node_modules/conventional-commits-filter": { @@ -5155,21 +5304,33 @@ } }, "node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", "dev": true, "dependencies": { - "is-text-path": "^1.0.1", + "is-text-path": "^2.0.0", "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" + "meow": "^12.0.1", + "split2": "^4.0.0" }, "bin": { - "conventional-commits-parser": "cli.js" + "conventional-commits-parser": "cli.mjs" }, "engines": { - "node": ">=14" + "node": ">=16" + } + }, + "node_modules/convert-hrtime": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", + "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/convert-source-map": { @@ -5361,15 +5522,15 @@ "dev": true }, "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "dependencies": { + "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "parse-json": "^5.2.0" }, "engines": { "node": ">=14" @@ -5387,26 +5548,22 @@ } }, "node_modules/cosmiconfig-typescript-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", - "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", "dev": true, + "dependencies": { + "jiti": "^1.19.1" + }, "engines": { - "node": ">=v14.21.3" + "node": ">=v16" }, "peerDependencies": { "@types/node": "*", - "cosmiconfig": ">=7", - "ts-node": ">=10", + "cosmiconfig": ">=8.2", "typescript": ">=4" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -5490,12 +5647,15 @@ "dev": true }, "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/data-uri-to-buffer": { @@ -5529,40 +5689,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decode-named-character-reference": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", @@ -5673,15 +5799,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -5815,9 +5932,9 @@ } }, "node_modules/env-ci": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz", - "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.0.0.tgz", + "integrity": "sha512-apikxMgkipkgTvMdRT9MNqWx5VLOci79F4VBd7Op/7OPjjoanjdAvn6fglMCCEf/1bAh8eOiuEVCUs4V3qP3nQ==", "dev": true, "dependencies": { "execa": "^8.0.0", @@ -5896,9 +6013,9 @@ } }, "node_modules/env-ci/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -5961,6 +6078,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/env-var": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/env-var/-/env-var-7.4.1.tgz", @@ -6501,19 +6627,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -6690,9 +6803,9 @@ "dev": true }, "node_modules/figures": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.0.1.tgz", - "integrity": "sha512-0oY/olScYD4IhQ8u//gCPA4F3mlTn2dacYmiDm/mbDQvpmLjV4uH+zhsQ5IyXRyvqkvtUkXkNdGvg5OFJTCsuQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", "dev": true, "dependencies": { "is-unicode-supported": "^2.0.0" @@ -6782,15 +6895,16 @@ } }, "node_modules/find-versions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", - "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-6.0.0.tgz", + "integrity": "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==", "dev": true, "dependencies": { - "semver-regex": "^4.0.5" + "semver-regex": "^4.0.5", + "super-regex": "^1.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7076,6 +7190,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function-timeout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.1.tgz", + "integrity": "sha512-6yPMImFFuaMPNaTMTBuolA8EanHJWF5Vju0NHpObRURT105J6x1Mf2a7J4P7Sqk2xDxv24N5L0RatEhTBhNmdA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/function.prototype.name": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", @@ -7294,22 +7420,20 @@ } }, "node_modules/git-raw-commits": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", - "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", "dev": true, "dependencies": { - "dargs": "^7.0.0", - "lodash": "^4.17.15", - "meow": "^8.0.0", - "split2": "^3.0.0", - "through2": "^4.0.0" + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" }, "bin": { - "git-raw-commits": "cli.js" + "git-raw-commits": "cli.mjs" }, "engines": { - "node": ">=10" + "node": ">=16" } }, "node_modules/glob": { @@ -7370,16 +7494,28 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, "dependencies": { - "ini": "^1.3.4" + "ini": "4.1.1" }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-directory/node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/globals": { @@ -7476,15 +7612,6 @@ "uglify-js": "^3.1.4" } }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -7580,6 +7707,15 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/hook-std": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", @@ -7599,15 +7735,24 @@ "dev": true }, "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "lru-cache": "^10.0.1" }, "engines": { - "node": ">=10" + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" } }, "node_modules/html-escaper": { @@ -7617,9 +7762,9 @@ "dev": true }, "node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "dependencies": { "agent-base": "^7.1.0", @@ -7630,9 +7775,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -7686,10 +7831,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true, + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "engines": { "node": ">= 4" } @@ -7720,9 +7864,9 @@ } }, "node_modules/import-from-esm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.3.tgz", - "integrity": "sha512-U3Qt/CyfFpTUv6LOP2jRTLYjphH6zg3okMfHbyqRa/W2w6hr8OsJWVggNlR4jxuojQy81TgTJTxgSkyoteRGMQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", + "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -8078,12 +8222,15 @@ } }, "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-regex": { @@ -8157,15 +8304,15 @@ } }, "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", "dev": true, "dependencies": { - "text-extensions": "^1.0.0" + "text-extensions": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/is-typed-array": { @@ -8221,9 +8368,9 @@ } }, "node_modules/issue-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", - "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.0.tgz", + "integrity": "sha512-jgAw78HO3gs9UrKqJNQvfDj9Ouy8Mhu40fbEJ8yXff4MW8+/Fcn9iFjyWUQ6SKbX8ipPk3X5A3AyfYHRu6uVLw==", "dev": true, "dependencies": { "lodash.capitalize": "^4.2.1", @@ -8233,7 +8380,7 @@ "lodash.uniqby": "^4.7.0" }, "engines": { - "node": ">=10.13" + "node": "^18.17 || >=20.6.1" } }, "node_modules/istanbul-lib-coverage": { @@ -8313,6 +8460,15 @@ "node": ">= 0.6.0" } }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8479,15 +8635,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8616,12 +8763,6 @@ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, - "node_modules/lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true - }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", @@ -8806,24 +8947,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/map-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", @@ -8847,35 +8970,35 @@ } }, "node_modules/marked": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", - "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", "dev": true, "bin": { "marked": "bin/marked.js" }, "engines": { - "node": ">= 16" + "node": ">= 18" } }, "node_modules/marked-terminal": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.1.0.tgz", - "integrity": "sha512-QaCSF6NV82oo6K0szEnmc65ooDeW0T/Adcyf0fcW+Hto2GT1VADFg8dn1zaeHqzj65fqDH1hMNChGNRaC/lbkA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.0.0.tgz", + "integrity": "sha512-sNEx8nn9Ktcm6pL0TnRz8tnXq/mSS0Q1FRSwJOAqw4lAB4l49UeDf85Gm1n9RPFm5qurCPjwi1StAQT2XExhZw==", "dev": true, "dependencies": { "ansi-escapes": "^6.2.0", - "cardinal": "^2.1.1", "chalk": "^5.3.0", + "cli-highlight": "^2.1.11", "cli-table3": "^0.6.3", - "node-emoji": "^2.1.0", + "node-emoji": "^2.1.3", "supports-hyperlinks": "^3.0.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "marked": ">=1 <11" + "marked": ">=1 <13" } }, "node_modules/mdast-util-find-and-replace": { @@ -9108,37 +9231,12 @@ } }, "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=16.10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9615,15 +9713,18 @@ } }, "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.3.tgz", + "integrity": "sha512-KgUb15Oorc0NEKPbvfa0wRU+PItIEZmiv+pyAO2i0oTIVTJhlzMclU7w4RXWQrSOVH5ax/p/CkIO7KI4OyFJTQ==", "dev": true, + "funding": [ + "https://github.com/sponsors/broofa" + ], "bin": { - "mime": "cli.js" + "mime": "bin/cli.js" }, "engines": { - "node": ">=10.0.0" + "node": ">=16" } }, "node_modules/mime-db": { @@ -9653,15 +9754,6 @@ "node": ">=6" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -9682,20 +9774,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/minipass": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", @@ -9783,11 +9861,21 @@ "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", "funding": [ { "type": "github", @@ -9795,10 +9883,10 @@ } ], "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^18 || >=20" } }, "node_modules/natural-compare": { @@ -9916,24 +10004,24 @@ "dev": true }, "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.1.tgz", + "integrity": "sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ==", "dev": true, "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": ">=10" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", "dev": true, "engines": { "node": ">=14.16" @@ -9943,9 +10031,9 @@ } }, "node_modules/npm": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.2.4.tgz", - "integrity": "sha512-umEuYneVEYO9KoEEI8n2sSGmNQeqco/3BSeacRlqIkCzw4E7XGtYSWMeJobxzr6hZ2n9cM+u5TsMTcC5bAgoWA==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.7.0.tgz", + "integrity": "sha512-FXylyYSXNjgXx3l82BT8RSQvCoGIQ3h8YdRFGKNvo3Pv/bKscK4pdWkx/onwTpHDqGw+oeLf4Rxln9WVyxAxlQ==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -9954,6 +10042,7 @@ "@npmcli/map-workspaces", "@npmcli/package-json", "@npmcli/promise-spawn", + "@npmcli/redact", "@npmcli/run-script", "@sigstore/tuf", "abbrev", @@ -9962,8 +10051,6 @@ "chalk", "ci-info", "cli-columns", - "cli-table3", - "columnify", "fastest-levenshtein", "fs-minipass", "glob", @@ -9999,7 +10086,6 @@ "npm-profile", "npm-registry-fetch", "npm-user-validate", - "npmlog", "p-map", "pacote", "parse-conflict-json", @@ -10009,7 +10095,6 @@ "semver", "spdx-expression-parse", "ssri", - "strip-ansi", "supports-color", "tar", "text-table", @@ -10020,72 +10105,76 @@ "write-file-atomic" ], "dev": true, + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^7.2.1", "@npmcli/config": "^8.0.2", "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.2", - "@sigstore/tuf": "^2.2.0", + "@npmcli/map-workspaces": "^3.0.6", + "@npmcli/package-json": "^5.1.0", + "@npmcli/promise-spawn": "^7.0.1", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", + "@sigstore/tuf": "^2.3.2", "abbrev": "^2.0.0", "archy": "~1.0.0", - "cacache": "^18.0.0", + "cacache": "^18.0.2", "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.3", - "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.3.10", + "glob": "^10.3.12", "graceful-fs": "^4.2.11", "hosted-git-info": "^7.0.1", - "ini": "^4.1.1", - "init-package-json": "^6.0.0", - "is-cidr": "^5.0.3", - "json-parse-even-better-errors": "^3.0.0", + "ini": "^4.1.2", + "init-package-json": "^6.0.2", + "is-cidr": "^5.0.5", + "json-parse-even-better-errors": "^3.0.1", "libnpmaccess": "^8.0.1", "libnpmdiff": "^6.0.3", - "libnpmexec": "^7.0.4", + "libnpmexec": "^8.0.0", "libnpmfund": "^5.0.1", "libnpmhook": "^10.0.0", "libnpmorg": "^6.0.1", - "libnpmpack": "^6.0.3", + "libnpmpack": "^7.0.0", "libnpmpublish": "^9.0.2", "libnpmsearch": "^7.0.0", "libnpmteam": "^6.0.0", - "libnpmversion": "^5.0.1", - "make-fetch-happen": "^13.0.0", - "minimatch": "^9.0.3", + "libnpmversion": "^6.0.0", + "make-fetch-happen": "^13.0.1", + "minimatch": "^9.0.4", "minipass": "^7.0.4", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.0.1", + "node-gyp": "^10.1.0", "nopt": "^7.2.0", "normalize-package-data": "^6.0.0", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.1.0", + "npm-profile": "^9.0.2", + "npm-registry-fetch": "^17.0.0", "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", "p-map": "^4.0.0", - "pacote": "^17.0.4", + "pacote": "^18.0.3", "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "qrcode-terminal": "^0.12.0", - "read": "^2.1.0", - "semver": "^7.5.4", - "spdx-expression-parse": "^3.0.1", + "read": "^3.0.1", + "semver": "^7.6.0", + "spdx-expression-parse": "^4.0.0", "ssri": "^10.0.5", - "strip-ansi": "^7.1.0", "supports-color": "^9.4.0", - "tar": "^6.2.0", + "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", @@ -10113,16 +10202,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/npm/node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -10140,6 +10219,18 @@ "node": ">=12" } }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "dev": true, @@ -10163,6 +10254,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", "dev": true, @@ -10170,7 +10276,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.0", + "version": "2.2.2", "dev": true, "inBundle": true, "license": "ISC", @@ -10179,46 +10285,47 @@ "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.1" + "socks-proxy-agent": "^8.0.3" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.2.1", + "version": "7.5.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/installed-package-contents": "^2.1.0", "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", + "@npmcli/metavuln-calculator": "^7.1.0", "@npmcli/name-from-folder": "^2.0.0", "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/query": "^3.0.1", - "@npmcli/run-script": "^7.0.2", + "@npmcli/package-json": "^5.1.0", + "@npmcli/query": "^3.1.0", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", "hosted-git-info": "^7.0.1", "json-parse-even-better-errors": "^3.0.0", "json-stringify-nice": "^1.1.4", - "minimatch": "^9.0.0", + "minimatch": "^9.0.4", "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", + "npm-registry-fetch": "^17.0.0", + "pacote": "^18.0.1", "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", + "proggy": "^2.0.0", "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.2", + "promise-call-limit": "^3.0.1", "read-package-json-fast": "^3.0.2", "semver": "^7.3.7", "ssri": "^10.0.5", @@ -10233,16 +10340,16 @@ } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.0.2", + "version": "8.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/map-workspaces": "^3.0.2", "ci-info": "^4.0.0", - "ini": "^4.1.0", + "ini": "^4.1.2", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "read-package-json-fast": "^3.0.2", "semver": "^7.3.5", "walk-up-path": "^3.0.1" @@ -10251,33 +10358,6 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/@npmcli/disparity-colors": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ansi-styles": "^4.3.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/npm/node_modules/@npmcli/fs": { "version": "3.1.0", "dev": true, @@ -10291,7 +10371,7 @@ } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.3", + "version": "5.0.6", "dev": true, "inBundle": true, "license": "ISC", @@ -10299,7 +10379,7 @@ "@npmcli/promise-spawn": "^7.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", @@ -10310,7 +10390,7 @@ } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.0.2", + "version": "2.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -10319,14 +10399,14 @@ "npm-normalize-package-bin": "^3.0.0" }, "bin": { - "installed-package-contents": "lib/index.js" + "installed-package-contents": "bin/index.js" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.4", + "version": "3.0.6", "dev": true, "inBundle": true, "license": "ISC", @@ -10341,14 +10421,15 @@ } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.0.0", + "version": "7.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "cacache": "^18.0.0", "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", + "pacote": "^18.0.0", + "proc-log": "^4.1.0", "semver": "^7.3.5" }, "engines": { @@ -10374,7 +10455,7 @@ } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.0.0", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -10384,7 +10465,7 @@ "hosted-git-info": "^7.0.0", "json-parse-even-better-errors": "^3.0.0", "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.5.3" }, "engines": { @@ -10392,7 +10473,7 @@ } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.0", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -10404,7 +10485,7 @@ } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.0.1", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -10415,16 +10496,26 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "7.0.2", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", "@npmcli/promise-spawn": "^7.0.0", "node-gyp": "^10.0.0", - "read-package-json-fast": "^3.0.0", + "proc-log": "^4.0.0", "which": "^4.0.0" }, "engines": { @@ -10442,34 +10533,44 @@ } }, "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.1.0", + "version": "2.3.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1" + "@sigstore/protobuf-specs": "^0.3.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/npm/node_modules/@sigstore/core": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.2.1", + "version": "0.3.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.2.0", + "version": "2.3.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", + "@sigstore/bundle": "^2.3.0", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.1", "make-fetch-happen": "^13.0.0" }, "engines": { @@ -10477,13 +10578,27 @@ } }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.2.0", + "version": "2.3.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.0", + "tuf-js": "^2.2.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "1.2.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1", - "tuf-js": "^2.1.0" + "@sigstore/bundle": "^2.3.1", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -10520,20 +10635,8 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/abort-controller": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/npm/node_modules/agent-base": { - "version": "7.1.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -10558,15 +10661,12 @@ } }, "node_modules/npm/node_modules/ansi-regex": { - "version": "6.0.1", + "version": "5.0.1", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/npm/node_modules/ansi-styles": { @@ -10593,45 +10693,12 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/are-we-there-yet": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^4.1.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/balanced-match": { "version": "1.0.2", "dev": true, "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/base64-js": { - "version": "1.5.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/bin-links": { "version": "4.0.3", "dev": true, @@ -10648,12 +10715,15 @@ } }, "node_modules/npm/node_modules/binary-extensions": { - "version": "2.2.0", + "version": "2.3.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm/node_modules/brace-expansion": { @@ -10665,32 +10735,8 @@ "balanced-match": "^1.0.0" } }, - "node_modules/npm/node_modules/buffer": { - "version": "6.0.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/npm/node_modules/builtins": { - "version": "5.0.1", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -10699,7 +10745,7 @@ } }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.0", + "version": "18.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -10709,7 +10755,7 @@ "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", - "minipass-collect": "^1.0.2", + "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^4.0.0", @@ -10758,7 +10804,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.0.3", + "version": "4.0.5", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -10778,62 +10824,17 @@ "node": ">=6" } }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cli-columns/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cli-columns/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cli-table3": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/npm/node_modules/clone": { - "version": "1.0.4", + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=0.8" + "node": ">= 10" } }, "node_modules/npm/node_modules/cmd-shim": { @@ -10863,61 +10864,12 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/npm/node_modules/columnify/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/columnify/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/common-ancestor-path": { "version": "1.0.1", "dev": true, "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/cross-spawn": { "version": "7.0.3", "dev": true, @@ -10982,26 +10934,8 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/delegates": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/diff": { - "version": "5.1.0", + "version": "5.2.0", "dev": true, "inBundle": true, "license": "BSD-3-Clause", @@ -11046,24 +10980,6 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/event-target-shim": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/events": { - "version": "3.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, "node_modules/npm/node_modules/exponential-backoff": { "version": "3.1.1", "dev": true, @@ -11116,57 +11032,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/npm/node_modules/gauge": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/gauge/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/gauge/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/glob": { - "version": "10.3.10", + "version": "10.3.12", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", + "jackspeak": "^2.3.6", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -11184,14 +11060,8 @@ "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/hasown": { - "version": "2.0.0", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -11221,7 +11091,7 @@ "license": "BSD-2-Clause" }, "node_modules/npm/node_modules/http-proxy-agent": { - "version": "7.0.0", + "version": "7.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -11234,7 +11104,7 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.2", + "version": "7.0.4", "dev": true, "inBundle": true, "license": "MIT", @@ -11259,28 +11129,8 @@ "node": ">=0.10.0" } }, - "node_modules/npm/node_modules/ieee754": { - "version": "1.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "BSD-3-Clause" - }, "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.3", + "version": "6.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -11310,7 +11160,7 @@ } }, "node_modules/npm/node_modules/ini": { - "version": "4.1.1", + "version": "4.1.2", "dev": true, "inBundle": true, "license": "ISC", @@ -11319,15 +11169,15 @@ } }, "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.0", + "version": "6.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@npmcli/package-json": "^5.0.0", "npm-package-arg": "^11.0.0", "promzard": "^1.0.0", - "read": "^2.0.0", - "read-package-json": "^7.0.0", + "read": "^3.0.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^5.0.0" @@ -11336,11 +11186,18 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/ip": { - "version": "2.0.0", + "node_modules/npm/node_modules/ip-address": { + "version": "9.0.5", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } }, "node_modules/npm/node_modules/ip-regex": { "version": "5.0.0", @@ -11355,12 +11212,12 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.0.3", + "version": "5.0.5", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "4.0.3" + "cidr-regex": "^4.0.4" }, "engines": { "node": ">=14" @@ -11417,8 +11274,14 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/npm/node_modules/jsbn": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "MIT", @@ -11457,52 +11320,50 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.1", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0" + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.0.3", + "version": "6.1.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", - "binary-extensions": "^2.2.0", + "@npmcli/installed-package-contents": "^2.1.0", + "binary-extensions": "^2.3.0", "diff": "^5.1.0", - "minimatch": "^9.0.0", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", - "tar": "^6.2.0" + "minimatch": "^9.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1", + "tar": "^6.2.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "7.0.4", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", + "@npmcli/run-script": "^8.1.0", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", - "read": "^2.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1", + "proc-log": "^4.2.0", + "read": "^3.0.1", "read-package-json-fast": "^3.0.2", "semver": "^7.3.7", "walk-up-path": "^3.0.1" @@ -11512,7 +11373,7 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.1", + "version": "5.0.9", "dev": true, "inBundle": true, "license": "ISC", @@ -11524,59 +11385,59 @@ } }, "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.0", + "version": "10.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.1", + "version": "6.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "6.0.3", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" + "@npmcli/run-script": "^8.1.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.2", + "version": "9.0.7", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "ci-info": "^4.0.0", "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.2.0", "semver": "^7.3.7", - "sigstore": "^2.1.0", + "sigstore": "^2.2.0", "ssri": "^10.0.5" }, "engines": { @@ -11584,40 +11445,40 @@ } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.0", + "version": "7.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.0", + "version": "6.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "5.0.1", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", + "@npmcli/git": "^5.0.6", + "@npmcli/run-script": "^8.1.0", "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "semver": "^7.3.7" }, "engines": { @@ -11625,19 +11486,16 @@ } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.0.2", + "version": "10.2.2", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, "engines": { "node": "14 || >=16.14" } }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.0", + "version": "13.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -11651,6 +11509,7 @@ "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", + "proc-log": "^4.2.0", "promise-retry": "^2.0.1", "ssri": "^10.0.0" }, @@ -11659,7 +11518,7 @@ } }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.3", + "version": "9.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -11683,27 +11542,15 @@ } }, "node_modules/npm/node_modules/minipass-collect": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", + "version": "2.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.0.3" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/npm/node_modules/minipass-fetch": { @@ -11879,7 +11726,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.0.1", + "version": "10.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -11902,6 +11749,15 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm/node_modules/nopt": { "version": "7.2.0", "dev": true, @@ -11975,13 +11831,13 @@ } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.1", + "version": "11.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" }, @@ -11990,12 +11846,12 @@ } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.0", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.0" + "ignore-walk": "^6.0.4" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -12017,31 +11873,32 @@ } }, "node_modules/npm/node_modules/npm-profile": { - "version": "9.0.0", + "version": "9.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "16.1.0", + "version": "17.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@npmcli/redact": "^2.0.0", "make-fetch-happen": "^13.0.0", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" + "proc-log": "^4.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -12056,21 +11913,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/npmlog": { - "version": "7.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/p-map": { "version": "4.0.0", "dev": true, @@ -12087,27 +11929,26 @@ } }, "node_modules/npm/node_modules/pacote": { - "version": "17.0.4", + "version": "18.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/git": "^5.0.0", "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", + "@npmcli/run-script": "^8.0.0", "cacache": "^18.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^11.0.0", "npm-packlist": "^8.0.0", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.0.0", + "sigstore": "^2.2.0", "ssri": "^10.0.0", "tar": "^6.1.11" }, @@ -12142,12 +11983,12 @@ } }, "node_modules/npm/node_modules/path-scurry": { - "version": "1.10.1", + "version": "1.10.2", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -12158,7 +11999,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.13", + "version": "6.0.16", "dev": true, "inBundle": true, "license": "MIT", @@ -12171,7 +12012,7 @@ } }, "node_modules/npm/node_modules/proc-log": { - "version": "3.0.0", + "version": "4.2.0", "dev": true, "inBundle": true, "license": "ISC", @@ -12179,13 +12020,13 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/process": { - "version": "0.11.10", + "node_modules/npm/node_modules/proggy": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">= 0.6.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm/node_modules/promise-all-reject-late": { @@ -12198,7 +12039,7 @@ } }, "node_modules/npm/node_modules/promise-call-limit": { - "version": "1.0.2", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -12226,12 +12067,12 @@ } }, "node_modules/npm/node_modules/promzard": { - "version": "1.0.0", + "version": "1.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "read": "^2.0.0" + "read": "^3.0.1" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -12246,12 +12087,12 @@ } }, "node_modules/npm/node_modules/read": { - "version": "2.1.0", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "mute-stream": "~1.0.0" + "mute-stream": "^1.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -12266,21 +12107,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/read-package-json": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, "node_modules/npm/node_modules/read-package-json-fast": { "version": "3.0.2", "dev": true, @@ -12294,22 +12120,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/readable-stream": { - "version": "4.4.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/npm/node_modules/retry": { "version": "0.12.0", "dev": true, @@ -12319,26 +12129,6 @@ "node": ">= 4" } }, - "node_modules/npm/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", "dev": true, @@ -12347,7 +12137,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.5.4", + "version": "7.6.0", "dev": true, "inBundle": true, "license": "ISC", @@ -12373,12 +12163,6 @@ "node": ">=10" } }, - "node_modules/npm/node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/shebang-command": { "version": "2.0.0", "dev": true, @@ -12413,15 +12197,17 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.1.0", + "version": "2.3.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "@sigstore/sign": "^2.1.0", - "@sigstore/tuf": "^2.1.0" + "@sigstore/bundle": "^2.3.1", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.1", + "@sigstore/sign": "^2.3.0", + "@sigstore/tuf": "^2.3.1", + "@sigstore/verify": "^1.2.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -12438,26 +12224,26 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.7.1", + "version": "2.8.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.2", + "version": "8.0.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.1", "debug": "^4.3.4", "socks": "^2.7.1" }, @@ -12475,14 +12261,24 @@ "spdx-license-ids": "^3.0.0" } }, + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.3.0", + "version": "2.5.0", "dev": true, "inBundle": true, "license": "CC-BY-3.0" }, "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", @@ -12492,11 +12288,17 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.16", + "version": "3.0.17", "dev": true, "inBundle": true, "license": "CC0-1.0" }, + "node_modules/npm/node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, "node_modules/npm/node_modules/ssri": { "version": "10.0.5", "dev": true, @@ -12509,15 +12311,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/npm/node_modules/string-width": { "version": "4.2.3", "dev": true, @@ -12547,37 +12340,7 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width/node_modules/strip-ansi": { + "node_modules/npm/node_modules/strip-ansi": { "version": "6.0.1", "dev": true, "inBundle": true, @@ -12589,21 +12352,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/npm/node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", @@ -12617,15 +12365,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/supports-color": { "version": "9.4.0", "dev": true, @@ -12639,7 +12378,7 @@ } }, "node_modules/npm/node_modules/tar": { - "version": "6.2.0", + "version": "6.2.1", "dev": true, "inBundle": true, "license": "ISC", @@ -12710,7 +12449,7 @@ } }, "node_modules/npm/node_modules/tuf-js": { - "version": "2.1.0", + "version": "2.2.0", "dev": true, "inBundle": true, "license": "MIT", @@ -12763,6 +12502,16 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/npm/node_modules/validate-npm-package-name": { "version": "5.0.0", "dev": true, @@ -12781,15 +12530,6 @@ "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/npm/node_modules/which": { "version": "4.0.0", "dev": true, @@ -12814,15 +12554,6 @@ "node": ">=16" } }, - "node_modules/npm/node_modules/wide-align": { - "version": "1.1.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "node_modules/npm/node_modules/wrap-ansi": { "version": "8.1.0", "dev": true, @@ -12858,15 +12589,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, @@ -12882,16 +12604,16 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { @@ -12917,6 +12639,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/npm/node_modules/write-file-atomic": { "version": "5.0.1", "dev": true, @@ -12950,6 +12687,15 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -13158,15 +12904,15 @@ } }, "node_modules/p-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", - "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", + "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", "dev": true, "dependencies": { - "p-map": "^5.1.0" + "p-map": "^7.0.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -13212,70 +12958,12 @@ } }, "node_modules/p-map": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", - "dev": true, - "dependencies": { - "aggregate-error": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "dev": true, - "dependencies": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/clean-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", + "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -13343,6 +13031,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -13582,6 +13291,24 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/preact": { "version": "10.20.2", "resolved": "https://registry.npmjs.org/preact/-/preact-10.20.2.tgz", @@ -13711,15 +13438,6 @@ } ] }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -13748,142 +13466,111 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/read-package-up/node_modules/type-fest": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.2.tgz", + "integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==", "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" + "node": ">=16" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/read-pkg-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", + "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", + "deprecated": "Renamed to read-package-up", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.2.tgz", + "integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "node_modules/read-pkg/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", "dev": true, "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.2.tgz", + "integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/readable-stream": { @@ -13899,28 +13586,6 @@ "node": ">= 6" } }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "dependencies": { - "esprima": "~4.0.0" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -13993,18 +13658,6 @@ "node": ">=8" } }, - "node_modules/resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", - "dev": true, - "dependencies": { - "global-dirs": "^0.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -14188,35 +13841,35 @@ "peer": true }, "node_modules/semantic-release": { - "version": "22.0.8", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.8.tgz", - "integrity": "sha512-55rb31jygqIYsGU/rY+gXXm2fnxBIWo9azOjxbqKsPnq7p70zwZ5v+xnD7TxJC+zvS3sy1eHLGXYWCaX3WI76A==", + "version": "23.1.1", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-23.1.1.tgz", + "integrity": "sha512-qqJDBhbtHsjUEMsojWKGuL5lQFCJuPtiXKEIlFKyTzDDGTAE/oyvznaP8GeOr5PvcqBJ6LQz4JCENWPLeehSpA==", "dev": true, "dependencies": { - "@semantic-release/commit-analyzer": "^11.0.0", + "@semantic-release/commit-analyzer": "^12.0.0", "@semantic-release/error": "^4.0.0", - "@semantic-release/github": "^9.0.0", - "@semantic-release/npm": "^11.0.0", - "@semantic-release/release-notes-generator": "^12.0.0", + "@semantic-release/github": "^10.0.0", + "@semantic-release/npm": "^12.0.0", + "@semantic-release/release-notes-generator": "^13.0.0", "aggregate-error": "^5.0.0", - "cosmiconfig": "^8.0.0", + "cosmiconfig": "^9.0.0", "debug": "^4.0.0", - "env-ci": "^10.0.0", - "execa": "^8.0.0", + "env-ci": "^11.0.0", + "execa": "^9.0.0", "figures": "^6.0.0", - "find-versions": "^5.1.0", + "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", "hook-std": "^3.0.0", "hosted-git-info": "^7.0.0", "import-from-esm": "^1.3.1", "lodash-es": "^4.17.21", - "marked": "^9.0.0", - "marked-terminal": "^6.0.0", + "marked": "^12.0.0", + "marked-terminal": "^7.0.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", - "read-pkg-up": "^11.0.0", + "read-package-up": "^11.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "semver-diff": "^4.0.0", @@ -14227,154 +13880,65 @@ "semantic-release": "bin/semantic-release.js" }, "engines": { - "node": "^18.17 || >=20.6.1" - } - }, - "node_modules/semantic-release/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/semantic-release/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/semantic-release/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "node": ">=20.8.1" + } + }, + "node_modules/semantic-release/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, "engines": { - "node": ">=16.17.0" + "node": ">=18" } }, - "node_modules/semantic-release/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "node_modules/semantic-release/node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/semantic-release/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, + "dependencies": { + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "node_modules/semantic-release/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, "engines": { - "node": "14 || >=16.14" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/semantic-release/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "engines": { "node": ">=12" @@ -14383,112 +13947,103 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", + "node_modules/semantic-release/node_modules/execa": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.0.2.tgz", + "integrity": "sha512-oO281GF7ksH/Ogv1xyDf1prvFta/6/XkGKxRUvA3IB2MU1rCJGlFs86HRZhdooow1ISkR0Np0rOxUCIJVw36Rg==", "dev": true, "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.3", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^7.0.0", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^5.2.0", + "pretty-ms": "^9.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/semantic-release/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, "dependencies": { - "path-key": "^4.0.0" + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/semantic-release/node_modules/human-signals": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-7.0.0.tgz", + "integrity": "sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==", "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18.18.0" } }, - "node_modules/semantic-release/node_modules/parse-json": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", - "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "node_modules/semantic-release/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "index-to-position": "^0.1.2", - "type-fest": "^4.7.1" - }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/semantic-release/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/read-pkg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", - "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "node_modules/semantic-release/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.3", - "normalize-package-data": "^6.0.0", - "parse-json": "^8.0.0", - "type-fest": "^4.6.0", - "unicorn-magic": "^0.1.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">=18" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/read-pkg-up": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", - "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", - "deprecated": "Renamed to read-package-up", + "node_modules/semantic-release/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "dependencies": { - "find-up-simple": "^1.0.0", - "read-pkg": "^9.0.0", - "type-fest": "^4.6.0" - }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -14507,24 +14062,12 @@ } }, "node_modules/semantic-release/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "dev": true, "engines": { - "node": ">=16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -14915,12 +14458,12 @@ } }, "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, - "dependencies": { - "readable-stream": "^3.0.0" + "engines": { + "node": ">= 10.x" } }, "node_modules/stackback": { @@ -15221,18 +14764,6 @@ "node": ">=6" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -15263,6 +14794,22 @@ "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", "dev": true }, + "node_modules/super-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.0.0.tgz", + "integrity": "sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==", + "dev": true, + "dependencies": { + "function-timeout": "^1.0.1", + "time-span": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -15416,12 +14963,15 @@ } }, "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", "dev": true, "engines": { - "node": ">=0.10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/text-table": { @@ -15430,19 +14980,46 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "node_modules/time-span": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", + "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", "dev": true, "dependencies": { - "readable-stream": "3" + "convert-hrtime": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/tinybench": { @@ -15518,15 +15095,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -15539,49 +15107,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -16024,24 +15549,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -16066,6 +15573,14 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/vfile": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", @@ -16752,15 +16267,6 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -16773,6 +16279,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.0.0.tgz", + "integrity": "sha512-esbDnt0Z1zI1KgvOZU90hJbL6BkoUbrP9yy7ArNZ6TmxBxydMJTYMf9FZjmwwcA8ZgEQzriQ3hwZ0NYXhlFo8Q==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 8db356b9..bb8fd13a 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,15 @@ "name": "node-llama-cpp", "version": "0.1.0", "description": "Run AI models locally on your machine with node.js bindings for llama.cpp. Force a JSON schema on the model output on the generation level", - "main": "dist/index.js", + "main": "./dist/index.js", "type": "module", "types": "./dist/index.d.ts", "bin": { - "node-llama-cpp": "./dist/cli/cli.js" + "node-llama-cpp": "dist/cli/cli.js" }, "files": [ "dist/", + "templates/packed/", "llama/", "llamaBins/", "package.json", @@ -41,8 +42,10 @@ }, "scripts": { "prepare": "[ \"$CI\" = true ] || [ -d '.husky/_' ] || husky install", + "postinstall": "cd templates && npm install", "prebuild": "rimraf ./dist ./tsconfig.tsbuildinfo", - "build": "tsc --build tsconfig.json --force", + "build": "tsc --build tsconfig.json --force && npm run build:packTemplates", + "build:packTemplates": "vite-node scripts/packTemplates.ts", "addPostinstallScript": "npm pkg set scripts.postinstall=\"node ./dist/cli/cli.js postinstall\"", "prewatch": "rimraf ./dist ./tsconfig.tsbuildinfo", "watch": "tsc --build tsconfig.json --watch --force", @@ -55,12 +58,12 @@ "test:modelDependent:interactive": "vitest watch ./test/modelDependent", "test:typescript": "tsc --build tsconfig.json --dry --force", "lint": "npm run lint:eslint", - "lint:eslint": "eslint --ext .js --ext .ts .", + "lint:eslint": "eslint --ext .js --ext .ts --report-unused-disable-directives .", "format": "npm run lint:eslint -- --fix", "dev:setup:downloadAllTestModels": "vite-node test/utils/scripts/downloadAllTestModels.ts", "dev:setup": "npm run build && node ./dist/cli/cli.js download --noUsageExample && npm run docs:generateTypedoc && npm run dev:setup:downloadAllTestModels", "dev:build": "npm run build && node ./dist/cli/cli.js build --noUsageExample", - "clean": "rm -rf ./node_modules ./dist ./tsconfig.tsbuildinfo ./test/.models ./docs/api ./docs/api-overrides", + "clean": "rm -rf ./node_modules ./dist ./tsconfig.tsbuildinfo ./test/.models ./docs/api ./docs/api-overrides ./templates/packed", "docs:generateTypedoc": "typedoc && rimraf ./docs/api/index.md ./docs/api/globals.md ./docs/api/functions/LlamaText.md && npm run docs:generateTypedoc:overrides", "docs:generateTypedoc:overrides": "typedoc --entryPoints ./src/apiDocsOverrides.ts --out ./docs/api-overrides && copyfiles --flat \"./docs/api-overrides/classes/LlamaText.md\" ./docs/api/classes && rimraf ./docs/api-overrides", "docs:dev": "npm run docs:generateTypedoc && vitepress dev", @@ -112,8 +115,8 @@ }, "homepage": "https://withcatai.github.io/node-llama-cpp/", "devDependencies": { - "@commitlint/cli": "^17.7.1", - "@commitlint/config-conventional": "^17.7.0", + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", "@semantic-release/exec": "^6.0.3", "@shikijs/vitepress-twoslash": "^1.3.0", "@types/async-retry": "^1.4.8", @@ -123,7 +126,7 @@ "@types/node": "^20.11.29", "@types/proper-lockfile": "^4.1.4", "@types/semver": "^7.5.8", - "@types/uuid": "^9.0.2", + "@types/validate-npm-package-name": "^4.0.2", "@types/which": "^3.0.0", "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^6.3.0", @@ -137,7 +140,7 @@ "eslint-plugin-n": "^16.3.1", "husky": "^8.0.3", "rimraf": "^5.0.1", - "semantic-release": "^22.0.8", + "semantic-release": "^23.1.1", "tslib": "^2.6.1", "typedoc": "^0.25.13", "typedoc-plugin-markdown": "^4.0.0-next.55", @@ -161,10 +164,12 @@ "env-var": "^7.3.1", "filenamify": "^6.0.0", "fs-extra": "^11.2.0", + "ignore": "^5.3.1", "ipull": "^3.1.1", "is-unicode-supported": "^2.0.0", "lifecycle-utils": "^1.4.1", "log-symbols": "^5.1.0", + "nanoid": "^5.0.7", "node-addon-api": "^7.0.0", "octokit": "^3.1.0", "ora": "^7.0.1", @@ -175,7 +180,7 @@ "slice-ansi": "^7.1.0", "stdout-update": "^4.0.1", "strip-ansi": "^7.1.0", - "uuid": "^9.0.0", + "validate-npm-package-name": "^5.0.1", "which": "^4.0.0", "yargs": "^17.7.2" }, diff --git a/packages/create-node-llama-cpp/.gitignore b/packages/create-node-llama-cpp/.gitignore new file mode 100644 index 00000000..9b1c8b13 --- /dev/null +++ b/packages/create-node-llama-cpp/.gitignore @@ -0,0 +1 @@ +/dist diff --git a/packages/create-node-llama-cpp/LICENSE b/packages/create-node-llama-cpp/LICENSE new file mode 100644 index 00000000..22789ae3 --- /dev/null +++ b/packages/create-node-llama-cpp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Gilad S. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/create-node-llama-cpp/README.md b/packages/create-node-llama-cpp/README.md new file mode 100644 index 00000000..49958d66 --- /dev/null +++ b/packages/create-node-llama-cpp/README.md @@ -0,0 +1,12 @@ +# `create-node-llama-cpp` +## Scaffold a new [`node-llama-cpp`](https://www.npmjs.com/package/node-llama-cpp) project from a template +```bash +npm create node-llama-cpp@latest +``` + +And then follow the prompts. + +You can directly specify the project name you want to use via the command line: +```bash +npm create node-llama-cpp@latest my-project +``` diff --git a/packages/create-node-llama-cpp/package-lock.json b/packages/create-node-llama-cpp/package-lock.json new file mode 100644 index 00000000..b9cf550e --- /dev/null +++ b/packages/create-node-llama-cpp/package-lock.json @@ -0,0 +1,138 @@ +{ + "name": "create-node-llama-cpp", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "create-node-llama-cpp", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "node-llama-cpp": "file:../.." + }, + "bin": { + "create-node-llama-cpp": "dist/cli.js" + }, + "devDependencies": { + "typescript": "^5.2.2" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/giladgd" + } + }, + "../..": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@huggingface/jinja": "^0.2.2", + "async-retry": "^1.3.3", + "bytes": "^3.1.2", + "chalk": "^5.3.0", + "chmodrp": "^1.0.2", + "cmake-js": "^7.3.0", + "cross-env": "^7.0.3", + "cross-spawn": "^7.0.3", + "env-var": "^7.3.1", + "filenamify": "^6.0.0", + "fs-extra": "^11.2.0", + "ignore": "^5.3.1", + "ipull": "^3.1.1", + "is-unicode-supported": "^2.0.0", + "lifecycle-utils": "^1.4.1", + "log-symbols": "^5.1.0", + "nanoid": "^5.0.7", + "node-addon-api": "^7.0.0", + "octokit": "^3.1.0", + "ora": "^7.0.1", + "pretty-ms": "^9.0.0", + "proper-lockfile": "^4.1.2", + "semver": "^7.6.0", + "simple-git": "^3.19.1", + "slice-ansi": "^7.1.0", + "stdout-update": "^4.0.1", + "strip-ansi": "^7.1.0", + "validate-npm-package-name": "^5.0.1", + "which": "^4.0.0", + "yargs": "^17.7.2" + }, + "bin": { + "node-llama-cpp": "dist/cli/cli.js" + }, + "devDependencies": { + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", + "@semantic-release/exec": "^6.0.3", + "@shikijs/vitepress-twoslash": "^1.3.0", + "@types/async-retry": "^1.4.8", + "@types/bytes": "^3.1.4", + "@types/cross-spawn": "^6.0.2", + "@types/fs-extra": "^11.0.4", + "@types/node": "^20.11.29", + "@types/proper-lockfile": "^4.1.4", + "@types/semver": "^7.5.8", + "@types/validate-npm-package-name": "^4.0.2", + "@types/which": "^3.0.0", + "@types/yargs": "^17.0.24", + "@typescript-eslint/eslint-plugin": "^6.3.0", + "@typescript-eslint/parser": "^6.3.0", + "@vitest/coverage-v8": "^1.4.0", + "@vitest/ui": "^1.4.0", + "copyfiles": "^2.4.1", + "eslint": "^8.46.0", + "eslint-plugin-import": "^2.28.0", + "eslint-plugin-jsdoc": "^46.9.0", + "eslint-plugin-n": "^16.3.1", + "husky": "^8.0.3", + "rimraf": "^5.0.1", + "semantic-release": "^23.1.1", + "tslib": "^2.6.1", + "typedoc": "^0.25.13", + "typedoc-plugin-markdown": "^4.0.0-next.55", + "typedoc-plugin-mdn-links": "^3.1.24", + "typedoc-vitepress-theme": "1.0.0-next.10", + "typescript": "^5.2.2", + "vite-node": "^1.4.0", + "vitepress": "^1.1.4", + "vitest": "^1.4.0", + "zx": "^7.2.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/giladgd" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/node-llama-cpp": { + "resolved": "../..", + "link": true + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + } + } +} diff --git a/packages/create-node-llama-cpp/package.json b/packages/create-node-llama-cpp/package.json new file mode 100644 index 00000000..004c5735 --- /dev/null +++ b/packages/create-node-llama-cpp/package.json @@ -0,0 +1,56 @@ +{ + "name": "create-node-llama-cpp", + "version": "0.1.0", + "description": "Scaffold a new node-llama-cpp project from a template", + "main": "dist/index.js", + "type": "module", + "types": "./dist/index.d.ts", + "bin": { + "create-node-llama-cpp": "dist/cli.js" + }, + "files": [ + "dist/", + "package.json", + "README.md", + "LICENSE" + ], + "exports": { + ".": { + "import": "./dist/index.js", + "node": "./dist/index.js", + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "engines": { + "node": ">=18.0.0" + }, + "scripts": { + "prebuild": "rimraf ./dist ./tsconfig.tsbuildinfo", + "build": "tsc --build tsconfig.json --force", + "prewatch": "rimraf ./dist ./tsconfig.tsbuildinfo", + "watch": "tsc --build tsconfig.json --watch --force", + "clean": "rm -rf ./node_modules ./dist ./tsconfig.tsbuildinfo" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/withcatai/node-llama-cpp.git" + }, + "keywords": [], + "author": "Gilad S.", + "license": "MIT", + "bugs": { + "url": "https://github.com/withcatai/node-llama-cpp/issues" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/giladgd" + }, + "homepage": "https://withcatai.github.io/node-llama-cpp/", + "devDependencies": { + "typescript": "^5.2.2" + }, + "dependencies": { + "node-llama-cpp": "file:../.." + } +} diff --git a/packages/create-node-llama-cpp/src/cli.ts b/packages/create-node-llama-cpp/src/cli.ts new file mode 100755 index 00000000..531508f4 --- /dev/null +++ b/packages/create-node-llama-cpp/src/cli.ts @@ -0,0 +1,19 @@ +#!/usr/bin/env node + +import path from "path"; +import {fileURLToPath} from "url"; +import fs from "node:fs/promises"; +// @ts-ignore +import {_startCreateCli} from "node-llama-cpp/commands"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const packageJson = JSON.parse(await fs.readFile(path.join(__dirname, "..", "package.json"), "utf8")); + +_startCreateCli({ + cliBinName: packageJson.name, + packageVersion: packageJson.version, + _enable: Symbol.for("internal") +}); + +export {}; diff --git a/packages/create-node-llama-cpp/src/index.ts b/packages/create-node-llama-cpp/src/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/create-node-llama-cpp/src/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/create-node-llama-cpp/tsconfig.json b/packages/create-node-llama-cpp/tsconfig.json new file mode 100644 index 00000000..2dd4bffc --- /dev/null +++ b/packages/create-node-llama-cpp/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "lib": ["es2022"], + "module": "es2022", + "target": "es2022", + "esModuleInterop": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitOverride": true, + "removeComments": false, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "moduleResolution": "node", + "resolveJsonModule": false, + "strictNullChecks": true, + "isolatedModules": true, + "noEmit": false, + "outDir": "./dist", + "strict": true, + "sourceMap": true, + "composite": false, + "declaration": true, + "stripInternal": true + }, + "files": [ + "./src/index.ts" + ], + "include": [ + "./src" + ] +} diff --git a/scripts/packTemplates.ts b/scripts/packTemplates.ts new file mode 100644 index 00000000..8dae0e9b --- /dev/null +++ b/scripts/packTemplates.ts @@ -0,0 +1,111 @@ +import path from "path"; +import fs from "fs-extra"; +import ignore, {Ignore} from "ignore"; +import { + getProjectTemplateParameterText, PackagedFileEntry, ProjectTemplate, ProjectTemplateParameter +} from "../src/cli/utils/projectTemplates.js"; +import {packedProjectTemplatesDirectory, projectTemplatesDirectory} from "../src/config.js"; + +const packedTemplatedDirectoryName = path.basename(packedProjectTemplatesDirectory); + +async function packTemplates() { + await fs.ensureDir(packedProjectTemplatesDirectory); + + for (const item of await fs.readdir(projectTemplatesDirectory, {withFileTypes: true})) { + if (!item.isDirectory()) + continue; + + if (item.name === packedTemplatedDirectoryName) + continue; + + await packTemplate(item.name); + } +} + +async function packTemplate(templateName: string) { + const templateDirectory = path.join(projectTemplatesDirectory, templateName); + const gitignorePath = path.join(templateDirectory, ".gitignore"); + const ig = (await fs.pathExists(gitignorePath)) + ? ignore().add(await fs.readFile(gitignorePath, "utf-8")) + : ignore(); + + const files: PackagedFileEntry[] = []; + + await packDirectory({ + files, ig, currentPath: [], templateDirectory + }); + + const templateFile: ProjectTemplate = { + files + }; + + await fs.writeFile(path.join(packedProjectTemplatesDirectory, `${templateName}.json`), JSON.stringify(templateFile)); +} + +async function packDirectory({ + files, ig, currentPath, templateDirectory +}: { + files: PackagedFileEntry[], + ig: Ignore, + currentPath: string[], + templateDirectory: string +}) { + for (const item of await fs.readdir(path.join(templateDirectory, ...currentPath), {withFileTypes: true})) { + const packItemPath = [...currentPath, item.name]; + const itemPath = path.join(templateDirectory, ...packItemPath); + + if (ig.ignores(path.relative(templateDirectory, itemPath))) + continue; + + if (item.isDirectory()) { + await packDirectory({ + files, ig, currentPath: packItemPath, templateDirectory + }); + } else { + const fileContent = await fs.readFile(itemPath, "utf-8"); + const packItem: PackagedFileEntry = { + path: packItemPath, + content: fileContent + }; + transformPackedItem(packItem); + + files.push(packItem); + } + } +} + +async function clearPackedTemplates() { + await fs.remove(packedProjectTemplatesDirectory); +} + +function transformPackedItem(item: PackagedFileEntry) { + if (item.path.length === 1 && item.path[0] === "package.json") { + const packageJson = JSON.parse(item.content); + const moduleName = "node-llama-cpp"; + + if (packageJson.dependencies?.[moduleName]) + packageJson.dependencies[moduleName] = + "^" + getProjectTemplateParameterText(ProjectTemplateParameter.CurrentModuleVersion, 1); + + if (packageJson.devDependencies?.[moduleName]) + packageJson.devDependencies[moduleName] = + "^" + getProjectTemplateParameterText(ProjectTemplateParameter.CurrentModuleVersion, 1); + + const newScripts: Record = {}; + for (const [scriptName, scriptCommand] of (Object.entries(packageJson.scripts) as [string, string][])) { + let transformedScriptName = scriptName; + if (transformedScriptName.startsWith("_")) + transformedScriptName = transformedScriptName.slice("_".length); + + newScripts[transformedScriptName] = scriptCommand; + } + packageJson.scripts = newScripts; + + item.content = JSON.stringify(packageJson, null, 2); + } +} + +export {}; + +await clearPackedTemplates(); +await packTemplates(); diff --git a/scripts/prepareCreateNodeLlamaCppModuleForPublish.ts b/scripts/prepareCreateNodeLlamaCppModuleForPublish.ts new file mode 100644 index 00000000..d37549cf --- /dev/null +++ b/scripts/prepareCreateNodeLlamaCppModuleForPublish.ts @@ -0,0 +1,27 @@ +import path from "path"; +import {fileURLToPath} from "url"; +import yargs from "yargs"; +import {hideBin} from "yargs/helpers"; +import fs from "fs-extra"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const createPackageModulePackageJsonPath = path.join(__dirname, "..", "packages", "create-node-llama-cpp", "package.json"); + +const argv = await yargs(hideBin(process.argv)) + .option("packageVersion", { + type: "string", + demandOption: true + }) + .argv; + +const {packageVersion} = argv; +if (packageVersion === "") + throw new Error("packageVersion is empty"); + +const packageJson = await fs.readJson(createPackageModulePackageJsonPath); +packageJson.version = packageVersion; +packageJson.dependencies["node-llama-cpp"] = packageVersion; +delete packageJson.devDependencies; + +await fs.writeJson(createPackageModulePackageJsonPath, packageJson, {spaces: 2}); +console.info(`Updated "create-node-llama-cpp/package.json" to version "${packageVersion}"`); diff --git a/src/bindings/AddonTypes.ts b/src/bindings/AddonTypes.ts index 6709809d..1e8c7a65 100644 --- a/src/bindings/AddonTypes.ts +++ b/src/bindings/AddonTypes.ts @@ -65,6 +65,7 @@ export type BindingModule = { export type AddonModel = { init(): Promise, + loadLora(loraFilePath: string, scale: number, threads: number, baseModelPath?: string): Promise, abortActiveModelLoad(): void, dispose(): Promise, tokenize(text: string, specialTokens: boolean): Uint32Array, diff --git a/src/bindings/Llama.ts b/src/bindings/Llama.ts index 46501776..7b7eff49 100644 --- a/src/bindings/Llama.ts +++ b/src/bindings/Llama.ts @@ -30,6 +30,7 @@ export class Llama { /** @internal */ public readonly _consts: ReturnType; /** @internal */ public readonly _vramOrchestrator: MemoryOrchestrator; /** @internal */ public readonly _vramPadding: MemoryReservation; + /** @internal */ public readonly _debug: boolean; /** @internal */ private readonly _gpu: BuildGpu; /** @internal */ private readonly _buildType: "localBuild" | "prebuilt"; /** @internal */ private readonly _cmakeOptions: Readonly>; @@ -53,7 +54,7 @@ export class Llama { public readonly onDispose = new EventRelay(); private constructor({ - bindings, logLevel, logger, buildType, cmakeOptions, llamaCppRelease, vramPadding + bindings, logLevel, logger, buildType, cmakeOptions, llamaCppRelease, vramPadding, debug }: { bindings: BindingModule, logLevel: LlamaLogLevel, @@ -64,7 +65,8 @@ export class Llama { repo: string, release: string }, - vramPadding: number | ((totalVram: number) => number) + vramPadding: number | ((totalVram: number) => number), + debug: boolean }) { this._bindings = bindings; this._gpu = bindings.getGpuType() ?? false; @@ -72,6 +74,7 @@ export class Llama { this._supportsMmap = bindings.getSupportsMmap(); this._supportsMlock = bindings.getSupportsMlock(); this._consts = bindings.getConsts(); + this._debug = debug; this._vramOrchestrator = new MemoryOrchestrator(() => { const {total, used} = bindings.getGpuVramInfo(); @@ -89,7 +92,9 @@ export class Llama { else this._vramPadding = this._vramOrchestrator.reserveMemory(vramPadding); - this._logLevel = logLevel ?? LlamaLogLevel.debug; + this._logLevel = this._debug + ? LlamaLogLevel.debug + : (logLevel ?? LlamaLogLevel.debug); this._logger = logger; this._buildType = buildType; this._cmakeOptions = Object.freeze({...cmakeOptions}); @@ -101,8 +106,10 @@ export class Llama { this._dispatchPendingLogMicrotask = this._dispatchPendingLogMicrotask.bind(this); this._onAddonLog = this._onAddonLog.bind(this); - this._bindings.setLogger(this._onAddonLog); - this._bindings.setLoggerLogLevel(LlamaLogLevelToAddonLogLevel.get(this._logLevel) ?? defaultLogLevel); + if (!this._debug) { + this._bindings.setLogger(this._onAddonLog); + this._bindings.setLoggerLogLevel(LlamaLogLevelToAddonLogLevel.get(this._logLevel) ?? defaultLogLevel); + } this._onExit = this._onExit.bind(this); @@ -151,7 +158,7 @@ export class Llama { public set logLevel(value: LlamaLogLevel) { this._ensureNotDisposed(); - if (value === this._logLevel) + if (value === this._logLevel || this._debug) return; this._bindings.setLoggerLogLevel(LlamaLogLevelToAddonLogLevel.get(value) ?? defaultLogLevel); @@ -337,7 +344,7 @@ export class Llama { /** @internal */ public static async _create({ - bindings, buildType, buildMetadata, logLevel, logger, vramPadding, skipLlamaInit = false + bindings, buildType, buildMetadata, logLevel, logger, vramPadding, skipLlamaInit = false, debug }: { bindings: BindingModule, buildType: "localBuild" | "prebuilt", @@ -345,7 +352,8 @@ export class Llama { logLevel: LlamaLogLevel, logger: (level: LlamaLogLevel, message: string) => void, vramPadding: number | ((totalVram: number) => number), - skipLlamaInit?: boolean + skipLlamaInit?: boolean, + debug: boolean }) { const llama = new Llama({ bindings, @@ -357,7 +365,8 @@ export class Llama { }, logLevel, logger, - vramPadding + vramPadding, + debug }); if (!skipLlamaInit) diff --git a/src/bindings/getLlama.ts b/src/bindings/getLlama.ts index 149006fd..6772164c 100644 --- a/src/bindings/getLlama.ts +++ b/src/bindings/getLlama.ts @@ -3,8 +3,8 @@ import path from "path"; import console from "console"; import {createRequire} from "module"; import { - builtinLlamaCppGitHubRepo, builtinLlamaCppRelease, defaultLlamaCppDebugLogs, defaultLlamaCppGitHubRepo, defaultLlamaCppGpuSupport, - defaultLlamaCppRelease, defaultSkipDownload, llamaLocalBuildBinsDirectory, recommendedBaseDockerImage + builtinLlamaCppGitHubRepo, builtinLlamaCppRelease, defaultLlamaCppLogLevel, defaultLlamaCppGitHubRepo, defaultLlamaCppGpuSupport, + defaultLlamaCppRelease, defaultSkipDownload, llamaLocalBuildBinsDirectory, recommendedBaseDockerImage, defaultLlamaCppDebugMode } from "../config.js"; import {getConsoleLogPrefix} from "../utils/getConsoleLogPrefix.js"; import {waitForLockfileRelease} from "../utils/waitForLockfileRelease.js"; @@ -115,7 +115,17 @@ export type LlamaOptions = { * Defaults to `1.5%` of the total VRAM or 300MB, whichever is lower. * Set to `0` to disable. */ - vramPadding?: number | ((totalVram: number) => number) + vramPadding?: number | ((totalVram: number) => number), + + /** + * Enable debug mode to find issues with llama.cpp. + * Makes logs print directly to the console from `llama.cpp` and not through the provided logger. + * + * Defaults to `false`. + * + * The default can be set using the `NODE_LLAMA_CPP_DEBUG` environment variable. + */ + debug?: boolean }; export type LastBuildOptions = { @@ -158,7 +168,17 @@ export type LastBuildOptions = { * Defaults to `6%` of the total VRAM or 300MB, whichever is lower. * Set to `0` to disable. */ - vramPadding?: number | ((totalVram: number) => number) + vramPadding?: number | ((totalVram: number) => number), + + /** + * Enable debug mode to find issues with llama.cpp. + * Makes logs print directly to the console from `llama.cpp` and not through the provided logger. + * + * Defaults to `false`. + * + * The default can be set using the `NODE_LLAMA_CPP_DEBUG` environment variable. + */ + debug?: boolean }; export const getLlamaFunctionName = "getLlama"; @@ -173,18 +193,19 @@ const defaultBuildOption: Exclude = runningInE * Defaults to prefer a prebuilt binary, and fallbacks to building from source if a prebuilt binary is not found. * Pass `"lastCliBuild"` to default to use the last successful build created using the `download` or `build` CLI commands if one exists. */ -export async function getLlama(options?: LlamaOptions): Promise; export async function getLlama(type: "lastBuild", lastBuildOptions?: LastBuildOptions): Promise; +export async function getLlama(options?: LlamaOptions): Promise; export async function getLlama(options?: LlamaOptions | "lastBuild", lastBuildOptions?: LastBuildOptions) { if (options === "lastBuild") { const lastBuildInfo = await getLastBuildInfo(); const getLlamaOptions: LlamaOptions = { - logLevel: lastBuildOptions?.logLevel ?? defaultLlamaCppDebugLogs, + logLevel: lastBuildOptions?.logLevel ?? defaultLlamaCppLogLevel, logger: lastBuildOptions?.logger ?? Llama.defaultConsoleLogger, usePrebuiltBinaries: lastBuildOptions?.usePrebuiltBinaries ?? true, progressLogs: lastBuildOptions?.progressLogs ?? true, skipDownload: lastBuildOptions?.skipDownload ?? defaultSkipDownload, - vramPadding: lastBuildOptions?.vramPadding ?? defaultLlamaVramPadding + vramPadding: lastBuildOptions?.vramPadding ?? defaultLlamaVramPadding, + debug: lastBuildOptions?.debug ?? defaultLlamaCppDebugMode }; if (lastBuildInfo == null) @@ -204,8 +225,9 @@ export async function getLlama(options?: LlamaOptions | "lastBuild", lastBuildOp buildType: "localBuild", buildMetadata, logger: lastBuildOptions?.logger ?? Llama.defaultConsoleLogger, - logLevel: lastBuildOptions?.logLevel ?? defaultLlamaCppDebugLogs, - vramPadding: lastBuildOptions?.vramPadding ?? defaultLlamaVramPadding + logLevel: lastBuildOptions?.logLevel ?? defaultLlamaCppLogLevel, + vramPadding: lastBuildOptions?.vramPadding ?? defaultLlamaVramPadding, + debug: lastBuildOptions?.debug ?? defaultLlamaCppDebugMode }); } catch (err) { console.error(getConsoleLogPrefix() + "Failed to load last build. Error:", err); @@ -221,7 +243,7 @@ export async function getLlama(options?: LlamaOptions | "lastBuild", lastBuildOp export async function getLlamaForOptions({ gpu = defaultLlamaCppGpuSupport, - logLevel = defaultLlamaCppDebugLogs, + logLevel = defaultLlamaCppLogLevel, logger = Llama.defaultConsoleLogger, build = defaultBuildOption, cmakeOptions = {}, @@ -229,7 +251,8 @@ export async function getLlamaForOptions({ usePrebuiltBinaries = true, progressLogs = true, skipDownload = defaultSkipDownload, - vramPadding = defaultLlamaVramPadding + vramPadding = defaultLlamaVramPadding, + debug = defaultLlamaCppDebugMode }: LlamaOptions, { updateLastBuildInfoOnCompile = false, skipLlamaInit = false @@ -240,7 +263,7 @@ export async function getLlamaForOptions({ const platform = getPlatform(); const arch = process.arch; - if (logLevel == null) logLevel = defaultLlamaCppDebugLogs; + if (logLevel == null) logLevel = defaultLlamaCppLogLevel; if (logger == null) logger = Llama.defaultConsoleLogger; if (build == null) build = defaultBuildOption; if (cmakeOptions == null) cmakeOptions = {}; @@ -249,6 +272,7 @@ export async function getLlamaForOptions({ if (progressLogs == null) progressLogs = true; if (skipDownload == null) skipDownload = defaultSkipDownload; if (vramPadding == null) vramPadding = defaultLlamaVramPadding; + if (debug == null) debug = defaultLlamaCppDebugMode; const clonedLlamaCppRepoReleaseInfo = await getClonedLlamaCppRepoReleaseInfo(); let canUsePrebuiltBinaries = (build === "forceRebuild" || !usePrebuiltBinaries) @@ -303,7 +327,8 @@ export async function getLlamaForOptions({ canBuild ? "falling back to building from source" : null - ) + ), + debug }); if (llama != null) @@ -353,7 +378,8 @@ export async function getLlamaForOptions({ logger, updateLastBuildInfoOnCompile, vramPadding, - skipLlamaInit + skipLlamaInit, + debug }); } catch (err) { console.error( @@ -387,7 +413,8 @@ async function loadExistingLlamaBinary({ platformInfo, skipLlamaInit, vramPadding, - fallbackMessage + fallbackMessage, + debug }: { buildOptions: BuildOptions, canUsePrebuiltBinaries: boolean, @@ -399,7 +426,8 @@ async function loadExistingLlamaBinary({ platformInfo: BinaryPlatformInfo, skipLlamaInit: boolean, vramPadding: Required["vramPadding"], - fallbackMessage: string | null + fallbackMessage: string | null, + debug: boolean }) { const buildFolderName = await getBuildFolderNameForBuildOptions(buildOptions); @@ -430,7 +458,8 @@ async function loadExistingLlamaBinary({ logLevel, logger, vramPadding, - skipLlamaInit + skipLlamaInit, + debug }); } else if (progressLogs) { console.warn( @@ -483,7 +512,8 @@ async function loadExistingLlamaBinary({ logLevel, logger, vramPadding, - skipLlamaInit + skipLlamaInit, + debug }); } else if (progressLogs) console.warn( @@ -527,7 +557,8 @@ async function buildAndLoadLlamaBinary({ logger, updateLastBuildInfoOnCompile, vramPadding, - skipLlamaInit + skipLlamaInit, + debug }: { buildOptions: BuildOptions, skipDownload: boolean, @@ -535,7 +566,8 @@ async function buildAndLoadLlamaBinary({ logger: Required["logger"], updateLastBuildInfoOnCompile: boolean, vramPadding: Required["vramPadding"], - skipLlamaInit: boolean + skipLlamaInit: boolean, + debug: boolean }) { const buildFolderName = await getBuildFolderNameForBuildOptions(buildOptions); @@ -564,7 +596,8 @@ async function buildAndLoadLlamaBinary({ logLevel, logger, vramPadding, - skipLlamaInit + skipLlamaInit, + debug }); } diff --git a/src/bindings/utils/detectAvailableComputeLayers.ts b/src/bindings/utils/detectAvailableComputeLayers.ts index 5c508507..66356d70 100644 --- a/src/bindings/utils/detectAvailableComputeLayers.ts +++ b/src/bindings/utils/detectAvailableComputeLayers.ts @@ -80,6 +80,8 @@ async function detectCudaSupport({ "/usr/lib", "/usr/lib64", "/usr/lib/x86_64-linux-gnu", + "/usr/lib/aarch64-linux-gnu", + "/usr/lib/armv7l-linux-gnu", ...cudaLibraryPaths ]; @@ -148,6 +150,8 @@ async function detectVulkanSupport({ "/usr/lib", "/usr/lib64", "/usr/lib/x86_64-linux-gnu", + "/usr/lib/aarch64-linux-gnu", + "/usr/lib/armv7l-linux-gnu", (process.env.PREFIX != null && process.env.PREFIX?.toLowerCase()?.includes?.("termux")) ? `${process.env.PREFIX}/usr/lib` : undefined diff --git a/src/bindings/utils/detectGlibc.ts b/src/bindings/utils/detectGlibc.ts index aa2675f3..84365694 100644 --- a/src/bindings/utils/detectGlibc.ts +++ b/src/bindings/utils/detectGlibc.ts @@ -16,7 +16,9 @@ export async function detectGlibc({ "/lib64", "/usr/lib", "/usr/lib64", - "/usr/lib/x86_64-linux-gnu" + "/usr/lib/x86_64-linux-gnu", + "/usr/lib/aarch64-linux-gnu", + "/usr/lib/armv7l-linux-gnu" ]; return await asyncEvery([ @@ -34,7 +36,15 @@ export async function detectGlibc({ hasFileInPath("ld-linux-x86-64.so", librarySearchPaths), hasFileInPath("ld-linux-x86-64.so.1", librarySearchPaths), hasFileInPath("ld-linux-x86-64.so.2", librarySearchPaths), - hasFileInPath("ld-linux-x86-64.so.3", librarySearchPaths) // for when the next version comes out + hasFileInPath("ld-linux-x86-64.so.3", librarySearchPaths), // for when the next version comes out + hasFileInPath("ld-linux-aarch64.so", librarySearchPaths), + hasFileInPath("ld-linux-aarch64.so.1", librarySearchPaths), + hasFileInPath("ld-linux-aarch64.so.2", librarySearchPaths), + hasFileInPath("ld-linux-aarch64.so.3", librarySearchPaths), // for when the next version comes out + hasFileInPath("ld-linux-armv7l.so", librarySearchPaths), + hasFileInPath("ld-linux-armv7l.so.1", librarySearchPaths), + hasFileInPath("ld-linux-armv7l.so.2", librarySearchPaths), + hasFileInPath("ld-linux-armv7l.so.3", librarySearchPaths) // for when the next version comes out ]) ]); } diff --git a/src/cli/cli.ts b/src/cli/cli.ts index bd2d0763..a1227a44 100644 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -3,20 +3,21 @@ import {fileURLToPath} from "url"; import path from "path"; import yargs from "yargs"; -// eslint-disable-next-line n/file-extension-in-import import {hideBin} from "yargs/helpers"; import fs from "fs-extra"; -import {cliBinName} from "../config.js"; +import {cliBinName, documentationPageUrls} from "../config.js"; import {setIsRunningFromCLI} from "../state.js"; -import {DownloadCommand} from "./commands/DownloadCommand.js"; -import {BuildCommand} from "./commands/BuildCommand.js"; -import {OnPostInstallCommand} from "./commands/OnPostInstallCommand.js"; -import {ClearCommand} from "./commands/ClearCommand.js"; +import {withCliCommandDescriptionDocsUrl} from "./utils/withCliCommandDescriptionDocsUrl.js"; +import {PullCommand} from "./commands/PullCommand.js"; import {ChatCommand} from "./commands/ChatCommand.js"; +import {InitCommand} from "./commands/InitCommand.js"; +import {DownloadCommand} from "./commands/DownloadCommand.js"; import {CompleteCommand} from "./commands/CompleteCommand.js"; import {InfillCommand} from "./commands/InfillCommand.js"; import {InspectCommand} from "./commands/inspect/InspectCommand.js"; -import {PullCommand} from "./commands/PullCommand.js"; +import {BuildCommand} from "./commands/BuildCommand.js"; +import {ClearCommand} from "./commands/ClearCommand.js"; +import {OnPostInstallCommand} from "./commands/OnPostInstallCommand.js"; import {DebugCommand} from "./commands/DebugCommand.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -29,9 +30,10 @@ const yarg = yargs(hideBin(process.argv)); yarg .scriptName(cliBinName) - .usage("Usage: $0 [options]") + .usage(withCliCommandDescriptionDocsUrl("Usage: $0 [options]", documentationPageUrls.CLI.index)) .command(PullCommand) .command(ChatCommand) + .command(InitCommand) .command(DownloadCommand) .command(CompleteCommand) .command(InfillCommand) @@ -48,5 +50,5 @@ yarg .help("h") .alias("h", "help") .version(packageJson.version) - .wrap(Math.min(100, yarg.terminalWidth())) + .wrap(Math.min(130, yarg.terminalWidth())) .parse(); diff --git a/src/cli/commands/BuildCommand.ts b/src/cli/commands/BuildCommand.ts index 8b4a6800..4d82b7fc 100644 --- a/src/cli/commands/BuildCommand.ts +++ b/src/cli/commands/BuildCommand.ts @@ -4,7 +4,7 @@ import chalk from "chalk"; import {compileLlamaCpp} from "../../bindings/utils/compileLLamaCpp.js"; import withOra from "../../utils/withOra.js"; import {clearTempFolder} from "../../utils/clearTempFolder.js"; -import {builtinLlamaCppGitHubRepo, builtinLlamaCppRelease, isCI, defaultLlamaCppGpuSupport} from "../../config.js"; +import {builtinLlamaCppGitHubRepo, builtinLlamaCppRelease, isCI, defaultLlamaCppGpuSupport, documentationPageUrls} from "../../config.js"; import {downloadCmakeIfNeeded} from "../../utils/cmake.js"; import withStatusLogs from "../../utils/withStatusLogs.js"; import {logBinaryUsageExampleToConsole} from "../../bindings/utils/logBinaryUsageExampleToConsole.js"; @@ -17,6 +17,7 @@ import {getGpuTypesToUseForOption} from "../../bindings/utils/getGpuTypesToUseFo import {getConsoleLogPrefix} from "../../utils/getConsoleLogPrefix.js"; import {getPrettyBuildGpuName} from "../../bindings/consts.js"; import {getPlatformInfo} from "../../bindings/utils/getPlatformInfo.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; type BuildCommand = { arch?: typeof process.arch, @@ -30,7 +31,11 @@ type BuildCommand = { export const BuildCommand: CommandModule = { command: "build", - describe: "Compile the currently downloaded llama.cpp", + aliases: ["compile"], + describe: withCliCommandDescriptionDocsUrl( + "Compile the currently downloaded `llama.cpp` source code", + documentationPageUrls.CLI.Build + ), builder(yargs) { return yargs .option("arch", { diff --git a/src/cli/commands/ChatCommand.ts b/src/cli/commands/ChatCommand.ts index 6535829f..432dbe76 100644 --- a/src/cli/commands/ChatCommand.ts +++ b/src/cli/commands/ChatCommand.ts @@ -4,7 +4,7 @@ import path from "path"; import {CommandModule} from "yargs"; import chalk from "chalk"; import fs from "fs-extra"; -import {chatCommandHistoryFilePath, defaultChatSystemPrompt} from "../../config.js"; +import {chatCommandHistoryFilePath, defaultChatSystemPrompt, documentationPageUrls} from "../../config.js"; import {getIsInDocumentationMode} from "../../state.js"; import {ReplHistory} from "../../utils/ReplHistory.js"; import {defineChatSessionFunction} from "../../evaluator/LlamaChatSession/utils/defineChatSessionFunction.js"; @@ -26,6 +26,7 @@ import {printCommonInfoLines} from "../utils/printCommonInfoLines.js"; import {resolveCommandGgufPath} from "../utils/resolveCommandGgufPath.js"; import {withProgressLog} from "../../utils/withProgressLog.js"; import {resolveHeaderFlag} from "../utils/resolveHeaderFlag.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; type ChatCommand = { modelPath?: string, @@ -64,7 +65,10 @@ type ChatCommand = { export const ChatCommand: CommandModule = { command: "chat [modelPath]", - describe: "Chat with a Llama model", + describe: withCliCommandDescriptionDocsUrl( + "Chat with a Llama model", + documentationPageUrls.CLI.Chat + ), builder(yargs) { const isInDocumentationMode = getIsInDocumentationMode(); diff --git a/src/cli/commands/ClearCommand.ts b/src/cli/commands/ClearCommand.ts index fa696f74..3b4382e8 100644 --- a/src/cli/commands/ClearCommand.ts +++ b/src/cli/commands/ClearCommand.ts @@ -1,10 +1,11 @@ import {CommandModule} from "yargs"; import fs from "fs-extra"; import chalk from "chalk"; -import {llamaCppDirectory, llamaCppDirectoryInfoFilePath} from "../../config.js"; +import {documentationPageUrls, llamaCppDirectory, llamaCppDirectoryInfoFilePath} from "../../config.js"; import withOra from "../../utils/withOra.js"; import {clearAllLocalBuilds} from "../../bindings/utils/clearAllLocalBuilds.js"; import {clearLocalCmake, fixXpackPermissions} from "../../utils/cmake.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; type ClearCommand = { type: "source" | "builds" | "cmake" | "all" @@ -13,7 +14,10 @@ type ClearCommand = { export const ClearCommand: CommandModule = { command: "clear [type]", aliases: ["clean"], - describe: "Clear files created by node-llama-cpp", + describe: withCliCommandDescriptionDocsUrl( + "Clear files created by node-llama-cpp", + documentationPageUrls.CLI.Clear + ), builder(yargs) { return yargs .option("type", { diff --git a/src/cli/commands/CompleteCommand.ts b/src/cli/commands/CompleteCommand.ts index 4ddbd18d..063eb8b1 100644 --- a/src/cli/commands/CompleteCommand.ts +++ b/src/cli/commands/CompleteCommand.ts @@ -16,6 +16,8 @@ import {printCommonInfoLines} from "../utils/printCommonInfoLines.js"; import {resolveCommandGgufPath} from "../utils/resolveCommandGgufPath.js"; import {withProgressLog} from "../../utils/withProgressLog.js"; import {resolveHeaderFlag} from "../utils/resolveHeaderFlag.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; +import {documentationPageUrls} from "../../config.js"; type CompleteCommand = { modelPath?: string, @@ -45,7 +47,10 @@ type CompleteCommand = { export const CompleteCommand: CommandModule = { command: "complete [modelPath]", - describe: "Generate a completion for a given text", + describe: withCliCommandDescriptionDocsUrl( + "Generate a completion for a given text", + documentationPageUrls.CLI.Complete + ), builder(yargs) { return yargs .option("modelPath", { diff --git a/src/cli/commands/DownloadCommand.ts b/src/cli/commands/DownloadCommand.ts index e2ffeb0d..5bc3b3bf 100644 --- a/src/cli/commands/DownloadCommand.ts +++ b/src/cli/commands/DownloadCommand.ts @@ -4,7 +4,7 @@ import fs from "fs-extra"; import chalk from "chalk"; import { defaultLlamaCppGitHubRepo, defaultLlamaCppRelease, isCI, llamaCppDirectory, llamaCppDirectoryInfoFilePath, - defaultLlamaCppGpuSupport + defaultLlamaCppGpuSupport, documentationPageUrls } from "../../config.js"; import {compileLlamaCpp} from "../../bindings/utils/compileLLamaCpp.js"; import withOra from "../../utils/withOra.js"; @@ -25,6 +25,7 @@ import {getGpuTypesToUseForOption} from "../../bindings/utils/getGpuTypesToUseFo import {getConsoleLogPrefix} from "../../utils/getConsoleLogPrefix.js"; import {getPrettyBuildGpuName} from "../../bindings/consts.js"; import {getPlatformInfo} from "../../bindings/utils/getPlatformInfo.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; type DownloadCommandArgs = { repo?: string, @@ -42,7 +43,10 @@ type DownloadCommandArgs = { export const DownloadCommand: CommandModule = { command: "download", - describe: "Download a release of llama.cpp and compile it", + describe: withCliCommandDescriptionDocsUrl( + "Download a release of `llama.cpp` and compile it", + documentationPageUrls.CLI.Download + ), builder(yargs) { const isInDocumentationMode = getIsInDocumentationMode(); diff --git a/src/cli/commands/InfillCommand.ts b/src/cli/commands/InfillCommand.ts index d785bd49..18061a17 100644 --- a/src/cli/commands/InfillCommand.ts +++ b/src/cli/commands/InfillCommand.ts @@ -16,6 +16,8 @@ import {printCommonInfoLines} from "../utils/printCommonInfoLines.js"; import {resolveCommandGgufPath} from "../utils/resolveCommandGgufPath.js"; import {withProgressLog} from "../../utils/withProgressLog.js"; import {resolveHeaderFlag} from "../utils/resolveHeaderFlag.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; +import {documentationPageUrls} from "../../config.js"; type InfillCommand = { modelPath?: string, @@ -47,7 +49,10 @@ type InfillCommand = { export const InfillCommand: CommandModule = { command: "infill [modelPath]", - describe: "Generate an infill completion for a given suffix and prefix texts", + describe: withCliCommandDescriptionDocsUrl( + "Generate an infill completion for a given suffix and prefix texts", + documentationPageUrls.CLI.Infill + ), builder(yargs) { return yargs .option("modelPath", { diff --git a/src/cli/commands/InitCommand.ts b/src/cli/commands/InitCommand.ts new file mode 100644 index 00000000..82b1f760 --- /dev/null +++ b/src/cli/commands/InitCommand.ts @@ -0,0 +1,245 @@ +import process from "process"; +import path from "path"; +import {CommandModule} from "yargs"; +import chalk from "chalk"; +import logSymbols from "log-symbols"; +import validateNpmPackageName from "validate-npm-package-name"; +import fs from "fs-extra"; +import {consolePromptQuestion} from "../utils/consolePromptQuestion.js"; +import {isUrl} from "../../utils/isUrl.js"; +import {basicChooseFromListConsoleInteraction} from "../utils/basicChooseFromListConsoleInteraction.js"; +import {splitAnsiToLines} from "../utils/splitAnsiToLines.js"; +import {arrowChar} from "../../consts.js"; +import {interactivelyAskForModel} from "../utils/interactivelyAskForModel.js"; +import {BuildGpu, LlamaLogLevel, nodeLlamaCppGpuOptions, parseNodeLlamaCppGpuOption} from "../../bindings/types.js"; +import {getLlama} from "../../bindings/getLlama.js"; +import {ProjectTemplate, ProjectTemplateParameter, scaffoldProjectTemplate} from "../utils/projectTemplates.js"; +import {documentationPageUrls, packedProjectTemplatesDirectory} from "../../config.js"; +import {getModuleVersion} from "../../utils/getModuleVersion.js"; +import withOra from "../../utils/withOra.js"; +import {ProjectTemplateOption, projectTemplates} from "../projectTemplates.js"; +import {getReadablePath} from "../utils/getReadablePath.js"; +import {createModelDownloader} from "../../utils/createModelDownloader.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; + +type InitCommand = { + name?: string, + template?: string, + gpu?: BuildGpu | "auto" +}; + +export const InitCommand: CommandModule = { + command: "init [name]", + describe: withCliCommandDescriptionDocsUrl( + "Generate a new `node-llama-cpp` project from a template", + documentationPageUrls.CLI.Init + ), + builder(yargs) { + return yargs + .option("name", { + type: "string", + description: "Project name" + }) + .option("template", { + type: "string", + choices: projectTemplates.map((template) => template.name), + description: "Template to use. If omitted, you will be prompted to select one" + }) + .option("gpu", { + type: "string", + + // yargs types don't support passing `false` as a choice, although it is supported by yargs + choices: nodeLlamaCppGpuOptions as any as Exclude[], + coerce: (value) => { + if (value == null || value == "") + return undefined; + + return parseNodeLlamaCppGpuOption(value); + }, + defaultDescription: "Uses the latest local build, and fallbacks to \"auto\"", + description: "Compute layer implementation type to use for llama.cpp" + }); + }, + handler: InitCommandHandler +}; + +export const CreateCliCommand: CommandModule = { + command: "$0", + describe: withCliCommandDescriptionDocsUrl( + "Scaffold a new `node-llama-cpp` project from a template", + documentationPageUrls.CLI.Init + ), + builder: InitCommand.builder, + handler: InitCommandHandler +}; + +export async function InitCommandHandler({name, template, gpu}: InitCommand) { + const currentDirectory = path.resolve(process.cwd()); + const projectName = (name != null && validateNpmPackageName(name ?? "").validForNewPackages) + ? name + : await askForProjectName(currentDirectory); + const selectedTemplateOption = ( + (template != null && template !== "") + ? projectTemplates.find((item) => item.name === template) + : undefined + ) ?? await askForTemplate(); + + const llama = gpu == null + ? await getLlama("lastBuild", { + logLevel: LlamaLogLevel.error + }) + : await getLlama({ + gpu, + logLevel: LlamaLogLevel.error + }); + + const modelUrl = await interactivelyAskForModel({ + llama, + allowLocalModels: false, + downloadIntent: false + }); + + const targetDirectory = path.join(currentDirectory, projectName); + const readableTargetDirectoryPath = getReadablePath(targetDirectory); + + await withOra({ + loading: `Scaffolding a ${chalk.yellow(selectedTemplateOption.title)} project to ${chalk.yellow(readableTargetDirectoryPath)}`, + success: `Scaffolded a ${chalk.yellow(selectedTemplateOption.title)} project to ${chalk.yellow(readableTargetDirectoryPath)}`, + fail: `Failed to scaffold a ${chalk.yellow(selectedTemplateOption.title)} project to ${chalk.yellow(readableTargetDirectoryPath)}` + }, async () => { + const startTime = Date.now(); + const minScaffoldTime = 1000 * 2; // ensure the IDE has enough time to refresh and show some progress + const template = await loadTemplate(selectedTemplateOption); + + await fs.ensureDir(targetDirectory); + + const modelDownloader = await createModelDownloader({ + modelUrl, + showCliProgress: false, + deleteTempFileOnCancel: false + }); + const modelEntrypointFilename = modelDownloader.entrypointFilename; + + await scaffoldProjectTemplate({ + template, + directoryPath: targetDirectory, + parameters: { + [ProjectTemplateParameter.ProjectName]: projectName, + [ProjectTemplateParameter.ModelUrl]: modelUrl, + [ProjectTemplateParameter.ModelFilename]: modelEntrypointFilename, + [ProjectTemplateParameter.CurrentModuleVersion]: await getModuleVersion() + } + }); + + try { + await modelDownloader.cancel(); + } catch (err) { + // do nothing + } + + await new Promise((resolve) => setTimeout(resolve, Math.max(0, minScaffoldTime - (Date.now() - startTime)))); + }); + + console.info(chalk.green("Done.")); + console.info(); + console.info("Now run these commands:"); + console.info(); + console.info(chalk.greenBright("cd") + " " + projectName); + console.info(chalk.greenBright("npm") + " install"); + console.info(chalk.greenBright("npm") + " start"); + console.info(); + console.info(chalk.grey("Note: running \"npm install\" may take a little while since it also downloads the model you selected")); + process.exit(0); +} + +async function askForTemplate() { + const selectedTemplateOption = await basicChooseFromListConsoleInteraction({ + title: chalk.bold("Select a template:"), + footer(item) { + if (item.description == null) + return undefined; + + const leftPad = 3; + const maxWidth = Math.max(1, process.stdout.columns - 2 - leftPad); + const lines = splitAnsiToLines(item.description, maxWidth); + + return " \n" + + " ".repeat(leftPad) + chalk.bold.gray("Template description") + "\n" + + lines.map((line) => (" ".repeat(leftPad) + line)).join("\n"); + }, + items: projectTemplates, + renderItem(item, focused) { + return renderSelectableItem( + item.titleFormat != null + ? item.titleFormat(item.title) + : item.title, + focused + ); + }, + aboveItemsPadding: 1, + belowItemsPadding: 1, + renderSummaryOnExit(item) { + if (item == null) + return ""; + + return logSymbols.success + " Selected template " + chalk.blue(item.title); + }, + exitOnCtrlC: true + }); + + if (selectedTemplateOption == null) + throw new Error("No template selected"); + + return selectedTemplateOption; +} + +async function askForProjectName(currentDirectory: string) { + console.info(); + const projectName = await consolePromptQuestion(chalk.bold("Enter a project name:") + chalk.dim(" (node-llama-cpp-project) "), { + defaultValue: "node-llama-cpp-project", + exitOnCtrlC: true, + async validate(input) { + const {validForNewPackages, errors} = validateNpmPackageName(input); + + if (!validForNewPackages) + return (errors ?? ["The given project name cannot be used in a package.json file"]).join("\n"); + + if (await fs.pathExists(path.join(currentDirectory, input))) + return "A directory with the given project name already exists"; + + return null; + }, + renderSummaryOnExit(item) { + if (item == null) + return ""; + + if (isUrl(item, false)) + return logSymbols.success + " Entered project name " + chalk.blue(item); + else + return logSymbols.success + " Entered project name " + chalk.blue(item); + } + }); + + if (projectName == null) + throw new Error("No project name entered"); + + return projectName; +} + +function renderSelectableItem(text: string, focused: boolean) { + if (focused) + return " " + chalk.cyan(arrowChar) + " " + chalk.cyan(text); + + return " * " + text; +} + +async function loadTemplate(templateOption: ProjectTemplateOption) { + const templateFilePath = path.join(packedProjectTemplatesDirectory, `${templateOption.name}.json`); + + if (!(await fs.pathExists(templateFilePath))) + throw new Error(`Template file was not found for template "${templateOption.title}" ("${templateOption.name}")`); + + const template: ProjectTemplate = await fs.readJSON(templateFilePath); + + return template; +} diff --git a/src/cli/commands/PullCommand.ts b/src/cli/commands/PullCommand.ts index b67c7396..b382bcc6 100644 --- a/src/cli/commands/PullCommand.ts +++ b/src/cli/commands/PullCommand.ts @@ -2,12 +2,13 @@ import process from "process"; import {CommandModule} from "yargs"; import fs from "fs-extra"; import chalk from "chalk"; -import {cliModelsDirectory} from "../../config.js"; +import {cliModelsDirectory, documentationPageUrls} from "../../config.js"; import {createModelDownloader} from "../../utils/createModelDownloader.js"; import {getReadablePath} from "../utils/getReadablePath.js"; import {ConsoleInteraction, ConsoleInteractionKey} from "../utils/ConsoleInteraction.js"; import {getIsInDocumentationMode} from "../../state.js"; import {resolveHeaderFlag} from "../utils/resolveHeaderFlag.js"; +import {withCliCommandDescriptionDocsUrl} from "../utils/withCliCommandDescriptionDocsUrl.js"; type PullCommand = { url: string, @@ -22,7 +23,10 @@ type PullCommand = { export const PullCommand: CommandModule = { command: "pull [url]", aliases: ["get"], - describe: "Download a model from a URL", + describe: withCliCommandDescriptionDocsUrl( + "Download a model from a URL", + documentationPageUrls.CLI.Pull + ), builder(yargs) { const isInDocumentationMode = getIsInDocumentationMode(); @@ -38,30 +42,35 @@ export const PullCommand: CommandModule = { ? "\n" : " " ), - demandOption: true + demandOption: true, + group: "Required:" }) .option("header", { alias: ["H"], type: "string", array: true, - description: "Headers to use when downloading a model from a URL, in the format `key: value`. You can pass this option multiple times to add multiple headers." + description: "Headers to use when downloading a model from a URL, in the format `key: value`. You can pass this option multiple times to add multiple headers.", + group: "Optional:" }) .option("override", { alias: ["o"], type: "boolean", - description: "Override the model if it already exists", - default: false + description: "Override the model file if it already exists", + default: false, + group: "Optional:" }) .option("noProgress", { type: "boolean", description: "Do not show a progress bar while downloading", - default: false + default: false, + group: "Optional:" }) .option("noTempFile", { alias: ["noTemp"], type: "boolean", description: "Delete the temporary file when canceling the download", - default: false + default: false, + group: "Optional:" }) .option("directory", { alias: ["d", "dir"], @@ -70,12 +79,14 @@ export const PullCommand: CommandModule = { default: cliModelsDirectory, defaultDescription: isInDocumentationMode ? "`" + getReadablePath(cliModelsDirectory) + "`" - : getReadablePath(cliModelsDirectory) + : getReadablePath(cliModelsDirectory), + group: "Optional:" }) .option("filename", { alias: ["n", "name"], type: "string", - description: "Filename to save the model as" + description: "Filename to save the model as", + group: "Optional:" }); }, async handler({url, header: headerArg, override, noProgress, noTempFile, directory, filename}: PullCommand) { diff --git a/src/cli/commands/inspect/InspectCommand.ts b/src/cli/commands/inspect/InspectCommand.ts index 4275f70d..45a2efd4 100644 --- a/src/cli/commands/inspect/InspectCommand.ts +++ b/src/cli/commands/inspect/InspectCommand.ts @@ -1,4 +1,6 @@ import {CommandModule} from "yargs"; +import {withCliCommandDescriptionDocsUrl} from "../../utils/withCliCommandDescriptionDocsUrl.js"; +import {documentationPageUrls} from "../../../config.js"; import {InspectGgufCommand} from "./commands/InspectGgufCommand.js"; import {InspectGpuCommand} from "./commands/InspectGpuCommand.js"; import {InspectMeasureCommand} from "./commands/InspectMeasureCommand.js"; @@ -9,7 +11,10 @@ type InspectCommand = { export const InspectCommand: CommandModule = { command: "inspect ", - describe: "Inspect the inner workings of node-llama-cpp", + describe: withCliCommandDescriptionDocsUrl( + "Inspect the inner workings of node-llama-cpp", + documentationPageUrls.CLI.Inspect.index + ), builder(yargs) { return yargs .command(InspectGpuCommand) diff --git a/src/cli/commands/inspect/commands/InspectGgufCommand.ts b/src/cli/commands/inspect/commands/InspectGgufCommand.ts index 3c0ca7ae..67e76dd5 100644 --- a/src/cli/commands/inspect/commands/InspectGgufCommand.ts +++ b/src/cli/commands/inspect/commands/InspectGgufCommand.ts @@ -11,6 +11,8 @@ import {normalizeGgufDownloadUrl} from "../../../../gguf/utils/normalizeGgufDown import {isUrl} from "../../../../utils/isUrl.js"; import {resolveHeaderFlag} from "../../../utils/resolveHeaderFlag.js"; import {getReadablePath} from "../../../utils/getReadablePath.js"; +import {withCliCommandDescriptionDocsUrl} from "../../../utils/withCliCommandDescriptionDocsUrl.js"; +import {documentationPageUrls} from "../../../../config.js"; type InspectGgufCommand = { modelPath: string, @@ -24,7 +26,10 @@ type InspectGgufCommand = { export const InspectGgufCommand: CommandModule = { command: "gguf [modelPath]", - describe: "Inspect a GGUF file", + describe: withCliCommandDescriptionDocsUrl( + "Inspect a GGUF file", + documentationPageUrls.CLI.Inspect.GGUF + ), builder(yargs) { return yargs .option("modelPath", { @@ -38,7 +43,8 @@ export const InspectGgufCommand: CommandModule = { alias: ["H"], type: "string", array: true, - description: "Headers to use when reading a model file from a URL, in the format `key: value`. You can pass this option multiple times to add multiple headers." + description: "Headers to use when reading a model file from a URL, in the format `key: value`. You can pass this option multiple times to add multiple headers.", + group: "Optional:" }) .option("noSplice", { alias: "s", diff --git a/src/cli/commands/inspect/commands/InspectGpuCommand.ts b/src/cli/commands/inspect/commands/InspectGpuCommand.ts index 370fee55..a50f9f5f 100644 --- a/src/cli/commands/inspect/commands/InspectGpuCommand.ts +++ b/src/cli/commands/inspect/commands/InspectGpuCommand.ts @@ -8,6 +8,8 @@ import {getPlatform} from "../../../../bindings/utils/getPlatform.js"; import {BuildGpu, LlamaLogLevel} from "../../../../bindings/types.js"; import {getPrettyBuildGpuName} from "../../../../bindings/consts.js"; import {getModuleVersion} from "../../../../utils/getModuleVersion.js"; +import {withCliCommandDescriptionDocsUrl} from "../../../utils/withCliCommandDescriptionDocsUrl.js"; +import {documentationPageUrls} from "../../../../config.js"; type InspectGpuCommand = { // no options for now @@ -15,7 +17,10 @@ type InspectGpuCommand = { export const InspectGpuCommand: CommandModule = { command: "gpu", - describe: "Show the detected GPU types and their VRAM usage", + describe: withCliCommandDescriptionDocsUrl( + "Show the detected GPU types and their VRAM usage", + documentationPageUrls.CLI.Inspect.GPU + ), async handler() { const platform = getPlatform(); const arch = process.arch; diff --git a/src/cli/commands/inspect/commands/InspectMeasureCommand.ts b/src/cli/commands/inspect/commands/InspectMeasureCommand.ts index 8f3a4dd3..10aec1ff 100644 --- a/src/cli/commands/inspect/commands/InspectMeasureCommand.ts +++ b/src/cli/commands/inspect/commands/InspectMeasureCommand.ts @@ -17,6 +17,8 @@ import {GgufInsights} from "../../../../gguf/insights/GgufInsights.js"; import {resolveHeaderFlag} from "../../../utils/resolveHeaderFlag.js"; import {getPrettyBuildGpuName} from "../../../../bindings/consts.js"; import {getReadablePath} from "../../../utils/getReadablePath.js"; +import {withCliCommandDescriptionDocsUrl} from "../../../utils/withCliCommandDescriptionDocsUrl.js"; +import {documentationPageUrls} from "../../../../config.js"; type InspectMeasureCommand = { modelPath?: string, @@ -34,7 +36,10 @@ type InspectMeasureCommand = { export const InspectMeasureCommand: CommandModule = { command: "measure [modelPath]", - describe: "Measure VRAM consumption of a GGUF model file with all possible combinations of gpu layers and context sizes", + describe: withCliCommandDescriptionDocsUrl( + "Measure VRAM consumption of a GGUF model file with all possible combinations of gpu layers and context sizes", + documentationPageUrls.CLI.Inspect.Measure + ), builder(yargs) { return yargs .option("modelPath", { diff --git a/src/cli/projectTemplates.ts b/src/cli/projectTemplates.ts new file mode 100644 index 00000000..ba19e588 --- /dev/null +++ b/src/cli/projectTemplates.ts @@ -0,0 +1,15 @@ +export type ProjectTemplateOption = { + title: string, + name: string, + titleFormat?(title: string): string, + description?: string +}; +export const projectTemplates: ProjectTemplateOption[] = [{ + title: "Node + TypeScript", + name: "node-typescript", + description: "A Node.js project with TypeScript using vite-node, some ESLint configuration, basic setup with a selected model file, and a working example of a simple usage of node-llama-cpp with the model" +}, { + title: "Electron + TypeScript + React", + name: "electron-typescript-react", + description: "An Electron project with TypeScript and React using Vite-Electron, some ESLint configuration, basic setup with a selected model file, and a working example of a simple usage of node-llama-cpp with the model" +}]; diff --git a/src/cli/startCreateCli.ts b/src/cli/startCreateCli.ts new file mode 100644 index 00000000..edc377a0 --- /dev/null +++ b/src/cli/startCreateCli.ts @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +import yargs from "yargs"; +import {hideBin} from "yargs/helpers"; +import {setIsRunningFromCLI} from "../state.js"; +import {CreateCliCommand} from "./commands/InitCommand.js"; + +/** @internal */ +export function _startCreateCli({ + cliBinName, + packageVersion, + _enable +}: { + cliBinName: string, + packageVersion: string, + _enable?: any +}) { + if (_enable !== Symbol.for("internal")) + return; + + setIsRunningFromCLI(true); + + const yarg = yargs(hideBin(process.argv)); + + yarg + .scriptName(cliBinName) + .usage("Usage: $0 [options]") + .command(CreateCliCommand) + .demandCommand(1) + .strict() + .strictCommands() + .alias("v", "version") + .help("h") + .alias("h", "help") + .version(packageVersion) + .wrap(Math.min(100, yarg.terminalWidth())) + .parse(); +} diff --git a/src/cli/utils/consolePromptQuestion.ts b/src/cli/utils/consolePromptQuestion.ts index 9af7e79a..9d25dfee 100644 --- a/src/cli/utils/consolePromptQuestion.ts +++ b/src/cli/utils/consolePromptQuestion.ts @@ -7,11 +7,13 @@ import {splitAnsiToLines} from "./splitAnsiToLines.js"; export async function consolePromptQuestion(question: string, { validate, renderSummaryOnExit, - exitOnCtrlC = true + exitOnCtrlC = true, + defaultValue }: { validate?: (input: string) => string | null | Promise, renderSummaryOnExit?: (item: string | null) => string, - exitOnCtrlC?: boolean + exitOnCtrlC?: boolean, + defaultValue?: string } = {}) { let lastErrorText = ""; let lastResponse = ""; @@ -25,7 +27,7 @@ export async function consolePromptQuestion(question: string, { output: process.stdout }); - const res = await new Promise((accept) => { + let res = await new Promise((accept) => { const initialCursorPosition = rl.getCursorPos(); function onSigInt() { rl.off("SIGINT", onSigInt); @@ -68,6 +70,9 @@ export async function consolePromptQuestion(question: string, { return null; } + if (res === "" && defaultValue != null) + res = defaultValue; + lastResponse = res; const validationError = await validate?.(res); diff --git a/src/cli/utils/interactivelyAskForModel.ts b/src/cli/utils/interactivelyAskForModel.ts new file mode 100644 index 00000000..0f60ba11 --- /dev/null +++ b/src/cli/utils/interactivelyAskForModel.ts @@ -0,0 +1,595 @@ +import path from "path"; +import process from "process"; +import chalk from "chalk"; +import bytes from "bytes"; +import fs from "fs-extra"; +import stripAnsi from "strip-ansi"; +import logSymbols from "log-symbols"; +import {getReadableContextSize} from "../../utils/getReadableContextSize.js"; +import {arrowChar} from "../../consts.js"; +import {Llama} from "../../bindings/Llama.js"; +import {getGgufSplitPartsInfo} from "../../gguf/utils/resolveSplitGgufParts.js"; +import {withProgressLog} from "../../utils/withProgressLog.js"; +import {GgufInsights} from "../../gguf/insights/GgufInsights.js"; +import {readGgufFileInfo} from "../../gguf/readGgufFileInfo.js"; +import {getPrettyBuildGpuName} from "../../bindings/consts.js"; +import {GgufInsightsConfigurationResolver} from "../../gguf/insights/GgufInsightsConfigurationResolver.js"; +import {isUrl} from "../../utils/isUrl.js"; +import {resolveModelRecommendationFileOptions} from "./resolveModelRecommendationFileOptions.js"; +import {getReadablePath} from "./getReadablePath.js"; +import {basicChooseFromListConsoleInteraction} from "./basicChooseFromListConsoleInteraction.js"; +import {splitAnsiToLines} from "./splitAnsiToLines.js"; +import {consolePromptQuestion} from "./consolePromptQuestion.js"; +import {renderInfoLine} from "./printInfoLine.js"; + +type ModelOption = { + type: "localModel", + title: string | (() => string), + path: string, + addedDate: number, + ggufInsights?: GgufInsights, + compatibilityScore?: number, + compatibilityContextSize?: number, + compatibilityBonusScore?: number +} | { + type: "recommendedModel", + title: string | (() => string), + description?: string, + potentialUrls: string[], + selectedUrl?: { + url: string, + ggufInsights: GgufInsights, + compatibilityScore: ReturnType + }, + urlSelectionLoadingState?: "done" | "loading" +} | { + type: "separator", + text: string | (() => string) +} | { + type: "action", + text: string | (() => string), + key: string +}; +const vramStateUpdateInterval = 1000; + +export async function interactivelyAskForModel({ + llama, + modelsDirectory, + allowLocalModels = true, + downloadIntent = true +}: { + llama: Llama, + modelsDirectory?: string, + allowLocalModels?: boolean, + downloadIntent?: boolean +}): Promise { + let localModelFileOptions: (ModelOption & { type: "localModel" })[] = []; + const recommendedModelOptions: (ModelOption & { type: "recommendedModel" })[] = []; + const activeInteractionController = new AbortController(); + let scheduledTitleRerenderTimeout: ReturnType | undefined = undefined; + let lastVramState: { used: number, total: number } = llama.getVramState(); + const canUseGpu = lastVramState.total > 0; + + if (allowLocalModels && modelsDirectory != null && await fs.existsSync(modelsDirectory)) { + const ggufFileNames = (await fs.readdir(modelsDirectory)) + .filter((fileName) => { + if (!fileName.endsWith(".gguf")) + return false; + + const partsInfo = getGgufSplitPartsInfo(fileName); + + return partsInfo == null || partsInfo.part === 1; + }); + let readItems = 0; + const renderProgress = () => ( + "(" + String(readItems) + .padStart(String(ggufFileNames.length).length, "0") + "/" + ggufFileNames.length + ")" + ); + + if (ggufFileNames.length > 0) + await withProgressLog({ + loadingText: "Reading local models directory", + failText: "Failed to read local models directory", + successText: "Read local models directory", + noSuccessLiveStatus: true, + initialProgressBarText: renderProgress() + }, async (progressUpdater) => { + localModelFileOptions = await Promise.all( + ggufFileNames.map(async (fileName) => { + const filePath = path.join(modelsDirectory, fileName); + + let ggufInsights: GgufInsights | undefined = undefined; + try { + const ggufFileInfo = await readGgufFileInfo(filePath, { + sourceType: "filesystem", + signal: activeInteractionController.signal + }); + ggufInsights = await GgufInsights.from(ggufFileInfo, llama); + } catch (err) { + // do nothing + } + + readItems++; + progressUpdater.setProgress(readItems / ggufFileNames.length, renderProgress()); + + const compatibilityScore = ggufInsights?.configurationResolver.scoreModelConfigurationCompatibility(); + + return { + type: "localModel", + title: fileName, + path: filePath, + addedDate: (await fs.stat(filePath)).birthtimeMs, + ggufInsights: ggufInsights, + compatibilityScore: compatibilityScore?.compatibilityScore, + compatibilityBonusScore: compatibilityScore?.bonusScore, + compatibilityContextSize: compatibilityScore?.resolvedValues.contextSize + } satisfies ModelOption; + }) + ); + + localModelFileOptions = localModelFileOptions.sort((a, b) => { + if (a.compatibilityScore == null && b.compatibilityScore == null) + return b.addedDate - a.addedDate; + else if (a.compatibilityScore == null) + return -1; + else if (b.compatibilityScore == null) + return 1; + else if (b.compatibilityScore === a.compatibilityScore && + b.compatibilityBonusScore != null && a.compatibilityBonusScore != null + ) + return b.compatibilityBonusScore - a.compatibilityBonusScore; + + return b.compatibilityScore - a.compatibilityScore; + }); + }); + } + + try { + // if this file gets very big, we don't want to load it on every CLI usage + const {recommendedModels} = await import("../recommendedModels.js"); + + for (const recommendedModel of recommendedModels) { + const potentialUrls = resolveModelRecommendationFileOptions(recommendedModel); + + if (potentialUrls.length > 0) + recommendedModelOptions.push({ + type: "recommendedModel", + title: recommendedModel.name, + potentialUrls, + description: recommendedModel.description + }); + } + } catch (err) { + // do nothing + } + + let initialFocusIndex = 3; // first model option + const options: ModelOption[] = [ + { + type: "action", + text: allowLocalModels + ? "Enter a model URL or file path..." + : "Enter a model URL...", + key: "getPath" + }, + ...( + (localModelFileOptions.length === 0 || modelsDirectory == null) + ? [] + : [ + { + type: "separator", + text: () => " " + chalk.gray("-".repeat(4)) + }, + { + type: "separator", + text: " " + chalk.bold("Downloaded models") + " " + chalk.dim(`(${getReadablePath(modelsDirectory)})`) + }, + ...localModelFileOptions + ] satisfies ModelOption[] + ), + ...( + recommendedModelOptions.length === 0 + ? [] + : [ + { + type: "separator", + text: () => " " + chalk.gray("-".repeat(4)) + }, + { + type: "separator", + text: " " + chalk.bold("Recommended models") + ( + downloadIntent + ? (" " + chalk.dim("(select to download)")) + : "" + ) + }, + ...recommendedModelOptions + ] satisfies ModelOption[] + ) + ]; + + try { + // eslint-disable-next-line no-constant-condition + while (true) { + const minWidth = Math.min(80, process.stdout.columns - 1); + const selectedItem = await basicChooseFromListConsoleInteraction({ + title(item, rerender) { + const title = chalk.bold("Select a model:") + " "; + + const vramState = llama.getVramState(); + const vramStateText = vramState.total === 0 + ? chalk.bgGray( + " " + + "No GPU" + + " " + ) + : ( + chalk.bgGray( + " " + + chalk.yellow("GPU:") + " " + getPrettyBuildGpuName(llama.gpu) + + " " + ) + + " " + + chalk.bgGray( + " " + + chalk.yellow("VRAM usage:") + " " + + (String(Math.floor((vramState.used / vramState.total) * 100 * 100) / 100) + "%") + " " + + chalk.dim("(" + bytes(vramState.used) + "/" + bytes(vramState.total) + ")") + + " " + ) + ); + + const pad = Math.max(0, minWidth - (stripAnsi(title).length + stripAnsi(vramStateText).length)); + + lastVramState = vramState; + clearTimeout(scheduledTitleRerenderTimeout); + scheduledTitleRerenderTimeout = setTimeout(() => { + const vramState = llama.getVramState(); + if (lastVramState.used !== vramState.used || lastVramState.total !== vramState.total) + rerender(); + }, vramStateUpdateInterval); + + return [ + title, + " ".repeat(pad), + vramStateText + ].join(""); + }, + footer(item) { + if (item.type !== "recommendedModel" || item.description == null) + return undefined; + + const leftPad = 3; + const maxWidth = Math.max(1, process.stdout.columns - 2 - leftPad); + const lines = splitAnsiToLines(item.description, maxWidth); + + return " \n" + + " ".repeat(leftPad) + chalk.bold.gray("Model description") + "\n" + + lines.map((line) => (" ".repeat(leftPad) + line)) + .join("\n") + "\n" + + splitAnsiToLines(renderRecommendedModelTechnicalInfo(item.selectedUrl, maxWidth, canUseGpu), maxWidth) + .map((line) => (" ".repeat(leftPad) + line)) + .join("\n"); + }, + items: options, + renderItem(item, focused, rerender) { + return renderSelectionItem(item, focused, rerender, activeInteractionController.signal, llama); + }, + canFocusItem(item) { + return item.type === "recommendedModel" || item.type === "localModel" || item.type === "action"; + }, + canSelectItem(item) { + if (item.type === "recommendedModel") + return item.selectedUrl != null; + + return item.type === "localModel" || item.type === "action"; + }, + initialFocusIndex: Math.min(initialFocusIndex, options.length - 1), + aboveItemsPadding: 1, + belowItemsPadding: 1, + renderSummaryOnExit(item) { + if (item == null || item.type === "action" || item.type === "separator") + return ""; + else if (item.type === "localModel") { + const modelTitle = item.title instanceof Function + ? item.title() + : item.title; + + return logSymbols.success + " Selected model " + chalk.blue(modelTitle); + } else if (item.type === "recommendedModel") { + const modelTitle = item.title instanceof Function + ? item.title() + : item.title; + + return logSymbols.success + " Selected model " + chalk.blue(modelTitle); + } + + void (item satisfies never); + return ""; + }, + exitOnCtrlC: true + }); + + if (selectedItem == null || selectedItem.type === "separator") + continue; + else if (selectedItem.type === "localModel") + return selectedItem.path; + else if (selectedItem.type === "recommendedModel" && selectedItem.selectedUrl != null) + return selectedItem.selectedUrl.url; + else if (selectedItem.type === "action") { + if (selectedItem.key === "getPath") { + initialFocusIndex = 0; + const selectedModelUrlOrPath = await askForModelUrlOrPath(allowLocalModels); + + if (selectedModelUrlOrPath == null) + continue; + + return selectedModelUrlOrPath; + } + } + } + } finally { + activeInteractionController.abort(); + } +} + +async function askForModelUrlOrPath(allowLocalModels: boolean): Promise { + return await consolePromptQuestion( + allowLocalModels + ? chalk.bold("Enter a model URL or file path: ") + : chalk.bold("Enter a model URL: "), + { + exitOnCtrlC: false, + async validate(input) { + if (isUrl(input, false)) { + try { + new URL(input); + } catch (err) { + return "Invalid URL"; + } + + return null; + } else if (!allowLocalModels) + return "Only URLs are allowed"; + + try { + if (await fs.pathExists(input)) + return null; + + return "File does not exist"; + } catch (err) { + return "Invalid path"; + } + }, + renderSummaryOnExit(item) { + if (item == null) + return ""; + + if (isUrl(item, false)) + return logSymbols.success + " Entered model URL " + chalk.blue(item); + else + return logSymbols.success + " Entered model path " + chalk.blue(item); + } + } + ); +} + +function renderSelectionItem(item: ModelOption, focused: boolean, rerender: () => void, abortSignal: AbortSignal, llama: Llama) { + if (item.type === "localModel") { + let modelText = item.title instanceof Function + ? item.title() + : item.title; + + if (item.ggufInsights != null) + modelText += " " + renderModelCompatibility(item.ggufInsights, item.compatibilityScore, item.compatibilityContextSize); + else + modelText += " " + chalk.bgGray.yellow(" Cannot read metadata "); + + return renderSelectableItem(modelText, focused); + } else if (item.type === "recommendedModel") { + let modelText = item.title instanceof Function + ? item.title() + : item.title; + + if (item.selectedUrl == null) { + if (item.urlSelectionLoadingState == null) { + item.urlSelectionLoadingState = "loading"; + void selectFileForModelRecommendation({ + recommendedModelOption: item, + abortSignal, + rerenderOption: rerender, + llama + }); + } + + if (item.urlSelectionLoadingState === "loading") + modelText += " " + chalk.bgGray.yellow(" Loading info "); + else if (item.urlSelectionLoadingState === "done") + modelText += " " + chalk.bgGray.yellow(" Failed to load info "); + else + void (item.urlSelectionLoadingState satisfies never); + } else + modelText += " " + renderModelCompatibility( + item.selectedUrl.ggufInsights, + item.selectedUrl.compatibilityScore.compatibilityScore, + item.selectedUrl.compatibilityScore.resolvedValues.contextSize + ); + + return renderSelectableItem(modelText, focused); + } else if (item.type === "separator") { + return item.text instanceof Function + ? item.text() + : item.text; + } else if (item.type === "action") { + const actionText = item.text instanceof Function + ? item.text() + : item.text; + + return renderSelectableItem(actionText, focused); + } + + void (item satisfies never); + return ""; +} + +function renderSelectableItem(text: string, focused: boolean) { + if (focused) + return " " + chalk.cyan(arrowChar) + " " + chalk.cyan(text); + + return " * " + text; +} + +function renderModelCompatibility( + ggufInsights: GgufInsights, compatibilityScore: number | undefined, compatibilityContextSize: number | undefined +) { + const info: string[] = []; + + if (compatibilityScore != null) + info.push( + renderCompatibilityPercentageWithColors(compatibilityScore * 100) + chalk.whiteBright(" compatibility") + + ( + compatibilityContextSize == null + ? "" + : (chalk.gray(" | ") + chalk.yellow(getReadableContextSize(compatibilityContextSize)) + chalk.whiteBright(" context")) + ) + ); + + info.push(chalk.yellow("Size:") + " " + chalk.whiteBright(bytes(ggufInsights.modelSize))); + + return info + .map((item) => chalk.bgGray(" " + item + " ")) + .join(" "); +} + +function renderRecommendedModelTechnicalInfo( + modelSelectedUrl: (ModelOption & { type: "recommendedModel" })["selectedUrl"], + maxWidth: number, + canUseGpu: boolean +) { + if (modelSelectedUrl == null) + return " \n" + chalk.bgGray.yellow(" Loading info ") + "\n "; + + const ggufInsights = modelSelectedUrl.ggufInsights; + const compatibilityScore = modelSelectedUrl.compatibilityScore; + + const longestTitle = Math.max("Model info".length, "Resolved config".length) + 1; + return " \n" + [ + renderInfoLine({ + title: "Model info", + padTitle: longestTitle, + separateLines: false, + maxWidth, + info: [{ + title: "Size", + value: bytes(ggufInsights.modelSize) + }, { + show: ggufInsights.trainContextSize != null, + title: "Train context size", + value: () => getReadableContextSize(ggufInsights.trainContextSize ?? 0) + }] + }), + renderInfoLine({ + title: "Resolved config", + padTitle: longestTitle, + separateLines: false, + maxWidth, + info: [{ + title: "", + value: renderCompatibilityPercentageWithColors(compatibilityScore.compatibilityScore * 100) + " compatibility" + }, { + show: ggufInsights.trainContextSize != null, + title: "Context size", + value: getReadableContextSize(compatibilityScore.resolvedValues.contextSize) + }, { + show: canUseGpu, + title: "GPU layers", + value: () => ( + compatibilityScore.resolvedValues.gpuLayers + "/" + ggufInsights.totalLayers + " " + + chalk.dim(`(${Math.floor((compatibilityScore.resolvedValues.gpuLayers / ggufInsights.totalLayers) * 100)}%)`) + ) + }, { + show: canUseGpu, + title: "VRAM usage", + value: () => bytes(compatibilityScore.resolvedValues.totalVramUsage) + }] + }) + ].join("\n"); +} + +function renderCompatibilityPercentageWithColors(percentage: number, { + greenBright = 100, + green = 95, + yellow = 85, + yellowBright = 75 +}: { + greenBright?: number, + green?: number, + yellow?: number, + yellowBright?: number +} = {}): string { + const percentageText = String(Math.floor(percentage)) + "%"; + + if (percentage >= greenBright) + return chalk.greenBright(percentageText); + else if (percentage >= green) + return chalk.green(percentageText); + else if (percentage >= yellow) + return chalk.yellow(percentageText); + else if (percentage >= yellowBright) + return chalk.yellowBright(percentageText); + + return chalk.red(percentageText); +} + +async function selectFileForModelRecommendation({ + recommendedModelOption, llama, abortSignal, rerenderOption +}: { + recommendedModelOption: ModelOption & { type: "recommendedModel" }, + llama: Llama, + abortSignal: AbortSignal, + rerenderOption(): void +}) { + try { + let bestScore: number | undefined = undefined; + let bestScoreSelectedUrl: (ModelOption & { type: "recommendedModel" })["selectedUrl"] | undefined = undefined; + + for (const potentialUrl of recommendedModelOption.potentialUrls) { + if (abortSignal.aborted) + return; + + try { + const ggufFileInfo = await readGgufFileInfo(potentialUrl, { + sourceType: "network", + signal: abortSignal + }); + const ggufInsights = await GgufInsights.from(ggufFileInfo, llama); + + if (abortSignal.aborted) + return; + + const compatibilityScore = ggufInsights.configurationResolver.scoreModelConfigurationCompatibility(); + + if (bestScore == null || compatibilityScore.compatibilityScore > bestScore) { + bestScore = compatibilityScore.compatibilityScore; + bestScoreSelectedUrl = { + url: potentialUrl, + ggufInsights, + compatibilityScore + }; + + if (bestScore === 1) + break; + } + } catch (err) { + // do nothing + } + } + + recommendedModelOption.selectedUrl = bestScoreSelectedUrl; + recommendedModelOption.urlSelectionLoadingState = "done"; + rerenderOption(); + } catch (err) { + recommendedModelOption.urlSelectionLoadingState = "done"; + rerenderOption(); + } +} diff --git a/src/cli/utils/projectTemplates.ts b/src/cli/utils/projectTemplates.ts new file mode 100644 index 00000000..5a10e445 --- /dev/null +++ b/src/cli/utils/projectTemplates.ts @@ -0,0 +1,81 @@ +import path from "path"; +import fs from "fs-extra"; + +export const enum ProjectTemplateParameter { + ProjectName = "projectName", + CurrentModuleVersion = "currentNodeLlamaCppModuleVersion", + ModelUrl = "modelUrl", + ModelFilename = "modelFilename", +} + +export type PackagedFileEntry = { + path: string[], + content: string +}; + +export type ProjectTemplate = { + files: PackagedFileEntry[] +}; + +export function getProjectTemplateParameterText(parameter: ProjectTemplateParameter, escapeText: boolean | 0 | 1 | 2 = true) { + let escapes = ""; + if (escapeText === true || escapeText === 1) + escapes = "|escape"; + else if (escapeText === 2) + escapes = "|escape|escape"; + + return "{{" + parameter + escapes + "}}"; +} + +function applyProjectTemplateParameters(template: string, parameters: Record) { + for (const [parameter, value] of (Object.entries(parameters) as [ProjectTemplateParameter, string][])) { + template = template.split(getProjectTemplateParameterText(parameter, 0)).join(String(value)); + template = template.split(getProjectTemplateParameterText(parameter, 1)).join(JSON.stringify(String(value)).slice(1, -1)); + template = template.split(getProjectTemplateParameterText(parameter, 2)).join( + JSON.stringify( + JSON.stringify( + String(value) + ).slice(1, -1) + ).slice(1, -1) + ); + } + + return template; +} + +export async function scaffoldProjectTemplate({ + template, parameters, directoryPath +}: { + template: ProjectTemplate, + parameters: Record, + directoryPath: string +}) { + for (const file of template.files) { + const filePath = path.join(directoryPath, ...file.path); + const fileContent = transformFileContent({ + content: applyProjectTemplateParameters(file.content, parameters), + originalPath: file.path, + parameters + }); + + await fs.ensureDir(path.dirname(filePath)); + await fs.writeFile(filePath, fileContent, "utf8"); + } +} + +function transformFileContent({ + content, originalPath, parameters +}: { + content: string, originalPath: string[], parameters: Record +}) { + if (originalPath.length === 1 && originalPath[0] === "package.json") { + const packageJson = JSON.parse(content); + + if (parameters[ProjectTemplateParameter.ProjectName] != null) + packageJson.name = parameters[ProjectTemplateParameter.ProjectName]; + + return JSON.stringify(packageJson, null, 2); + } + + return content; +} diff --git a/src/cli/utils/resolveCommandGgufPath.ts b/src/cli/utils/resolveCommandGgufPath.ts index 69827de7..31609e33 100644 --- a/src/cli/utils/resolveCommandGgufPath.ts +++ b/src/cli/utils/resolveCommandGgufPath.ts @@ -2,29 +2,14 @@ import path from "path"; import process from "process"; import chalk from "chalk"; import fs from "fs-extra"; -import bytes from "bytes"; -import logSymbols from "log-symbols"; -import stripAnsi from "strip-ansi"; import {cliModelsDirectory} from "../../config.js"; import {normalizeGgufDownloadUrl} from "../../gguf/utils/normalizeGgufDownloadUrl.js"; -import {GgufInsights} from "../../gguf/insights/GgufInsights.js"; -import {readGgufFileInfo} from "../../gguf/readGgufFileInfo.js"; import {Llama} from "../../bindings/Llama.js"; import {isUrl} from "../../utils/isUrl.js"; -import {arrowChar} from "../../consts.js"; -import {withProgressLog} from "../../utils/withProgressLog.js"; -import {getReadableContextSize} from "../../utils/getReadableContextSize.js"; -import {GgufInsightsConfigurationResolver} from "../../gguf/insights/GgufInsightsConfigurationResolver.js"; -import {getPrettyBuildGpuName} from "../../bindings/consts.js"; -import {getGgufSplitPartsInfo} from "../../gguf/utils/resolveSplitGgufParts.js"; import {createModelDownloader} from "../../utils/createModelDownloader.js"; import {ConsoleInteraction, ConsoleInteractionKey} from "./ConsoleInteraction.js"; import {getReadablePath} from "./getReadablePath.js"; -import {basicChooseFromListConsoleInteraction} from "./basicChooseFromListConsoleInteraction.js"; -import {consolePromptQuestion} from "./consolePromptQuestion.js"; -import {resolveModelRecommendationFileOptions} from "./resolveModelRecommendationFileOptions.js"; -import {splitAnsiToLines} from "./splitAnsiToLines.js"; -import {renderInfoLine} from "./printInfoLine.js"; +import {interactivelyAskForModel} from "./interactivelyAskForModel.js"; export async function resolveCommandGgufPath(ggufPath: string | undefined, llama: Llama, fetchHeaders?: Record, { targetDirectory = cliModelsDirectory @@ -34,7 +19,12 @@ export async function resolveCommandGgufPath(ggufPath: string | undefined, llama let resolvedGgufPath = ggufPath; if (resolvedGgufPath == null) - resolvedGgufPath = await interactiveChooseModel(llama, targetDirectory); + resolvedGgufPath = await interactivelyAskForModel({ + llama, + modelsDirectory: targetDirectory, + allowLocalModels: true, + downloadIntent: true + }); if (!isUrl(resolvedGgufPath)) { try { @@ -105,551 +95,3 @@ export async function resolveCommandGgufPath(ggufPath: string | undefined, llama return downloader.entrypointFilePath; } -type ModelOption = { - type: "localModel", - title: string | (() => string), - path: string, - addedDate: number, - ggufInsights?: GgufInsights, - compatibilityScore?: number, - compatibilityContextSize?: number, - compatibilityBonusScore?: number -} | { - type: "recommendedModel", - title: string | (() => string), - description?: string, - potentialUrls: string[], - selectedUrl?: { - url: string, - ggufInsights: GgufInsights, - compatibilityScore: ReturnType - }, - urlSelectionLoadingState?: "done" | "loading" -} | { - type: "separator", - text: string | (() => string) -} | { - type: "action", - text: string | (() => string), - key: string -}; - -const vramStateUpdateInterval = 1000; - -async function interactiveChooseModel(llama: Llama, targetDirectory: string): Promise { - let localModelFileOptions: (ModelOption & {type: "localModel"})[] = []; - const recommendedModelOptions: (ModelOption & {type: "recommendedModel"})[] = []; - const activeInteractionController = new AbortController(); - let scheduledTitleRerenderTimeout: ReturnType | undefined = undefined; - let lastVramState: {used: number, total: number} = llama.getVramState(); - const canUseGpu = lastVramState.total > 0; - - if (await fs.existsSync(targetDirectory)) { - const ggufFileNames = (await fs.readdir(targetDirectory)) - .filter((fileName) => { - if (!fileName.endsWith(".gguf")) - return false; - - const partsInfo = getGgufSplitPartsInfo(fileName); - - return partsInfo == null || partsInfo.part === 1; - }); - let readItems = 0; - const renderProgress = () => ( - "(" + String(readItems).padStart(String(ggufFileNames.length).length, "0") + "/" + ggufFileNames.length + ")" - ); - - if (ggufFileNames.length > 0) - await withProgressLog({ - loadingText: "Reading local models directory", - failText: "Failed to read local models directory", - successText: "Read local models directory", - noSuccessLiveStatus: true, - initialProgressBarText: renderProgress() - }, async (progressUpdater) => { - localModelFileOptions = await Promise.all( - ggufFileNames.map(async (fileName) => { - const filePath = path.join(targetDirectory, fileName); - - let ggufInsights: GgufInsights | undefined = undefined; - try { - const ggufFileInfo = await readGgufFileInfo(filePath, { - sourceType: "filesystem", - signal: activeInteractionController.signal - }); - ggufInsights = await GgufInsights.from(ggufFileInfo, llama); - } catch (err) { - // do nothing - } - - readItems++; - progressUpdater.setProgress(readItems / ggufFileNames.length, renderProgress()); - - const compatibilityScore = ggufInsights?.configurationResolver.scoreModelConfigurationCompatibility(); - - return { - type: "localModel", - title: fileName, - path: filePath, - addedDate: (await fs.stat(filePath)).birthtimeMs, - ggufInsights: ggufInsights, - compatibilityScore: compatibilityScore?.compatibilityScore, - compatibilityBonusScore: compatibilityScore?.bonusScore, - compatibilityContextSize: compatibilityScore?.resolvedValues.contextSize - } satisfies ModelOption; - }) - ); - - localModelFileOptions = localModelFileOptions.sort((a, b) => { - if (a.compatibilityScore == null && b.compatibilityScore == null) - return b.addedDate - a.addedDate; - else if (a.compatibilityScore == null) - return -1; - else if (b.compatibilityScore == null) - return 1; - else if (b.compatibilityScore === a.compatibilityScore && - b.compatibilityBonusScore != null && a.compatibilityBonusScore != null - ) - return b.compatibilityBonusScore - a.compatibilityBonusScore; - - return b.compatibilityScore - a.compatibilityScore; - }); - }); - } - - try { - // if this file gets very big, we don't want to load it on every CLI usage - const {recommendedModels} = await import("../recommendedModels.js"); - - for (const recommendedModel of recommendedModels) { - const potentialUrls = resolveModelRecommendationFileOptions(recommendedModel); - - if (potentialUrls.length > 0) - recommendedModelOptions.push({ - type: "recommendedModel", - title: recommendedModel.name, - potentialUrls, - description: recommendedModel.description - }); - } - } catch (err) { - // do nothing - } - - let initialFocusIndex = 3; // first model option - const options: ModelOption[] = [ - { - type: "action", - text: "Enter a model URL or file path...", - key: "getPath" - }, - ...( - localModelFileOptions.length === 0 - ? [] - : [ - { - type: "separator", - text: () => " " + chalk.gray("-".repeat(4)) - }, - { - type: "separator", - text: " " + chalk.bold("Downloaded models") + " " + chalk.dim(`(${getReadablePath(targetDirectory)})`) - }, - ...localModelFileOptions - ] satisfies ModelOption[] - ), - ...( - recommendedModelOptions.length === 0 - ? [] - : [ - { - type: "separator", - text: () => " " + chalk.gray("-".repeat(4)) - }, - { - type: "separator", - text: " " + chalk.bold("Recommended models") + " " + chalk.dim("(select to download)") - }, - ...recommendedModelOptions - ] satisfies ModelOption[] - ) - ]; - - try { - // eslint-disable-next-line no-constant-condition - while (true) { - const minWidth = Math.min(80, process.stdout.columns - 1); - const selectedItem = await basicChooseFromListConsoleInteraction({ - title(item, rerender) { - const title = chalk.bold("Select a model:") + " "; - - const vramState = llama.getVramState(); - const vramStateText = vramState.total === 0 - ? chalk.bgGray( - " " + - "No GPU" + - " " - ) - : ( - chalk.bgGray( - " " + - chalk.yellow("GPU:") + " " + getPrettyBuildGpuName(llama.gpu) + - " " - ) + - " " + - chalk.bgGray( - " " + - chalk.yellow("VRAM usage:") + " " + - (String(Math.floor((vramState.used / vramState.total) * 100 * 100) / 100) + "%") + " " + - chalk.dim("(" + bytes(vramState.used) + "/" + bytes(vramState.total) + ")") + - " " - ) - ); - - const pad = Math.max(0, minWidth - (stripAnsi(title).length + stripAnsi(vramStateText).length)); - - lastVramState = vramState; - clearTimeout(scheduledTitleRerenderTimeout); - scheduledTitleRerenderTimeout = setTimeout(() => { - const vramState = llama.getVramState(); - if (lastVramState.used !== vramState.used || lastVramState.total !== vramState.total) - rerender(); - }, vramStateUpdateInterval); - - return [ - title, - " ".repeat(pad), - vramStateText - ].join(""); - }, - footer(item) { - if (item.type !== "recommendedModel" || item.description == null) - return undefined; - - const leftPad = 3; - const maxWidth = Math.max(1, process.stdout.columns - leftPad); - const lines = splitAnsiToLines(item.description, maxWidth); - - return " \n" + - " ".repeat(leftPad) + chalk.bold.gray("Model description") + "\n" + - lines.map((line) => (" ".repeat(leftPad) + line)).join("\n") + "\n" + - splitAnsiToLines(renderRecommendedModelTechnicalInfo(item.selectedUrl, maxWidth, canUseGpu), maxWidth) - .map((line) => (" ".repeat(leftPad) + line)) - .join("\n"); - }, - items: options, - renderItem(item, focused, rerender) { - return renderSelectionItem(item, focused, rerender, activeInteractionController.signal, llama); - }, - canFocusItem(item) { - return item.type === "recommendedModel" || item.type === "localModel" || item.type === "action"; - }, - canSelectItem(item) { - if (item.type === "recommendedModel") - return item.selectedUrl != null; - - return item.type === "localModel" || item.type === "action"; - }, - initialFocusIndex: Math.min(initialFocusIndex, options.length - 1), - aboveItemsPadding: 1, - belowItemsPadding: 1, - renderSummaryOnExit(item) { - if (item == null || item.type === "action" || item.type === "separator") - return ""; - else if (item.type === "localModel") { - const modelTitle = item.title instanceof Function - ? item.title() - : item.title; - - return logSymbols.success + " Selected model " + chalk.blue(modelTitle); - } else if (item.type === "recommendedModel") { - const modelTitle = item.title instanceof Function - ? item.title() - : item.title; - - return logSymbols.success + " Selected model " + chalk.blue(modelTitle); - } - - void (item satisfies never); - return ""; - }, - exitOnCtrlC: true - }); - - if (selectedItem == null || selectedItem.type === "separator") - continue; - else if (selectedItem.type === "localModel") - return selectedItem.path; - else if (selectedItem.type === "recommendedModel" && selectedItem.selectedUrl != null) - return selectedItem.selectedUrl.url; - else if (selectedItem.type === "action") { - if (selectedItem.key === "getPath") { - initialFocusIndex = 0; - const selectedModelUrlOrPath = await askForModelUrlOrPath(); - - if (selectedModelUrlOrPath == null) - continue; - - return selectedModelUrlOrPath; - } - } - } - } finally { - activeInteractionController.abort(); - } -} - -async function askForModelUrlOrPath(): Promise { - return await consolePromptQuestion(chalk.bold("Enter a model URL or file path: "), { - exitOnCtrlC: false, - async validate(input) { - if (isUrl(input, false)) { - try { - new URL(input); - } catch (err) { - return "Invalid URL"; - } - - return null; - } - - try { - if (await fs.pathExists(input)) - return null; - - return "File does not exist"; - } catch (err) { - return "Invalid path"; - } - }, - renderSummaryOnExit(item) { - if (item == null) - return ""; - - if (isUrl(item, false)) - return logSymbols.success + " Entered model URL " + chalk.blue(item); - else - return logSymbols.success + " Entered model path " + chalk.blue(item); - } - }); -} - -function renderSelectionItem(item: ModelOption, focused: boolean, rerender: () => void, abortSignal: AbortSignal, llama: Llama) { - if (item.type === "localModel") { - let modelText = item.title instanceof Function - ? item.title() - : item.title; - - if (item.ggufInsights != null) - modelText += " " + renderModelCompatibility(item.ggufInsights, item.compatibilityScore, item.compatibilityContextSize); - else - modelText += " " + chalk.bgGray.yellow(" Cannot read metadata "); - - return renderSelectableItem(modelText, focused); - } else if (item.type === "recommendedModel") { - let modelText = item.title instanceof Function - ? item.title() - : item.title; - - if (item.selectedUrl == null) { - if (item.urlSelectionLoadingState == null) { - item.urlSelectionLoadingState = "loading"; - void selectFileForModelRecommendation({ - recommendedModelOption: item, - abortSignal, - rerenderOption: rerender, - llama - }); - } - - if (item.urlSelectionLoadingState === "loading") - modelText += " " + chalk.bgGray.yellow(" Loading info "); - else if (item.urlSelectionLoadingState === "done") - modelText += " " + chalk.bgGray.yellow(" Failed to load info "); - else - void (item.urlSelectionLoadingState satisfies never); - } else - modelText += " " + renderModelCompatibility( - item.selectedUrl.ggufInsights, - item.selectedUrl.compatibilityScore.compatibilityScore, - item.selectedUrl.compatibilityScore.resolvedValues.contextSize - ); - - return renderSelectableItem(modelText, focused); - } else if (item.type === "separator") { - return item.text instanceof Function - ? item.text() - : item.text; - } else if (item.type === "action") { - const actionText = item.text instanceof Function - ? item.text() - : item.text; - - return renderSelectableItem(actionText, focused); - } - - void (item satisfies never); - return ""; -} - -function renderSelectableItem(text: string, focused: boolean) { - if (focused) - return " " + chalk.cyan(arrowChar) + " " + chalk.cyan(text); - - return " * " + text; -} - -function renderModelCompatibility( - ggufInsights: GgufInsights, compatibilityScore: number | undefined, compatibilityContextSize: number | undefined -) { - const info: string[] = []; - - if (compatibilityScore != null) - info.push( - renderCompatibilityPercentageWithColors(compatibilityScore * 100) + chalk.whiteBright(" compatibility") - + ( - compatibilityContextSize == null - ? "" - : (chalk.gray(" | ") + chalk.yellow(getReadableContextSize(compatibilityContextSize)) + chalk.whiteBright(" context")) - ) - ); - - info.push(chalk.yellow("Size:") + " " + chalk.whiteBright(bytes(ggufInsights.modelSize))); - - return info - .map((item) => chalk.bgGray(" " + item + " ")) - .join(" "); -} - -function renderRecommendedModelTechnicalInfo( - modelSelectedUrl: (ModelOption & {type: "recommendedModel"})["selectedUrl"], - maxWidth: number, - canUseGpu: boolean -) { - if (modelSelectedUrl == null) - return " \n" + chalk.bgGray.yellow(" Loading info ") + "\n "; - - const ggufInsights = modelSelectedUrl.ggufInsights; - const compatibilityScore = modelSelectedUrl.compatibilityScore; - - const longestTitle = Math.max("Model info".length, "Resolved config".length) + 1; - return " \n" + [ - renderInfoLine({ - title: "Model info", - padTitle: longestTitle, - separateLines: false, - maxWidth, - info: [{ - title: "Size", - value: bytes(ggufInsights.modelSize) - }, { - show: ggufInsights.trainContextSize != null, - title: "Train context size", - value: () => getReadableContextSize(ggufInsights.trainContextSize ?? 0) - }] - }), - renderInfoLine({ - title: "Resolved config", - padTitle: longestTitle, - separateLines: false, - maxWidth, - info: [{ - title: "", - value: renderCompatibilityPercentageWithColors(compatibilityScore.compatibilityScore * 100) + " compatibility" - }, { - show: ggufInsights.trainContextSize != null, - title: "Context size", - value: getReadableContextSize(compatibilityScore.resolvedValues.contextSize) - }, { - show: canUseGpu, - title: "GPU layers", - value: () => ( - compatibilityScore.resolvedValues.gpuLayers + "/" + ggufInsights.totalLayers + " " + - chalk.dim(`(${Math.floor((compatibilityScore.resolvedValues.gpuLayers / ggufInsights.totalLayers) * 100)}%)`) - ) - }, { - show: canUseGpu, - title: "VRAM usage", - value: () => bytes(compatibilityScore.resolvedValues.totalVramUsage) - }] - }) - ].join("\n"); -} - -function renderCompatibilityPercentageWithColors(percentage: number, { - greenBright = 100, - green = 95, - yellow = 85, - yellowBright = 75 -}: { - greenBright?: number, - green?: number, - yellow?: number, - yellowBright?: number -} = {}): string { - const percentageText = String(Math.floor(percentage)) + "%"; - - if (percentage >= greenBright) - return chalk.greenBright(percentageText); - else if (percentage >= green) - return chalk.green(percentageText); - else if (percentage >= yellow) - return chalk.yellow(percentageText); - else if (percentage >= yellowBright) - return chalk.yellowBright(percentageText); - - return chalk.red(percentageText); -} - -async function selectFileForModelRecommendation({ - recommendedModelOption, llama, abortSignal, rerenderOption -}: { - recommendedModelOption: ModelOption & {type: "recommendedModel"}, - llama: Llama, - abortSignal: AbortSignal, - rerenderOption(): void -}) { - try { - let bestScore: number | undefined = undefined; - let bestScoreSelectedUrl: (ModelOption & {type: "recommendedModel"})["selectedUrl"] | undefined = undefined; - - for (const potentialUrl of recommendedModelOption.potentialUrls) { - if (abortSignal.aborted) - return; - - try { - const ggufFileInfo = await readGgufFileInfo(potentialUrl, { - sourceType: "network", - signal: abortSignal - }); - const ggufInsights = await GgufInsights.from(ggufFileInfo, llama); - - if (abortSignal.aborted) - return; - - const compatibilityScore = ggufInsights.configurationResolver.scoreModelConfigurationCompatibility(); - - if (bestScore == null || compatibilityScore.compatibilityScore > bestScore) { - bestScore = compatibilityScore.compatibilityScore; - bestScoreSelectedUrl = { - url: potentialUrl, - ggufInsights, - compatibilityScore - }; - - if (bestScore === 1) - break; - } - } catch (err) { - // do nothing - } - } - - recommendedModelOption.selectedUrl = bestScoreSelectedUrl; - recommendedModelOption.urlSelectionLoadingState = "done"; - rerenderOption(); - } catch (err) { - recommendedModelOption.urlSelectionLoadingState = "done"; - rerenderOption(); - } -} diff --git a/src/cli/utils/splitAnsiToLines.ts b/src/cli/utils/splitAnsiToLines.ts index eba4eb33..e3389539 100644 --- a/src/cli/utils/splitAnsiToLines.ts +++ b/src/cli/utils/splitAnsiToLines.ts @@ -1,18 +1,36 @@ import stripAnsi from "strip-ansi"; import sliceAnsi from "slice-ansi"; -export function splitAnsiToLines(text: string | undefined, width: number) { +export function splitAnsiToLines(text: string | undefined, width: number, maxRoundToWords: number = Math.min(16, width)) { if (text == null || text === "") return []; const lines: string[] = []; - const linesWithoutAnsi = stripAnsi(text) - .split("\n"); + const linesWithoutAnsi = stripAnsi(text).split("\n"); let textIndex = 0; for (const line of linesWithoutAnsi) { - for (let lineIndex = 0; lineIndex < line.length; lineIndex += width) - lines.push(sliceAnsi(text, textIndex + lineIndex, Math.min(textIndex + lineIndex + width, textIndex + line.length))); + for (let lineIndex = 0; lineIndex < line.length;) { + let currentWidth = width; + + if (maxRoundToWords > 0) { + const currentMaxWidth = Math.min(currentWidth, line.length - lineIndex); + const currentChunkLastChar = line[lineIndex + currentMaxWidth - 1]; + const nextChunkFirstChar = line[lineIndex + currentMaxWidth] ?? ""; + + if (currentChunkLastChar !== " " && nextChunkFirstChar !== "" && nextChunkFirstChar !== " ") { + const lastSpaceIndex = line.lastIndexOf(" ", lineIndex + currentMaxWidth - 1); + if (lastSpaceIndex >= 0) { + const diff = currentMaxWidth - (lastSpaceIndex + " ".length); + if (diff > 0 && diff < maxRoundToWords && diff < currentWidth) + currentWidth -= diff; + } + } + } + + lines.push(sliceAnsi(text, textIndex + lineIndex, Math.min(textIndex + lineIndex + currentWidth, textIndex + line.length))); + lineIndex += currentWidth; + } textIndex += line.length + "\n".length; } diff --git a/src/cli/utils/withCliCommandDescriptionDocsUrl.ts b/src/cli/utils/withCliCommandDescriptionDocsUrl.ts new file mode 100644 index 00000000..e64521d0 --- /dev/null +++ b/src/cli/utils/withCliCommandDescriptionDocsUrl.ts @@ -0,0 +1,28 @@ +import {getIsInDocumentationMode} from "../../state.js"; +import {documentationPageUrls} from "../../config.js"; + +export function withCliCommandDescriptionDocsUrl(description: string, docsUrl: string) { + const isInDocumentationMode = getIsInDocumentationMode(); + + if (isInDocumentationMode) + return description; + + return [ + description, + docsUrl + ].join("\n").trim(); +} + +export function withoutCliCommandDescriptionDocsUrl(description: string | boolean) { + if (typeof description !== "string") + return description; + + const lines = description.split("\n"); + if (lines.length > 0 && lines[lines.length - 1].startsWith(documentationPageUrls.CLI.index)) + return lines + .slice(0, -1) + .join("\n") + .trim(); + + return description; +} diff --git a/src/commands.ts b/src/commands.ts index ef49bd5e..a61556b3 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1,6 +1,10 @@ import {BuildLlamaCppCommand} from "./cli/commands/BuildCommand.js"; import {DownloadLlamaCppCommand} from "./cli/commands/DownloadCommand.js"; import {ClearLlamaCppBuildCommand} from "./cli/commands/ClearCommand.js"; +import {_startCreateCli} from "./cli/startCreateCli.js"; import {getBuildDefaults} from "./utils/getBuildDefaults.js"; export {BuildLlamaCppCommand, DownloadLlamaCppCommand, ClearLlamaCppBuildCommand, getBuildDefaults}; + +/** @internal */ +export {_startCreateCli}; diff --git a/src/config.ts b/src/config.ts index b542bb8e..e750210a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,7 +3,7 @@ import * as path from "path"; import * as os from "os"; import process from "process"; import envVar from "env-var"; -import * as uuid from "uuid"; +import {nanoid} from "nanoid"; import {getBinariesGithubRelease} from "./bindings/utils/binariesGithubRelease.js"; import { nodeLlamaCppGpuOptions, LlamaLogLevel, LlamaLogLevelValues, parseNodeLlamaCppGpuOption, nodeLlamaCppGpuOffStringOptions @@ -19,9 +19,11 @@ export const llamaToolchainsDirectory = path.join(llamaDirectory, "toolchains"); export const llamaPrebuiltBinsDirectory = path.join(__dirname, "..", "llamaBins"); export const llamaLocalBuildBinsDirectory = path.join(llamaDirectory, "localBuilds"); export const llamaBinsGrammarsDirectory = path.join(__dirname, "..", "llama", "grammars"); +export const projectTemplatesDirectory = path.join(__dirname, "..", "templates"); +export const packedProjectTemplatesDirectory = path.join(projectTemplatesDirectory, "packed"); export const llamaCppDirectory = path.join(llamaDirectory, "llama.cpp"); export const llamaCppGrammarsDirectory = path.join(llamaDirectory, "llama.cpp", "grammars"); -export const tempDownloadDirectory = path.join(os.tmpdir(), "node-llama-cpp", uuid.v4()); +export const tempDownloadDirectory = path.join(os.tmpdir(), "node-llama-cpp", nanoid()); export const cliHomedirDirectory = path.join(os.homedir(), ".node-llama-cpp"); export const chatCommandHistoryFilePath = path.join(cliHomedirDirectory, ".chat_repl_history"); export const cliModelsDirectory = path.join(cliHomedirDirectory, "models"); @@ -62,9 +64,12 @@ export const defaultLlamaCppGpuSupport = parseNodeLlamaCppGpuOption( )) ) ); -export const defaultLlamaCppDebugLogs = env.get("NODE_LLAMA_CPP_LOG_LEVEL") +export const defaultLlamaCppLogLevel = env.get("NODE_LLAMA_CPP_LOG_LEVEL") .default(LlamaLogLevel.warn) .asEnum(LlamaLogLevelValues); +export const defaultLlamaCppDebugMode = env.get("NODE_LLAMA_CPP_DEBUG") + .default("false") + .asBool(); export const defaultSkipDownload = env.get("NODE_LLAMA_CPP_SKIP_DOWNLOAD") .default("false") .asBool(); @@ -88,9 +93,27 @@ export const npxRunPrefix = "npx --no "; export const enableRecursiveClone = false; const documentationUrl = "https://withcatai.github.io/node-llama-cpp"; +const documentationCliUrl = documentationUrl + "/guide/cli"; export const documentationPageUrls = { CUDA: documentationUrl + "/guide/CUDA", - Vulkan: documentationUrl + "/guide/vulkan" + Vulkan: documentationUrl + "/guide/vulkan", + CLI: { + index: documentationCliUrl, + Pull: documentationCliUrl + "/pull", + Chat: documentationCliUrl + "/chat", + Init: documentationCliUrl + "/init", + Download: documentationCliUrl + "/download", + Complete: documentationCliUrl + "/complete", + Infill: documentationCliUrl + "/infill", + Inspect: { + index: documentationCliUrl + "/inspect", + GPU: documentationCliUrl + "/inspect/gpu", + GGUF: documentationCliUrl + "/inspect/gguf", + Measure: documentationCliUrl + "/inspect/measure" + }, + Build: documentationCliUrl + "/build", + Clear: documentationCliUrl + "/clear" + } } as const; export const recommendedBaseDockerImage = "node:20"; export const minAllowedContextSizeInCalculations = 24; diff --git a/src/evaluator/LlamaContext/LlamaContext.ts b/src/evaluator/LlamaContext/LlamaContext.ts index 20c64553..d811ff7f 100644 --- a/src/evaluator/LlamaContext/LlamaContext.ts +++ b/src/evaluator/LlamaContext/LlamaContext.ts @@ -922,7 +922,6 @@ export class LlamaContextSequence { if (evalTokens.length === 0) return; - // eslint-disable-next-line no-constant-condition while (true) { this._ensureNotDisposed(); diff --git a/src/evaluator/LlamaModel.ts b/src/evaluator/LlamaModel.ts index 479270db..4aea5131 100644 --- a/src/evaluator/LlamaModel.ts +++ b/src/evaluator/LlamaModel.ts @@ -54,7 +54,8 @@ export type LlamaModelOptions = { /** * Use mmap if possible. - * Enabled by default in llama.cpp. + * Defaults to `true`. + * If LoRA is used, this will always be set to `false`. */ useMmap?: boolean, @@ -71,8 +72,42 @@ export type LlamaModelOptions = { */ checkTensors?: boolean, + /** + * Load the provided LoRA adapters onto the model after loading the model. + * LoRA adapters are used to modify the weights of a pretrained model to adapt to new tasks or domains + * without the need for extensive retraining from scratch. + * + * If a string is provided, it will be treated as a path to a single LoRA adapter file. + */ + lora?: string | { + adapters: Array<{ + loraFilePath: string, + baseModelPath?: string, + + /** + * Defaults to `1`. + */ + scale?: number + }>, + + /** + * The number of threads to use when loading the LoRA adapters. + * set to 0 to use the maximum threads supported by the current machine hardware. + * + * Defaults to `6`. + */ + threads?: number, + + /** + * Called with the LoRA adapters load percentage when the LoRA adapters are being loaded. + * @param loadProgress - a number between 0 (exclusive) and 1 (inclusive). + */ + onLoadProgress?(loadProgress: number): void + }, + /** * Called with the load percentage when the model is being loaded. + * > **Note:** This progress does not include the progress of loading the provided LoRA adapters (when `lora` is used) * @param loadProgress - a number between 0 (exclusive) and 1 (inclusive). */ onLoadProgress?(loadProgress: number): void, @@ -89,6 +124,10 @@ export type LlamaModelOptions = { ignoreMemorySafetyChecks?: boolean }; +const defaultLoraThreads = 6; +const defaultLoraScale = 1; +const defaultUseMmap = true; + export class LlamaModel { /** @internal */ public readonly _llama: Llama; /** @internal */ public readonly _model: AddonModel; @@ -411,6 +450,22 @@ export class LlamaModel { throw new DisposedError(); } + /** @internal */ + private async _loadLora({ + loraFilePath, baseModelPath, scale, threads + }: { + loraFilePath: string, baseModelPath?: string, scale?: number, threads: number + }) { + await this._model.loadLora( + path.resolve(process.cwd(), loraFilePath), + scale ?? defaultLoraScale, + Math.max(0, Math.floor(threads)), + baseModelPath == null + ? undefined + : path.resolve(process.cwd(), baseModelPath) + ); + } + /** @internal */ public static async _create(modelOptions: LlamaModelOptions, { _llama @@ -418,6 +473,14 @@ export class LlamaModel { _llama: Llama }) { const {loadSignal} = modelOptions; + let useMmap = modelOptions.useMmap ?? defaultUseMmap; + const loraOptions: LlamaModelOptions["lora"] = typeof modelOptions.lora === "string" + ? {adapters: [{loraFilePath: modelOptions.lora}]} + : modelOptions.lora; + + if (loraOptions?.adapters != null && loraOptions.adapters.length > 0) + useMmap = false; // using LoRA with nmap crashes the process + const fileInfo = await readGgufFileInfo(modelOptions.modelPath, { sourceType: "filesystem", signal: loadSignal @@ -428,7 +491,7 @@ export class LlamaModel { }); const vramRequiredEstimate = ggufInsights.estimateModelResourceRequirements({gpuLayers: gpuLayers}).gpuVram; - const model = new LlamaModel({...modelOptions, gpuLayers}, {_fileInfo: fileInfo, _fileInsights: ggufInsights, _llama}); + const model = new LlamaModel({...modelOptions, gpuLayers, useMmap}, {_fileInfo: fileInfo, _fileInsights: ggufInsights, _llama}); const modelCreationMemoryReservation = modelOptions.ignoreMemorySafetyChecks ? null : _llama._vramOrchestrator.reserveMemory(vramRequiredEstimate); @@ -456,6 +519,45 @@ export class LlamaModel { } else if (!modelLoaded) throw new Error("Failed to load model"); + loadSignal?.removeEventListener("abort", onAbort); + + if (loraOptions != null && loraOptions.adapters.length > 0) { + const loraThreads = loraOptions.threads ?? defaultLoraThreads; + let loadedAdapters = 0; + + for (const adapter of loraOptions.adapters) { + try { + await model._loadLora({ + loraFilePath: adapter.loraFilePath, + baseModelPath: adapter.baseModelPath, + scale: adapter.scale, + threads: loraThreads + }); + loadedAdapters++; + + try { + loraOptions.onLoadProgress?.(loadedAdapters / loraOptions.adapters.length); + } catch (err) { + console.error(err); + } + } catch (err) { + await model._model.dispose(); + throw err; + } + + if (loadSignal?.aborted) { + await model._model.dispose(); + throw loadSignal.reason; + } + } + } else if (loraOptions?.onLoadProgress != null) { + try { + loraOptions.onLoadProgress(1); + } catch (err) { + console.error(err); + } + } + return model; } finally { loadSignal?.removeEventListener("abort", onAbort); diff --git a/src/utils/createModelDownloader.ts b/src/utils/createModelDownloader.ts index b9f92c99..0cdaa46b 100644 --- a/src/utils/createModelDownloader.ts +++ b/src/utils/createModelDownloader.ts @@ -18,7 +18,12 @@ export type ModelDownloaderOptions = { fileName?: string, headers?: Record, + + /** + * Defaults to `false`. + */ showCliProgress?: boolean, + onProgress?: (status: {totalSize: number, downloadedSize: number}) => void, /** diff --git a/templates/.gitignore b/templates/.gitignore new file mode 100644 index 00000000..70f76b39 --- /dev/null +++ b/templates/.gitignore @@ -0,0 +1 @@ +/*/**/package-lock.json diff --git a/templates/electron-typescript-react/.editorconfig b/templates/electron-typescript-react/.editorconfig new file mode 100644 index 00000000..1c7d0091 --- /dev/null +++ b/templates/electron-typescript-react/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +indent_style = space +indent_size = 4 + +[{*.ts,*.tsx,*.js,*.jsx,*.css,*.scss}] +insert_final_newline = true + +[{package.json,package-lock.json,manifest.json,electron-builder.json5}] +indent_size = 2 + +[*.yml] +indent_size = 2 diff --git a/templates/electron-typescript-react/.eslintrc.json b/templates/electron-typescript-react/.eslintrc.json new file mode 100644 index 00000000..bc9f536d --- /dev/null +++ b/templates/electron-typescript-react/.eslintrc.json @@ -0,0 +1,160 @@ +{ + "root": true, + "env": { + "node": true, + "browser": false, + "es6": true + }, + "ignorePatterns": ["/dist", "/dist-electron", "/release", "/models"], + "extends": [ + "eslint:recommended", + "plugin:jsdoc/recommended", + "plugin:react-hooks/recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 2023, + "sourceType": "module" + }, + "overrides": [{ + "files": ["**.ts", "**.tsx"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:jsdoc/recommended-typescript" + ], + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint", + "import", + "jsdoc", + "react-refresh" + ], + "rules": { + "@typescript-eslint/explicit-module-boundary-types": ["off"], + "@typescript-eslint/ban-ts-comment": ["off"], + "@typescript-eslint/no-explicit-any": ["off"], + "semi": ["off"], + "@typescript-eslint/semi": ["warn", "always"], + "@typescript-eslint/no-inferrable-types": ["off"], + "@typescript-eslint/member-ordering": ["warn", { + "default": ["field", "constructor", "method", "signature"], + "typeLiterals": [] + }], + "@typescript-eslint/parameter-properties": ["warn", { + "allow": [] + }], + "@typescript-eslint/explicit-member-accessibility": ["warn"], + "@typescript-eslint/member-delimiter-style": ["warn", { + "multiline": { + "delimiter": "comma", + "requireLast": false + }, + "singleline": { + "delimiter": "comma", + "requireLast": false + }, + "multilineDetection": "brackets" + }], + "jsdoc/require-param": ["off"], + "jsdoc/check-param-names": ["warn", { + "checkDestructured": false + }], + "jsdoc/require-returns": ["off"], + "jsdoc/require-jsdoc": ["off"], + "jsdoc/require-yields": ["off"], + "jsdoc/require-param-description": ["off"] + } + }], + "plugins": [ + "@typescript-eslint", + "import", + "jsdoc", + "react-refresh" + ], + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [".ts"] + }, + "jsdoc": { + "exemptDestructuredRootsFromChecks": true, + "tagNamePreference": { + "hidden": "hidden" + } + } + }, + "rules": { + "indent": ["warn", 4, { + "SwitchCase": 1, + "FunctionDeclaration": { + "parameters": "first" + } + }], + "eqeqeq": ["off"], + "no-undef": "off", + "quotes": ["warn", "double", { "avoidEscape": true }], + "no-unused-vars": ["warn", { + "args": "none", + "ignoreRestSiblings": true, + "varsIgnorePattern": "^set" + }], + "no-prototype-builtins": ["off"], + "object-curly-spacing": ["warn", "never"], + "semi": ["warn", "always"], + "no-undefined": ["off"], + "array-bracket-newline": ["error", "consistent"], + "brace-style": ["error", "1tbs", { + "allowSingleLine": false + }], + "comma-spacing": ["error", { + "before": false, + "after": true + }], + "comma-style": ["error", "last"], + "comma-dangle": ["error", "never"], + "no-var": ["error"], + "import/order": ["error", { + "groups": ["builtin", "external","internal", "parent", "sibling", "index", "type", "object", "unknown"], + "warnOnUnassignedImports": true + }], + "newline-per-chained-call": ["error", { + "ignoreChainWithDepth": 2 + }], + "no-confusing-arrow": ["error"], + "no-const-assign": ["error"], + "no-duplicate-imports": ["error", { + "includeExports": true + }], + "camelcase": ["warn"], + "jsx-quotes": ["warn"], + "yoda": ["error", "never", { + "exceptRange": true + }], + "no-eval": ["error"], + "array-callback-return": ["error"], + "no-empty": ["error", { + "allowEmptyCatch": true + }], + "keyword-spacing": ["warn"], + "space-infix-ops": ["warn"], + "spaced-comment": ["warn", "always", { + "markers": ["/"] + }], + "eol-last": ["warn", "always"], + "max-len": ["warn", { + "code": 140, + "tabWidth": 4, + "ignoreStrings": true + }], + "react-refresh/only-export-components": ["warn", { + "allowConstantExport": true + }], + "react-hooks/exhaustive-deps": ["off"] + } +} diff --git a/templates/electron-typescript-react/.gitignore b/templates/electron-typescript-react/.gitignore new file mode 100644 index 00000000..047135f3 --- /dev/null +++ b/templates/electron-typescript-react/.gitignore @@ -0,0 +1,9 @@ +/.idea +/.vscode +node_modules +.DS_Store + +/dist +/dist-electron +/release +/models diff --git a/templates/electron-typescript-react/README.md b/templates/electron-typescript-react/README.md new file mode 100644 index 00000000..11a2f5fe --- /dev/null +++ b/templates/electron-typescript-react/README.md @@ -0,0 +1,13 @@ +# Electron + TypeScript + React + Vite + `node-llama-cpp` +This template provides a minimal setup to get an Electron app working with TypeScript and `node-llama-cpp`, React with TypeScript for the renderer, and some ESLint rules. + +## Get started +Install node modules and download the model files used by `node-llama-cpp`: +```bash +npm install +``` + +Start the project: +```bash +npm start +``` diff --git a/templates/electron-typescript-react/electron-builder.json5 b/templates/electron-typescript-react/electron-builder.json5 new file mode 100644 index 00000000..d2c73cd4 --- /dev/null +++ b/templates/electron-typescript-react/electron-builder.json5 @@ -0,0 +1,51 @@ +// @see - https://www.electron.build/configuration/configuration +{ + "$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json", + "appId": "YourAppID", + "asar": true, + "productName": "YourAppName", + "directories": { + "output": "release/${version}" + }, + "files": [ + "dist", + "dist-electron", + "!node_modules/node-llama-cpp/llamaBins/*", + "node_modules/node-llama-cpp/llamaBins/${os}-${arch}*/**/*", + "!node_modules/node-llama-cpp/llama/localBuilds/*", + "node_modules/node-llama-cpp/llama/localBuilds/${os}-${arch}*/**/*" + ], + "asarUnpack": [ + "node_modules/node-llama-cpp/llamaBins", + "node_modules/node-llama-cpp/llama/localBuilds" + ], + "mac": { + "target": [ + "dmg" + ], + "artifactName": "${productName}-Mac-${version}-Installer.${ext}" + }, + "win": { + "target": [ + { + "target": "nsis", + "arch": [ + "x64" + ] + } + ], + "artifactName": "${productName}-Windows-${version}-Setup.${ext}" + }, + "nsis": { + "oneClick": false, + "perMachine": false, + "allowToChangeInstallationDirectory": true, + "deleteAppDataOnUninstall": false + }, + "linux": { + "target": [ + "AppImage" + ], + "artifactName": "${productName}-Linux-${version}.${ext}" + } +} diff --git a/templates/electron-typescript-react/electron/electron-env.d.ts b/templates/electron-typescript-react/electron/electron-env.d.ts new file mode 100644 index 00000000..ed472c93 --- /dev/null +++ b/templates/electron-typescript-react/electron/electron-env.d.ts @@ -0,0 +1,27 @@ +/// + +declare namespace NodeJS { + interface ProcessEnv { + /** + * The built directory structure + * + * ```tree + * ├─┬─┬ dist + * │ │ └── index.html + * │ │ + * │ ├─┬ dist-electron + * │ │ ├── index.js + * │ │ └── preload.mjs + * │ + * ``` + */ + APP_ROOT: string, + /** /dist/ or /public/ */ + VITE_PUBLIC: string + } +} + +// Used in Renderer process, expose in `preload.ts` +interface Window { + ipcRenderer: import("electron").IpcRenderer +} diff --git a/templates/electron-typescript-react/electron/index.ts b/templates/electron-typescript-react/electron/index.ts new file mode 100644 index 00000000..aa6390b2 --- /dev/null +++ b/templates/electron-typescript-react/electron/index.ts @@ -0,0 +1,67 @@ +import {fileURLToPath} from "node:url"; +import path from "node:path"; +import {app, BrowserWindow} from "electron"; +import {registerLlmRpc} from "./rpc/llmRpc.ts"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +// The built directory structure +// +// ├─┬─┬ dist +// │ │ └── index.html +// │ │ +// │ ├─┬ dist-electron +// │ │ ├── index.js +// │ │ └── preload.mjs +// │ +process.env.APP_ROOT = path.join(__dirname, ".."); + +export const VITE_DEV_SERVER_URL = process.env["VITE_DEV_SERVER_URL"]; +export const MAIN_DIST = path.join(process.env.APP_ROOT, "dist-electron"); +export const RENDERER_DIST = path.join(process.env.APP_ROOT, "dist"); + +process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL + ? path.join(process.env.APP_ROOT, "public") + : RENDERER_DIST; + +let win: BrowserWindow | null; + +function createWindow() { + win = new BrowserWindow({ + icon: path.join(process.env.VITE_PUBLIC, "electron-vite.svg"), + webPreferences: { + preload: path.join(__dirname, "preload.mjs") + } + }); + registerLlmRpc(win); + + // Test active push message to Renderer-process. + win.webContents.on("did-finish-load", () => { + win?.webContents.send("main-process-message", (new Date).toLocaleString()); + }); + + if (VITE_DEV_SERVER_URL) + void win.loadURL(VITE_DEV_SERVER_URL); + else + void win.loadFile(path.join(RENDERER_DIST, "index.html")); +} + +// Quit when all windows are closed, except on macOS. There, it's common +// for applications and their menu bar to stay active until the user quits +// explicitly with Cmd + Q. +app.on("window-all-closed", () => { + if (process.platform !== "darwin") { + app.quit(); + win = null; + } +}); + +app.on("activate", () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } +}); + +app.whenReady().then(createWindow); diff --git a/templates/electron-typescript-react/electron/preload.ts b/templates/electron-typescript-react/electron/preload.ts new file mode 100644 index 00000000..0e040983 --- /dev/null +++ b/templates/electron-typescript-react/electron/preload.ts @@ -0,0 +1,24 @@ +import {ipcRenderer, contextBridge} from "electron"; + +// --------- Expose some API to the Renderer process --------- +contextBridge.exposeInMainWorld("ipcRenderer", { + on(...args: Parameters) { + const [channel, listener] = args; + return ipcRenderer.on(channel, (event, ...args) => listener(event, ...args)); + }, + off(...args: Parameters) { + const [channel, ...omit] = args; + return ipcRenderer.off(channel, ...omit); + }, + send(...args: Parameters) { + const [channel, ...omit] = args; + return ipcRenderer.send(channel, ...omit); + }, + invoke(...args: Parameters) { + const [channel, ...omit] = args; + return ipcRenderer.invoke(channel, ...omit); + } + + // You can expose other APIs you need here + // ... +}); diff --git a/templates/electron-typescript-react/electron/rpc/llmRpc.ts b/templates/electron-typescript-react/electron/rpc/llmRpc.ts new file mode 100644 index 00000000..4731a4ed --- /dev/null +++ b/templates/electron-typescript-react/electron/rpc/llmRpc.ts @@ -0,0 +1,78 @@ +import path from "node:path"; +import fs from "node:fs/promises"; +import {BrowserWindow, dialog} from "electron"; +import {createElectronSideBirpc} from "../utils/createElectronSideBirpc.ts"; +import {llmFunctions, llmState} from "../state/llmState.ts"; +import type {RenderedFunctions} from "../../src/rpc/llmRpc.ts"; + +const modelDirectoryPath = path.join(process.cwd(), "models"); + +export class ElectronLlmRpc { + public readonly rendererLlmRpc: ReturnType>; + + public readonly functions = { + async selectModelFileAndLoad() { + const res = await dialog.showOpenDialog({ + message: "Select a model file", + title: "Select a model file", + filters: [ + {name: "Model file", extensions: ["gguf"]} + ], + buttonLabel: "Open", + defaultPath: await pathExists(modelDirectoryPath) + ? modelDirectoryPath + : undefined, + properties: ["openFile"] + }); + + if (!res.canceled && res.filePaths.length > 0) { + llmState.state = { + ...llmState.state, + selectedModelFilePath: path.resolve(res.filePaths[0]) + }; + + if (!llmState.state.llama.loaded) + await llmFunctions.loadLlama(); + + await llmFunctions.loadModel(llmState.state.selectedModelFilePath!); + await llmFunctions.createContext(); + await llmFunctions.createContextSequence(); + await llmFunctions.chatSession.createChatSession(); + } + }, + getState() { + return llmState.state; + }, + prompt: llmFunctions.chatSession.prompt, + stopActivePrompt: llmFunctions.chatSession.stopActivePrompt, + resetChatHistory: llmFunctions.chatSession.resetChatHistory + } as const; + + public constructor(window: BrowserWindow) { + this.rendererLlmRpc = createElectronSideBirpc("llmRpc", "llmRpc", window, this.functions); + + this.sendCurrentLlmState = this.sendCurrentLlmState.bind(this); + + llmState.createChangeListener(this.sendCurrentLlmState); + this.sendCurrentLlmState(); + } + + public sendCurrentLlmState() { + this.rendererLlmRpc.updateState(llmState.state); + } +} + +export type ElectronFunctions = typeof ElectronLlmRpc.prototype.functions; + +export function registerLlmRpc(window: BrowserWindow) { + new ElectronLlmRpc(window); +} + +async function pathExists(path: string) { + try { + await fs.access(path); + return true; + } catch { + return false; + } +} diff --git a/templates/electron-typescript-react/electron/state/llmState.ts b/templates/electron-typescript-react/electron/state/llmState.ts new file mode 100644 index 00000000..f2472859 --- /dev/null +++ b/templates/electron-typescript-react/electron/state/llmState.ts @@ -0,0 +1,413 @@ +import path from "node:path"; +import {getLlama, Llama, LlamaChatSession, LlamaContext, LlamaContextSequence, LlamaModel, Token} from "node-llama-cpp"; +import {withLock, State} from "lifecycle-utils"; + +export const llmState = new State({ + llama: { + loaded: false + }, + model: { + loaded: false + }, + context: { + loaded: false + }, + contextSequence: { + loaded: false + }, + chatSession: { + loaded: false, + generatingResult: false, + simplifiedChat: [] + } +}); + +export type LlmState = { + llama: { + loaded: boolean, + error?: string + }, + selectedModelFilePath?: string, + model: { + loaded: boolean, + loadProgress?: number, + name?: string, + error?: string + }, + context: { + loaded: boolean, + error?: string + }, + contextSequence: { + loaded: boolean, + error?: string + }, + chatSession: { + loaded: boolean, + generatingResult: boolean, + simplifiedChat: SimplifiedChatItem[] + } +}; + +type SimplifiedChatItem = { + type: "user" | "model", + message: string +}; + +let llama: Llama | null = null; +let model: LlamaModel | null = null; +let context: LlamaContext | null = null; +let contextSequence: LlamaContextSequence | null = null; + +let chatSession: LlamaChatSession | null = null; +let promptAbortController: AbortController | null = null; +const inProgressResponse: Token[] = []; + +export const llmFunctions = { + async loadLlama() { + await withLock(llmFunctions, "llama", async () => { + if (llama != null) { + try { + await llama.dispose(); + llama = null; + } catch (err) { + console.error("Failed to dispose llama", err); + } + } + + try { + llmState.state = { + ...llmState.state, + llama: {loaded: false} + }; + + llama = await getLlama(); + llmState.state = { + ...llmState.state, + llama: {loaded: true} + }; + + llama.onDispose.createListener(() => { + llmState.state = { + ...llmState.state, + llama: {loaded: false} + }; + }); + } catch (err) { + console.error("Failed to load llama", err); + llmState.state = { + ...llmState.state, + llama: { + loaded: false, + error: String(err) + } + }; + } + }); + }, + async loadModel(modelPath: string) { + await withLock(llmFunctions, "model", async () => { + if (llama == null) + throw new Error("Llama not loaded"); + + if (model != null) { + try { + await model.dispose(); + model = null; + } catch (err) { + console.error("Failed to dispose model", err); + } + } + + try { + llmState.state = { + ...llmState.state, + model: { + loaded: false, + loadProgress: 0 + } + }; + + model = await llama.loadModel({ + modelPath, + onLoadProgress(loadProgress: number) { + llmState.state = { + ...llmState.state, + model: { + ...llmState.state.model, + loadProgress + } + }; + } + }); + llmState.state = { + ...llmState.state, + model: { + loaded: true, + loadProgress: 1, + name: path.basename(modelPath) + } + }; + + model.onDispose.createListener(() => { + llmState.state = { + ...llmState.state, + model: {loaded: false} + }; + }); + } catch (err) { + console.error("Failed to load model", err); + llmState.state = { + ...llmState.state, + model: { + loaded: false, + error: String(err) + } + }; + } + }); + }, + async createContext() { + await withLock(llmFunctions, "context", async () => { + if (model == null) + throw new Error("Model not loaded"); + + if (context != null) { + try { + await context.dispose(); + context = null; + } catch (err) { + console.error("Failed to dispose context", err); + } + } + + try { + llmState.state = { + ...llmState.state, + context: {loaded: false} + }; + + context = await model.createContext(); + llmState.state = { + ...llmState.state, + context: {loaded: true} + }; + + context.onDispose.createListener(() => { + llmState.state = { + ...llmState.state, + context: {loaded: false} + }; + }); + } catch (err) { + console.error("Failed to create context", err); + llmState.state = { + ...llmState.state, + context: { + loaded: false, + error: String(err) + } + }; + } + }); + }, + async createContextSequence() { + await withLock(llmFunctions, "contextSequence", async () => { + if (context == null) + throw new Error("Context not loaded"); + + try { + llmState.state = { + ...llmState.state, + contextSequence: {loaded: false} + }; + + contextSequence = context.getSequence(); + llmState.state = { + ...llmState.state, + contextSequence: {loaded: true} + }; + + contextSequence.onDispose.createListener(() => { + llmState.state = { + ...llmState.state, + contextSequence: {loaded: false} + }; + }); + } catch (err) { + console.error("Failed to get context sequence", err); + llmState.state = { + ...llmState.state, + contextSequence: { + loaded: false, + error: String(err) + } + }; + } + }); + }, + chatSession: { + async createChatSession() { + await withLock(llmFunctions, "chatSession", async () => { + if (contextSequence == null) + throw new Error("Context sequence not loaded"); + + if (chatSession != null) { + try { + chatSession.dispose(); + chatSession = null; + } catch (err) { + console.error("Failed to dispose chat session", err); + } + } + + try { + llmState.state = { + ...llmState.state, + chatSession: { + loaded: false, + generatingResult: false, + simplifiedChat: [] + } + }; + + chatSession = new LlamaChatSession({ + contextSequence + }); + llmState.state = { + ...llmState.state, + chatSession: { + loaded: true, + generatingResult: false, + simplifiedChat: [] + } + }; + + chatSession.onDispose.createListener(() => { + llmState.state = { + ...llmState.state, + chatSession: { + loaded: false, + generatingResult: false, + simplifiedChat: [] + } + }; + }); + } catch (err) { + console.error("Failed to create chat session", err); + llmState.state = { + ...llmState.state, + chatSession: { + loaded: false, + generatingResult: false, + simplifiedChat: [] + } + }; + } + }); + }, + async prompt(message: string) { + await withLock(llmFunctions, "chatSession", async () => { + if (chatSession == null) + throw new Error("Chat session not loaded"); + + llmState.state = { + ...llmState.state, + chatSession: { + ...llmState.state.chatSession, + generatingResult: true + } + }; + promptAbortController = new AbortController(); + + llmState.state = { + ...llmState.state, + chatSession: { + ...llmState.state.chatSession, + simplifiedChat: getSimplifiedChatHistory(true, message) + } + }; + await chatSession.prompt(message, { + signal: promptAbortController.signal, + stopOnAbortSignal: true, + onToken(chunk) { + inProgressResponse.push(...chunk); + llmState.state = { + ...llmState.state, + chatSession: { + ...llmState.state.chatSession, + simplifiedChat: getSimplifiedChatHistory(true, message) + } + }; + } + }); + llmState.state = { + ...llmState.state, + chatSession: { + ...llmState.state.chatSession, + generatingResult: false, + simplifiedChat: getSimplifiedChatHistory(false) + } + }; + inProgressResponse.length = 0; + }); + }, + stopActivePrompt() { + promptAbortController?.abort(); + }, + resetChatHistory() { + if (contextSequence == null) + return; + + chatSession = new LlamaChatSession({ + contextSequence + }); + + llmState.state = { + ...llmState.state, + chatSession: { + ...llmState.state.chatSession, + simplifiedChat: [] + } + }; + } + } +} as const; + +function getSimplifiedChatHistory(generatingResult: boolean, currentPrompt?: string) { + if (chatSession == null) + return []; + + const chatHistory: SimplifiedChatItem[] = chatSession.getChatHistory() + .flatMap((item): SimplifiedChatItem[] => { + if (item.type === "system") + return []; + else if (item.type === "user") + return [{type: "user", message: item.text}]; + else if (item.type === "model") + return [{ + type: "model", + message: item.response + .filter((value) => typeof value === "string") + .join("") + }]; + + void (item satisfies never); // ensure all item types are handled + return []; + }); + + if (generatingResult && currentPrompt != null) { + chatHistory.push({ + type: "user", + message: currentPrompt + }); + + if (inProgressResponse.length > 0) + chatHistory.push({ + type: "model", + message: chatSession.model.detokenize(inProgressResponse) + }); + } + + return chatHistory; +} diff --git a/templates/electron-typescript-react/electron/utils/createElectronSideBirpc.ts b/templates/electron-typescript-react/electron/utils/createElectronSideBirpc.ts new file mode 100644 index 00000000..72998928 --- /dev/null +++ b/templates/electron-typescript-react/electron/utils/createElectronSideBirpc.ts @@ -0,0 +1,22 @@ +import {BrowserWindow, ipcMain} from "electron"; +import {createBirpc} from "birpc"; + +export function createElectronSideBirpc< + const RendererFunction = Record, + const ElectronFunctions extends object = Record +>( + toRendererEventName: string, + fromRendererEventName: string, + window: BrowserWindow, + electronFunctions: ElectronFunctions +) { + return createBirpc(electronFunctions, { + post: (data) => window.webContents.send(toRendererEventName, data), + on: (onData) => ipcMain.on(fromRendererEventName, (event, data) => { + if (BrowserWindow.fromWebContents(event.sender) === window) + onData(data); + }), + serialize: (value) => JSON.stringify(value), + deserialize: (value) => JSON.parse(value) + }); +} diff --git a/templates/electron-typescript-react/package.json b/templates/electron-typescript-react/package.json new file mode 100644 index 00000000..ee75dd29 --- /dev/null +++ b/templates/electron-typescript-react/package.json @@ -0,0 +1,45 @@ +{ + "name": "node-llama-cpp-project", + "private": true, + "version": "0.0.0", + "main": "./dist-electron/index.js", + "type": "module", + "scripts": { + "_postinstall": "npm run models:pull", + "models:pull": "node-llama-cpp pull --dir ./models \"{{modelUrl|escape|escape}}\"", + "start": "vite dev", + "start:build": "electron ./dist-electron", + "prebuild": "rimraf ./dist ./dist-electron ./release", + "build": "tsc && vite build && electron-builder", + "lint": "npm run lint:eslint", + "lint:eslint": "eslint --ext .js --ext .ts --report-unused-disable-directives .", + "format": "npm run lint:eslint -- --fix", + "clean": "rm -rf ./node_modules ./dist ./dist-electron ./models" + }, + "dependencies": { + "birpc": "^0.2.17", + "classnames": "^2.5.1", + "lifecycle-utils": "^1.4.1", + "node-llama-cpp": "file:../..", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.2.64", + "@types/react-dom": "^18.2.21", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "@vitejs/plugin-react": "^4.2.1", + "electron": "^30.0.1", + "electron-builder": "^24.13.3", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsdoc": "^48.2.4", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "rimraf": "^5.0.7", + "typescript": "^5.2.2", + "vite": "^5.1.6", + "vite-plugin-electron": "^0.28.6" + } +} diff --git a/templates/electron-typescript-react/public/vite.svg b/templates/electron-typescript-react/public/vite.svg new file mode 100644 index 00000000..764880c5 --- /dev/null +++ b/templates/electron-typescript-react/public/vite.svg @@ -0,0 +1,18 @@ + diff --git a/templates/electron-typescript-react/src/App/App.css b/templates/electron-typescript-react/src/App/App.css new file mode 100644 index 00000000..c6f6a3a5 --- /dev/null +++ b/templates/electron-typescript-react/src/App/App.css @@ -0,0 +1,40 @@ +#root { + margin: 0 auto; + padding: 16px; + text-align: center; + width: 100%; + min-height: 100%; + align-items: center; + display: flex; + flex-direction: column; +} + +.app { + display: flex; + flex-direction: column; + width: 100%; + min-height: 100%; + max-width: 1280px; + + > .message { + flex: 1; + display: flex; + flex-direction: column; + justify-content: space-evenly; + align-items: center; + gap: 48px; + overflow: auto; + padding: 24px 0px; + + > .error { + border: solid 1px var(--error-border-color); + padding: 8px 12px; + border-radius: 12px; + box-shadow: 0px 8px 32px -16px var(--error-border-color); + } + + > .loadModel { + opacity: 0.6; + } + } +} diff --git a/templates/electron-typescript-react/src/App/App.tsx b/templates/electron-typescript-react/src/App/App.tsx new file mode 100644 index 00000000..a82d4aa5 --- /dev/null +++ b/templates/electron-typescript-react/src/App/App.tsx @@ -0,0 +1,129 @@ +import {useCallback, useLayoutEffect} from "react"; +import {llmState} from "../state/llmState.ts"; +import {electronLlmRpc} from "../rpc/llmRpc.ts"; +import {useExternalState} from "../hooks/useExternalState.ts"; +import {Header} from "./components/Header/Header.tsx"; +import {ChatHistory} from "./components/ChatHistory/ChatHistory.tsx"; +import {InputRow} from "./components/InputRow/InputRow.tsx"; + +import "./App.css"; + + +export function App() { + const state = useExternalState(llmState); + const {generatingResult} = state.chatSession; + + useLayoutEffect(() => { + // anchor scroll to bottom + + let isAnchored = false; + function isAtTheBottom() { + return document.documentElement.scrollHeight - document.documentElement.scrollTop === document.documentElement.clientHeight; + } + + function scrollToBottom() { + document.documentElement.scrollTop = document.documentElement.scrollHeight; + } + + function onScroll() { + isAnchored = isAtTheBottom(); + } + + const observer = new ResizeObserver(() => { + if (isAnchored && !isAtTheBottom()) + scrollToBottom(); + }); + + window.addEventListener("scroll", onScroll, {passive: false}); + observer.observe(document.body, { + box: "border-box" + }); + scrollToBottom(); + isAnchored = isAtTheBottom(); + + return () => { + observer.disconnect(); + window.removeEventListener("scroll", onScroll); + }; + }, []); + + const openSelectModelFileDialog = useCallback(async () => { + await electronLlmRpc.selectModelFileAndLoad(); + }, []); + + const stopActivePrompt = useCallback(() => { + void electronLlmRpc.stopActivePrompt(); + }, []); + + const resetChatHistory = useCallback(() => { + void electronLlmRpc.stopActivePrompt(); + void electronLlmRpc.resetChatHistory(); + }, []); + + const sendPrompt = useCallback((prompt: string) => { + if (generatingResult) + return; + + void electronLlmRpc.prompt(prompt); + }, [generatingResult]); + + const error = state.llama.error ?? state.model.error ?? state.context.error ?? state.contextSequence.error; + const showMessage = state.selectedModelFilePath == null || error != null || state.chatSession.simplifiedChat.length === 0; + + return
+
+ { + showMessage && +
+ { + error != null && +
+ {String(error)} +
+ } + { + (state.selectedModelFilePath == null || state.llama.error != null) && +
+ Click the button above to load a model +
+ } + { + ( + state.selectedModelFilePath != null && + error == null && + state.chatSession.simplifiedChat.length === 0 + ) && +
+ Type a message to start the conversation +
+ } +
+ } + { + !showMessage && + + } + +
; +} diff --git a/templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.css b/templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.css new file mode 100644 index 00000000..72194661 --- /dev/null +++ b/templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.css @@ -0,0 +1,61 @@ +.appChatHistory { + flex: 1; + display: flex; + flex-direction: column; + text-align: start; + overflow: auto; + padding: 24px 0px; + + > .message.user { + align-self: flex-end; + background-color: var(--user-message-background-color); + padding: 8px 12px; + border-radius: 12px; + margin-bottom: 12px; + margin-inline-start: 48px; + margin-inline-end: 12px; + color: var(--user-message-text-color); + + &:not(:first-child) { + margin-top: 36px; + } + } + + > .message.model { + align-self: flex-start; + margin-inline-end: 48px; + padding-inline-start: 24px; + + &.active { + &:after { + content: ""; + position: static; + display: inline-block; + background-color: currentColor; + width: 8px; + height: 8px; + translate: 0px -2px; + border-radius: 9999px; + margin-inline-start: 8px; + vertical-align: middle; + + animation: activeModelMessageIndicator 2s infinite ease-in-out; + } + } + } +} + +@keyframes activeModelMessageIndicator { + 0% { + transform: scale(1); + opacity: 0.64; + } + 50% { + transform: scale(1.4); + opacity: 0.32; + } + 100% { + transform: scale(1); + opacity: 0.64; + } +} diff --git a/templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.tsx b/templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.tsx new file mode 100644 index 00000000..168aafb1 --- /dev/null +++ b/templates/electron-typescript-react/src/App/components/ChatHistory/ChatHistory.tsx @@ -0,0 +1,39 @@ +import classNames from "classnames"; +import {LlmState} from "../../../../electron/state/llmState.ts"; + +import "./ChatHistory.css"; + + +export function ChatHistory({simplifiedChat, generatingResult}: ChatHistoryProps) { + return
+ { + simplifiedChat.map((item, index) => { + if (item.type === "model") { + const isActive = index === simplifiedChat.length - 1 && generatingResult; + return
+ {item.message} +
; + + } else if (item.type === "user") + return
+ {item.message} +
; + + return null; + }) + } + { + ( + simplifiedChat.length > 0 && + simplifiedChat[simplifiedChat.length - 1].type !== "model" && + generatingResult + ) && +
+ } +
; +} + +type ChatHistoryProps = { + simplifiedChat: LlmState["chatSession"]["simplifiedChat"], + generatingResult: boolean +}; diff --git a/templates/electron-typescript-react/src/App/components/Header/Header.css b/templates/electron-typescript-react/src/App/components/Header/Header.css new file mode 100644 index 00000000..ffc42954 --- /dev/null +++ b/templates/electron-typescript-react/src/App/components/Header/Header.css @@ -0,0 +1,89 @@ +.appHeader { + display: flex; + flex-direction: row; + z-index: 10; + position: sticky; + top: 16px; + pointer-events: none; + + > .panel { + pointer-events: all; + display: flex; + flex-direction: row; + align-self: start; + background-color: var(--panel-background-color); + border-radius: 12px; + backdrop-filter: blur(8px); + box-shadow: var(--panel-box-shadow); + overflow: clip; + isolation: isolate; + color: var(--panel-text-color); + z-index: 10; + + > button { + flex-shrink: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 8px 12px; + margin: 8px; + background-color: var(--panel-button-background-color); + color: var(--panel-text-color); + fill: var(--panel-text-color); + + + button { + margin-inline-start: 0px; + } + + &:hover, + &:focus, + &:focus-visible { + border-color: var(--panel-button-hover-border-color); + } + + > .icon { + width: 20px; + height: 20px; + } + } + } + + > .model { + position: relative; + + > .progress { + position: absolute; + inset-inline-start: 0; + top: 0; + bottom: 0; + background-color: var(--panel-progress-color); + width: calc(var(--progress) * 100%); + pointer-events: none; + z-index: -1; + + --progress: 0; + + &.hide { + opacity: 0; + + transition: opacity 0.3s var(--transition-easing); + } + } + + > .modelName, + > .noModel { + flex: 1; + text-align: start; + align-self: center; + flex-basis: 400px; + padding: 12px 24px; + + margin-inline-end: 48px; + } + } + + > .spacer { + flex-grow: 1; + } +} diff --git a/templates/electron-typescript-react/src/App/components/Header/Header.tsx b/templates/electron-typescript-react/src/App/components/Header/Header.tsx new file mode 100644 index 00000000..cc0ff213 --- /dev/null +++ b/templates/electron-typescript-react/src/App/components/Header/Header.tsx @@ -0,0 +1,48 @@ +import {CSSProperties} from "react"; +import classNames from "classnames"; +import {LoadFileIconSVG} from "../../../icons/LoadFileIconSVG.tsx"; +import {DeleteIconSVG} from "../../../icons/DeleteIconSVG.tsx"; + +import "./Header.css"; + + +export function Header({modelName, onLoadClick, loadPercentage, onResetChatClick}: HeaderProps) { + return
+
+
+ + { + modelName != null && +
{modelName}
+ } + { + modelName == null && +
No model loaded
+ } + + + +
+
+
; +} + +type HeaderProps = { + modelName?: string, + onLoadClick?(): void, + loadPercentage?: number, + onResetChatClick?(): void +}; diff --git a/templates/electron-typescript-react/src/App/components/InputRow/InputRow.css b/templates/electron-typescript-react/src/App/components/InputRow/InputRow.css new file mode 100644 index 00000000..51491f6d --- /dev/null +++ b/templates/electron-typescript-react/src/App/components/InputRow/InputRow.css @@ -0,0 +1,73 @@ +.appInputRow { + display: flex; + flex-direction: row; + position: sticky; + bottom: 16px; + background-color: var(--panel-background-color); + border-radius: 12px; + backdrop-filter: blur(8px); + box-shadow: var(--panel-box-shadow); + overflow: clip; + color: var(--panel-text-color); + flex-shrink: 0; + z-index: 10; + align-items: flex-end; + + > .input { + flex: 1; + border: none; + resize: none; + box-sizing: border-box; + max-height: 160px; + height: 55px; + outline: none; + padding: 12px 24px; + background-color: transparent; + font: inherit; + align-content: center; + align-self: stretch; + color: var(--panel-text-color); + + &::placeholder { + color: var(--panel-text-color); + opacity: 0.4; + } + } + + > .stopGenerationButton, + > .sendButton { + flex-shrink: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 8px 12px; + margin: 8px; + background-color: var(--panel-button-background-color); + color: var(--panel-text-color); + fill: var(--panel-text-color); + + + button { + margin-inline-start: 0px; + } + + &:hover, + &:focus, + &:focus-visible { + border-color: var(--panel-button-hover-border-color); + } + + > .icon { + width: 20px; + height: 20px; + } + } + + > .stopGenerationButton { + transition: border-color 0.3s var(--transition-easing), opacity 0.3s var(--transition-easing); + + &[disabled] { + opacity: 0; + } + } +} diff --git a/templates/electron-typescript-react/src/App/components/InputRow/InputRow.tsx b/templates/electron-typescript-react/src/App/components/InputRow/InputRow.tsx new file mode 100644 index 00000000..44dc1db5 --- /dev/null +++ b/templates/electron-typescript-react/src/App/components/InputRow/InputRow.tsx @@ -0,0 +1,79 @@ +import {useCallback, useRef, useState} from "react"; +import {AddMessageIconSVG} from "../../../icons/AddMessageIconSVG.tsx"; +import {AbortIconSVG} from "../../../icons/AbortIconSVG.tsx"; + +import "./InputRow.css"; + + +export function InputRow({stopGeneration, sendPrompt, generatingResult, contextSequenceLoaded}: InputRowProps) { + const [inputEmpty, setInputEmpty] = useState(true); + const inputRef = useRef(null); + + const resizeInput = useCallback(() => { + if (inputRef.current == null) + return; + + inputRef.current.style.minHeight = ""; + inputRef.current.style.minHeight = inputRef.current.scrollHeight + "px"; + }, []); + + const submitPrompt = useCallback(() => { + if (generatingResult || inputRef.current == null) + return; + + const message = inputRef.current.value; + if (message.length === 0) + return; + + inputRef.current.value = ""; + resizeInput(); + sendPrompt(message); + }, [generatingResult, resizeInput, sendPrompt]); + + const onInput = useCallback(() => { + setInputEmpty(inputRef.current?.value.length === 0); + resizeInput(); + }, [resizeInput]); + + const onInputKeyDown = useCallback((event: React.KeyboardEvent) => { + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + submitPrompt(); + resizeInput(); + } + }, [submitPrompt]); + + return
+