{ "name": "twinny", "displayName": "twinny - AI Code Completion and Chat", "description": "AI code completion, chat, inline edit and code review on models you run. Private, open source, one gateway for the whole team.", "version": "4.3.15", "icon": "assets/icon.png", "keywords": [ "code-inference", "code-suggestion", "copilot", "localhost", "no-leaks", "private", "twinny", "ai", "ollama", "llama", "development", "extension", "llama-code", "snippets", "chat", "code-snippets", "autocomplete", "intellisense", "llama-ai", "vscode-extension" ], "repository": { "url": "https://github.com/twinnydotdev/twinny" }, "license": "MIT", "publisher": "rjmacarthy", "engines": { "vscode": "^1.93.0" }, "bugs": { "url": "https://github.com/twinnydotdev/twinny/issues" }, "categories": [ "Programming Languages", "Snippets", "Debuggers", "Formatters", "Machine Learning", "Education", "Testing", "Data Science", "Extension Packs", "Linters" ], "activationEvents": [ "onStartupFinished", "onUri" ], "author": { "name": "rjmacarthy" }, "main": "./out/index.js", "browser": "./out/index.js", "bin": { "twinny-node": "./out/node/cli.js" }, "contributes": { "menus": { "editor/context": [ { "when": "editorTextFocus", "command": "twinny.explain" }, { "when": "editorTextFocus", "command": "twinny.refactor" }, { "when": "editorTextFocus && !editorReadonly", "command": "twinny.edit" }, { "when": "editorTextFocus", "command": "twinny.addTypes" }, { "when": "editorTextFocus", "command": "twinny.addTests" }, { "when": "editorTextFocus", "command": "twinny.generateDocs" }, { "when": "editorTextFocus", "command": "twinny.addFileToContext" }, { "when": "editorHasSelection", "command": "twinny.addSelectionToContext" } ], "view/title": [ { "command": "twinny.openChat", "group": "navigation@0", "when": "view == twinny.sidebar && twinnyManageTemplates || view == twinny.sidebar && twinnyManageProviders || view == twinny.sidebar && twinnyConversationHistory || view == twinny.sidebar && twinnyReviewTab || view == twinny.sidebar && twinnyEmbeddingsTab" }, { "command": "twinny.review", "group": "navigation@1", "when": "view == twinny.sidebar" }, { "command": "twinny.manageProviders", "group": "navigation@3", "when": "view == twinny.sidebar" }, { "command": "twinny.manageTemplates", "group": "navigation@4", "when": "view == twinny.sidebar" }, { "command": "twinny.embeddings", "when": "view == twinny.sidebar", "group": "navigation@5", "icon": "$(database)" }, { "command": "twinny.conversationHistory", "when": "view == twinny.sidebar", "group": "navigation@6" }, { "command": "twinny.openPanelChat", "when": "view == twinny.sidebar", "group": "navigation@7" }, { "command": "twinny.newConversation", "when": "view == twinny.sidebar", "group": "navigation@8" }, { "command": "twinny.settings", "when": "view == twinny.sidebar", "group": "navigation@9" }, { "command": "twinny.exportConversation", "when": "view == twinny.sidebar", "group": "conversation@1" }, { "command": "twinny.showShortcuts", "when": "view == twinny.sidebar", "group": "conversation@2" } ], "scm/title": [ { "command": "twinny.generateCommitMessage", "group": "navigation", "when": "scmProvider == git" } ], "commandPalette": [ { "command": "twinny.statusBarMenu", "when": "false" }, { "command": "twinny.acceptEdit", "when": "twinnyInlineEditPending" }, { "command": "twinny.rejectEdit", "when": "twinnyInlineEditPending" } ], "terminal/context": [ { "command": "twinny.fixTerminalError", "group": "twinny@1" }, { "command": "twinny.terminalCommand", "group": "twinny@2" } ], "explorer/context": [ { "command": "twinny.addFileToContext", "group": "twinny@1", "when": "!explorerResourceIsFolder" } ] }, "commands": [ { "command": "twinny.explain", "title": "Twinny - Explain" }, { "command": "twinny.refactor", "title": "Twinny - Refactor" }, { "command": "twinny.edit", "title": "Twinny - Edit with instruction..." }, { "command": "twinny.acceptEdit", "title": "Twinny - Accept edit" }, { "command": "twinny.rejectEdit", "title": "Twinny - Reject edit" }, { "command": "twinny.addTypes", "title": "Twinny - Add types" }, { "command": "twinny.addTests", "title": "Twinny - Write tests" }, { "command": "twinny.generateDocs", "title": "Twinny - Generate docs" }, { "command": "twinny.enable", "shortTitle": "Enable twinny", "title": "Enable twinny" }, { "command": "twinny.stopGeneration", "title": "Stop generation" }, { "command": "twinny.disable", "title": "Disable twinny", "shortTitle": "Disable twinny" }, { "command": "twinny.sidebar.focus", "shortTitle": "Enable twinny sidebar", "title": "Enable twinny sidebar" }, { "command": "twinny.settings", "shortTitle": "twinny settings", "title": "Open twinny settings", "icon": "$(gear)" }, { "command": "twinny.setUpTeam", "shortTitle": "Set up for your team", "title": "Twinny - Set up for your team (gateway, keys, usage)", "icon": "$(organization)" }, { "command": "twinny.openTeamPlugins", "shortTitle": "Team plugins", "title": "Twinny - Open your team's plugins (pull requests, reviews)", "icon": "$(link-external)" }, { "command": "twinny.review", "shortTitle": "twinny code reviewer", "title": "Code reviewer", "icon": "$(git-pull-request)" }, { "command": "twinny.conversationHistory", "shortTitle": "twinny conversation history", "title": "Open twinny conversation history", "icon": "$(history)" }, { "command": "twinny.openPanelChat", "shortTitle": "Open twinny panel chat", "title": "Open twinny panel chat", "icon": "$(screen-full)" }, { "command": "twinny.exportConversation", "title": "Twinny - Open conversation as Markdown", "icon": "$(markdown)" }, { "command": "twinny.showShortcuts", "title": "Twinny - Chat keyboard shortcuts", "icon": "$(keyboard)" }, { "command": "twinny.forgetAlwaysRunCommands", "title": "Twinny - Forget commands set to always run" }, { "command": "twinny.newConversation", "shortTitle": "New chat", "title": "Start a new chat", "icon": "$(plus)" }, { "command": "twinny.templates", "shortTitle": "Edit twinny templates", "title": "Edit twinny templates", "icon": "$(pencil)" }, { "command": "twinny.manageTemplates", "shortTitle": "Manage twinny templates", "title": "Manage twinny templates", "icon": "$(book)" }, { "command": "twinny.manageProviders", "shortTitle": "Manage twinny providers", "title": "Manage twinny providers", "icon": "$(robot)" }, { "command": "twinny.showLogs", "title": "Twinny - Show logs" }, { "command": "twinny.openChat", "shortTitle": "Back to chat view", "title": "Back to chat view", "icon": "$(arrow-left)" }, { "command": "twinny.embeddings", "shortTitle": "twinny embeddings", "title": "Embedding options", "icon": "$(database)" }, { "command": "twinny.addFileToContext", "title": "Twinny - Add file to context" }, { "command": "twinny.addSelectionToContext", "title": "Twinny: Add Selection to Context" }, { "command": "twinny.generateCommitMessage", "title": "Twinny - Generate commit message", "icon": "$(sparkle)" }, { "command": "twinny.statusBarMenu", "title": "Twinny - Status bar options" }, { "command": "twinny.shareOllama", "title": "Twinny - Share this computer's Ollama with my other devices (P2P)" }, { "command": "twinny.terminalCommand", "title": "Twinny - Write a terminal command from a description" }, { "command": "twinny.fixTerminalError", "title": "Twinny - Fix the last terminal error" } ], "keybindings": [ { "key": "Alt+\\", "command": "editor.action.inlineSuggest.trigger", "when": "editorTextFocus && !editorReadonly" }, { "key": "ctrl+i", "mac": "cmd+i", "command": "twinny.edit", "when": "editorTextFocus && !editorReadonly" }, { "key": "CTRL+SHIFT+/", "command": "twinny.stopGeneration", "when": "twinnyGeneratingText" }, { "key": "ctrl+shift+enter", "mac": "cmd+shift+enter", "command": "twinny.acceptEdit", "when": "twinnyInlineEditPending && editorTextFocus" }, { "key": "ctrl+shift+backspace", "mac": "cmd+shift+backspace", "command": "twinny.rejectEdit", "when": "twinnyInlineEditPending && editorTextFocus" } ], "viewsContainers": { "activitybar": [ { "id": "twinny-sidebar-view", "title": "twinny", "icon": "assets/twinny.svg" } ] }, "views": { "twinny-sidebar-view": [ { "type": "webview", "id": "twinny.sidebar", "name": "twinny", "icon": "assets/twinny.svg", "contextualTitle": "twinny" } ] }, "configuration": { "title": "twinny", "properties": { "twinny.enabled": { "order": 0, "type": "boolean", "default": true, "markdownDescription": "Toggles the Twinny extension on or off. When `true`, Twinny is active and ready to provide completions." }, "twinny.enabledLanguages": { "order": 1, "type": "object", "additionalProperties": { "type": "boolean" }, "default": { "*": true }, "markdownDescription": "Specifies which languages to enable completions with Twinny for. Use `*` as the default for all languages. Example:\n```json\n{\n \"*\": true,\n \"python\": true,\n \"javascript\": false\n}\n```" }, "twinny.locale": { "order": 2, "type": "string", "enum": [ "en", "zh-CN", "zh-HK", "de", "es", "es-CL", "ja", "fr", "it", "pt", "ru", "ko", "nl" ], "enumDescriptions": [ "English", "Chinese (Simplified)", "Chinese (Hong Kong)", "German", "Spanish", "Spanish (Chile)", "Japanese", "French", "Italian", "Portuguese", "Russian", "Korean", "Dutch" ], "default": "en", "markdownDescription": "Sets the locale for Twinny. The default is `en` (English)." }, "twinny.autoSuggestEnabled": { "order": 3, "type": "boolean", "default": true, "markdownDescription": "When `true`, Twinny will automatically suggest completions. You can still manually trigger completions using the default shortcut (`Alt+\\`)." }, "twinny.contextLength": { "order": 4, "type": "number", "default": 100, "markdownDescription": "Specifies how many lines of context (before and after the current line) to include in Fill-in-Middle (FIM) prompts. A higher number provides more context but may slow down completions.", "required": true }, "twinny.debounceWait": { "order": 5, "type": "number", "default": 300, "markdownDescription": "Sets the delay (in milliseconds) before triggering the next completion. This helps reduce API calls and improve performance.", "required": true }, "twinny.temperature": { "order": 6, "type": "number", "default": 0.2, "markdownDescription": "Controls the randomness of code completions. Lower values (e.g., 0.2) produce more focused and deterministic completions, while higher values (e.g., 0.8) lead to more diverse ones. Chat, inline edit and code review send no temperature; the server's default applies.", "required": true }, "twinny.multilineCompletionsEnabled": { "order": 7, "type": "boolean", "default": true, "markdownDescription": "When `true`, Twinny will attempt to generate multi-line completions. This is an experimental feature and may not work perfectly in all scenarios." }, "twinny.maxLines": { "dependencies": { "twinny.multilineCompletionsEnabled": true }, "order": 8, "type": "number", "default": 40, "markdownDescription": "Sets the maximum number of lines for multi-line completions. Only applies when `twinny.multilineCompletionsEnabled` is `true`." }, "twinny.fileContextEnabled": { "order": 9, "type": "boolean", "default": false, "markdownDescription": "When `true`, Twinny will scan neighboring documents to provide more context for completions. This is an experimental feature and may impact performance." }, "twinny.recentEditsEnabled": { "order": 9, "type": "boolean", "default": true, "markdownDescription": "Shows the model the last few changes you made, in any open file, as short diffs. A half-done rename or a pattern being applied across a file then carries into completions. Up to 6 changes and 2,500 characters." }, "twinny.lspContextEnabled": { "order": 9, "type": "boolean", "default": true, "markdownDescription": "Includes matching IntelliSense symbols and available type signatures in FIM context. Uses installed completion providers, with up to 20 suggestions, 2,000 characters and a 150 ms wait limit. Works independently of file context." }, "twinny.completionCacheEnabled": { "order": 10, "type": "boolean", "default": false, "markdownDescription": "Enables caching of Fill-in-Middle (FIM) completions for identical prompts. This can significantly improve performance but may use more memory." }, "twinny.numPredictFim": { "order": 12, "type": "number", "default": 512, "markdownDescription": "Defines the maximum number of tokens for Fill-in-Middle (FIM) completions. Use `-1` for no limit. Twinny will attempt to stop at logical line breaks regardless of this setting.", "required": true }, "twinny.enableSubsequentCompletions": { "order": 13, "type": "boolean", "default": true, "markdownDescription": "When `true`, Twinny will continue to make completion requests to the API after the previous completion was accepted. This can provide a more fluid completion experience." }, "twinny.embeddingIgnoredGlobs": { "order": 14, "type": "array", "default": [], "markdownDescription": "Extra file patterns to skip when building embeddings, such as `**/*.md` or `**/fixtures/**`. Only source, config and documentation files are indexed to begin with; binaries such as fonts and images are always skipped." }, "twinny.embeddingUpdateOnSave": { "order": 14, "type": "boolean", "default": true, "description": "Keep the workspace index current: re-embed a file when it is saved and forget it when it is deleted. Only applies once the workspace has been indexed." }, "twinny.ollamaHostname": { "order": 15, "type": "string", "default": "0.0.0.0", "markdownDescription": "Specifies the hostname for the Ollama API. Use `0.0.0.0` for localhost or provide a specific IP address or domain name.", "required": true }, "twinny.ollamaApiPort": { "order": 16, "type": [ "number", "null" ], "default": 11434, "markdownDescription": "Sets the port number for the Ollama API. The default is `11434`, but you can change it if your Ollama instance uses a different port.", "required": false }, "twinny.p2pPort": { "order": 16, "type": "number", "default": 49737, "minimum": 1, "maximum": 65535, "markdownDescription": "UDP port this computer listens on when sharing its Ollama with paired devices (Providers → Devices → Share). Devices on your network connect to this port, so a firewall on this computer must allow it, e.g. `sudo ufw allow 49737/udp`. Takes effect the next time sharing starts." }, "twinny.teamShareSlots": { "order": 16, "type": "number", "default": 2, "minimum": 1, "maximum": 8, "markdownDescription": "How many teammates' requests this computer runs at once while sharing it with the team (Providers → Share this computer). Takes effect the next time sharing starts." }, "twinny.keepAlive": { "order": 17, "type": "string", "default": "5m", "markdownDescription": "Sets the duration to keep models in memory for Ollama API. Use formats like `5m` for 5 minutes or `1h` for 1 hour. Set to `-1` to keep models in memory indefinitely." }, "twinny.warmUpModel": { "order": 17, "type": "boolean", "default": true, "markdownDescription": "Load the completion model when VS Code starts or regains focus, so the first completion does not wait for a cold model. Only for local model servers (Ollama, LM Studio, llama.cpp); hosted APIs are never called." }, "twinny.ollamaUseTls": { "order": 18, "type": "boolean", "default": false, "markdownDescription": "When `true`, Twinny will use TLS encryption for connections to the Ollama API. Ensure your Ollama instance is configured for TLS before enabling this option." }, "twinny.secretShield": { "order": 18, "type": "string", "enum": [ "offMachine", "always", "off" ], "enumDescriptions": [ "Redact credentials in prompts sent to anything that is not on this machine: hosted APIs, a Twinny gateway, a paired device, a server elsewhere on the network.", "Redact credentials in every prompt, local servers included.", "Send prompts as they are." ], "default": "offMachine", "markdownDescription": "**Secret shield.** API keys, tokens, private keys and passwords in a prompt (your question, attached files, the code around the cursor) are replaced with placeholders like `REDACTED_GITHUB_TOKEN_1` before the request is sent, and put back wherever the reply repeats a placeholder. The model never sees the value; the chat shows how many were withheld. Detection covers well-known token formats, private key blocks, passwords in URLs, and secret-named values in code and `.env` files." }, "twinny.enableLogging": { "order": 19, "type": "boolean", "default": true, "markdownDescription": "Writes what Twinny is doing to the **Twinny** output channel: one line per completion or chat request with model, timing, size and why it stopped. Set the channel's log level to *Debug* (the dropdown in the Output panel) to also see the prompts and replies. Warnings and errors are written even when this is off." }, "twinny.chatSuggestions": { "order": 19, "type": "boolean", "default": true, "markdownDescription": "Shows grey text ahead of the cursor in the chat composer; `Tab` accepts it and `Ctrl+→` accepts a word of it. It finishes words from what you have typed before, as a phone keyboard does, and once a conversation has an exchange, a pause after a word asks the chat model for the rest of the message given the last few turns. No requests are made while a reply is coming." }, "twinny.chatTools": { "order": 20, "type": "boolean", "default": false, "markdownDescription": "**Experimental.** Lets the chat model work in the workspace: find, read and search files (by regular expression, and by meaning through the embeddings index), read git history, ask the language servers for errors, references and definitions, edit, create, rename, move and delete files, and run commands. Edits are applied straight away unless `#twinny.chatToolsEdits#` asks for review; each applied edit comes back with any errors the editor then reports in the file, and the reply ends with the files it changed, each of which can be compared with what it was or undone. Commands ask first unless `#twinny.chatToolsCommands#` says otherwise. The project's `AGENTS.md` (or `CLAUDE.md`) is followed, and a folder's own `AGENTS.md` once the model works there. Files ignored by a `.gitignore` are off limits, and changes to `.vscode/`, a `.gitignore` or an `AGENTS.md` are always shown for review. Each step shows in the reply at the point it ran. Needs a capable coder model such as `qwen3-coder:30b` with a context of 8k tokens or more; small models tend to call tools badly. Set in your user settings; a workspace cannot turn it on.", "scope": "machine" }, "twinny.chatToolsEdits": { "order": 20, "type": "string", "enum": [ "apply", "review" ], "enumDescriptions": [ "Edits go straight into the file and are saved; the model carries on until the task is done. Ctrl+Z in the file undoes an edit. Deleting a file git has no copy of still asks first.", "Each edit opens as a diff to accept or reject, and the model stops until you have decided. Renames, moves and deletes ask in the chat." ], "default": "apply", "markdownDescription": "What happens when the chat model changes a file (with `#twinny.chatTools#` on).", "scope": "machine" }, "twinny.chatToolsCommands": { "order": 20, "type": "string", "enum": [ "ask", "allow", "off" ], "enumDescriptions": [ "Each command the model wants to run is shown in the chat with Run, Always run and Skip first.", "Commands run straight away. A command cannot be undone like an edit can.", "The model cannot run commands." ], "default": "ask", "markdownDescription": "Whether the chat model may run shell commands (tests, builds), with `#twinny.chatTools#` on. It sees the exit code and the end of the output. This sets where the **auto-run** switch in the chat's composer starts; once you switch it, the switch decides (`off` still turns commands off). Reading git (status, diff, log) never asks: it cannot change anything.", "scope": "machine" }, "twinny.chatToolsMcpServers": { "order": 20, "type": "object", "default": {}, "additionalProperties": { "type": "object", "required": [ "command" ], "properties": { "command": { "type": "string", "description": "The program that runs the server, e.g. npx or uvx." }, "args": { "type": "array", "items": { "type": "string" }, "description": "Its arguments." }, "env": { "type": "object", "additionalProperties": { "type": "string" }, "description": "Environment variables for it, on top of VS Code's." }, "cwd": { "type": "string", "description": "The folder it runs in; the workspace root by default." } } }, "markdownDescription": "Model Context Protocol servers whose tools agent mode can use (with `#twinny.chatTools#` on), by name: `{ \"github\": { \"command\": \"npx\", \"args\": [\"-y\", \"@modelcontextprotocol/server-github\"], \"env\": { \"GITHUB_TOKEN\": \"…\" } } }`. Servers run on this machine over standard input and output, start with the first agent reply and stop with the chat. Each call is shown with Run and Skip first, unless you chose Always run for that tool. Every tool goes into every agent request, so a server with many tools makes small models pick worse. Set in your user settings; a workspace cannot add one.", "scope": "machine" }, "twinny.chatToolsMaxSteps": { "order": 20, "type": "number", "default": 30, "minimum": 4, "maximum": 40, "markdownDescription": "How many tool steps one agent reply may take before the model is asked to answer with what it has (with `#twinny.chatTools#` on). More lets a capable model finish longer tasks in one reply; each step is another request to the model.", "scope": "machine" }, "twinny.chatToolsCommandsRunIn": { "order": 20, "type": "string", "enum": [ "background", "terminal" ], "enumDescriptions": [ "Each command runs in a process of its own through your shell, from the workspace root. Its output shows in the chat as it prints. Nothing can answer a prompt, and it is stopped after two minutes.", "Commands run in the **twinny tools** terminal, which opens beside the editor, so you can watch and type into them. Needs VS Code's shell integration; without it they run in the background." ], "default": "background", "markdownDescription": "Where the chat model's commands run (with `#twinny.chatToolsCommands#` not `off`).", "scope": "machine" }, "twinny.githubToken": { "order": 21, "type": "string", "default": "", "markdownDescription": "Your personal GitHub access token. This is used for fetching data from GitHub repositories. Keep this token secure and do not share it." }, "twinny.providerStorageLocation": { "order": 22, "type": "string", "enum": [ "globalState", "file" ], "default": "globalState", "markdownDescription": "Specifies where to store Twinny provider configurations. 'globalState' uses VS Code's global state (persists per domain, may be lost if domain changes frequently). 'file' stores configurations in a file within the extension's global storage directory (more resilient to domain changes)." }, "twinny.reviewMaxDiffChars": { "order": 30, "type": "number", "default": 16000, "minimum": 2000, "description": "Characters of diff sent to the model per code-review request. Larger reviews are split into parts. Lower this for models with small context windows; raise it for large-context models to get fewer parts." } } } }, "scripts": { "build": "node scripts/build.mjs", "build-tests": "tsc -p . --outDir out", "clean": "node -e \"require('fs').rmSync('out',{recursive:true,force:true})\"", "lint": "eslint src", "lint:fix": "eslint src --fix", "node": "node ./out/node/cli.js", "package": "node scripts/build.mjs", "pretest": "npm run clean && npm run build-tests && npm run build && npm run lint", "test": "node ./out/test/runTest.js", "test:sqlite": "node --test out/test/standalone/*.standalone.js", "vscode:package": "npm exec vsce package", "vscode:prepublish": "npm run package", "vscode:publish": "npm exec vsce publish", "watch-tests": "tsc -p . -w --outDir out", "watch": "node scripts/build.mjs --watch" }, "devDependencies": { "@hyrious/esbuild-plugin-commonjs": "^0.2.4", "@types/cheerio": "^0.22.35", "@types/minimatch": "^5.1.2", "@types/mocha": "^10.0.6", "@types/node": "^16.18.68", "@types/react-dom": "^18.2.18", "@types/react-syntax-highlighter": "^15.5.11", "@types/uuid": "^9.0.8", "@types/vscode": "^1.93.0", "@typescript-eslint/eslint-plugin": "^8.21.0", "@typescript-eslint/parser": "^8.21.0", "@vscode/test-cli": "^0.0.6", "@vscode/test-electron": "^2.3.10", "@vscode/vsce": "^3.1.1", "copy-webpack-plugin": "^12.0.2", "css-loader": "^6.8.1", "esbuild": "^0.21.5", "esbuild-plugin-copy": "^2.1.1", "eslint-plugin-import": "^2.31.0", "eslint-plugin-simple-import-sort": "^12.1.1", "jest": "^29.7.0", "mocha": "^10.3.0", "rimraf": "^5.0.5", "style-loader": "^3.3.3", "tree-sitter-wasms": "^0.1.7", "ts-loader": "^9.5.1", "typescript": "^4.7.4", "web-tree-sitter": "^0.22.1" }, "dependencies": { "@lancedb/lancedb": "^0.19.1", "@tiptap/extension-image": "^2.11.7", "@tiptap/extension-mention": "^2.5.9", "@tiptap/extension-placeholder": "^2.5.9", "@tiptap/pm": "^2.5.9", "@tiptap/react": "^2.5.9", "@tiptap/starter-kit": "^2.5.9", "@tiptap/suggestion": "^2.5.9", "@types/react": "^18.2.46", "@vscode/codicons": "^0.0.35", "@vscode/webview-ui-toolkit": "^1.4.0", "@wasm-tool/wasm-pack-plugin": "^1.7.0", "cheerio": "^1.0.0", "classnames": "^2.5.1", "dompurify": "^3.2.3", "fastest-levenshtein": "^1.0.16", "fluency.js": "^1.0.31", "fuse.js": "^7.0.0", "handlebars": "^4.7.8", "handlebars-loader": "^1.7.3", "hyperdht": "^6.34.0", "i18next": "^23.16.5", "i18next-http-backend": "^2.6.2", "ignore": "^6.0.2", "lucide-react": "^0.473.0", "node-polyfill-webpack-plugin": "^3.0.0", "onnxruntime-web": "^1.18.0", "p-queue": "^8.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-i18next": "^15.1.1", "react-markdown": "^9.0.1", "react-syntax-highlighter": "^15.5.0", "react-virtuoso": "^4.12.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", "tippy.js": "^6.3.7", "tiptap-markdown": "^0.8.10", "toxe": "^1.1.0", "uuid": "^9.0.1" }, "os": [ "darwin", "linux", "win32" ], "cpu": [ "x64", "arm64" ] }