Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,5 @@ storybook-static/
*.tgz
src/test-workspaces/
terminal-bench-results/
nodemon.json
test_hot_reload.sh
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ dev: node_modules/.installed build-main ## Start development server (Vite + tsgo
"bun x concurrently \"$(TSGO) -w -p tsconfig.main.json\" \"bun x tsc-alias -w -p tsconfig.main.json\"" \
"vite"

dev-server: node_modules/.installed build-main ## Start server mode with hot reload (backend :3000 + frontend :5173). Use VITE_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0 for remote access
@echo "Starting dev-server..."
@echo " Backend (IPC/WebSocket): http://$(or $(BACKEND_HOST),localhost):$(or $(BACKEND_PORT),3000)"
@echo " Frontend (with HMR): http://$(or $(VITE_HOST),localhost):$(or $(VITE_PORT),5173)"
@echo ""
@echo "For remote access: make dev-server VITE_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0"
@bun x concurrently -k \
"bun x concurrently \"$(TSGO) -w -p tsconfig.main.json\" \"bun x tsc-alias -w -p tsconfig.main.json\"" \
"bun x nodemon --watch dist/main.js --watch dist/main-server.js --delay 500ms --exec 'node dist/main.js server --host $(or $(BACKEND_HOST),localhost) --port $(or $(BACKEND_PORT),3000)'" \
"CMUX_VITE_HOST=$(or $(VITE_HOST),127.0.0.1) CMUX_VITE_PORT=$(or $(VITE_PORT),5173) VITE_BACKEND_URL=http://$(or $(BACKEND_HOST),localhost):$(or $(BACKEND_PORT),3000) vite"



start: node_modules/.installed build-main build-preload build-static ## Build and start Electron app
@bun x electron --remote-debugging-port=9222 .

Expand Down
26 changes: 23 additions & 3 deletions bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@tailwindcss/vite": "^4.1.15",
"@testing-library/react": "^16.3.0",
"@types/bun": "^1.2.23",
"@types/commander": "^2.12.5",
"@types/cors": "^2.8.19",
"@types/diff": "^8.0.0",
"@types/escape-html": "^1.0.4",
Expand Down Expand Up @@ -84,6 +85,7 @@
"eslint-plugin-tailwindcss": "4.0.0-beta.0",
"jest": "^30.1.3",
"mermaid": "^11.12.0",
"nodemon": "^3.1.10",
"playwright": "^1.56.0",
"postcss": "^8.5.6",
"posthog-js": "^1.276.0",
Expand Down Expand Up @@ -708,6 +710,8 @@

"@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="],

"@types/commander": ["@types/commander@2.12.5", "", { "dependencies": { "commander": "*" } }, "sha512-YXGZ/rz+s57VbzcvEV9fUoXeJlBt5HaKu5iUheiIWNsJs23bz6AnRuRiZBRVBLYyPnixNvVnuzM5pSaxr8Yp/g=="],

"@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],

"@types/cors": ["@types/cors@2.8.19", "", { "dependencies": { "@types/node": "*" } }, "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg=="],
Expand Down Expand Up @@ -1186,7 +1190,7 @@

"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],

"commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],
"commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],

"commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="],

Expand Down Expand Up @@ -1724,6 +1728,8 @@

"ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],

"ignore-by-default": ["ignore-by-default@1.0.1", "", {}, "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="],

"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],

"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
Expand Down Expand Up @@ -2210,6 +2216,8 @@

"node-releases": ["node-releases@2.0.26", "", {}, "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA=="],

"nodemon": ["nodemon@3.1.10", "", { "dependencies": { "chokidar": "^3.5.2", "debug": "^4", "ignore-by-default": "^1.0.1", "minimatch": "^3.1.2", "pstree.remy": "^1.1.8", "semver": "^7.5.3", "simple-update-notifier": "^2.0.0", "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.5" }, "bin": { "nodemon": "bin/nodemon.js" } }, "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw=="],

"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],

"normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="],
Expand Down Expand Up @@ -2358,6 +2366,8 @@

"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],

"pstree.remy": ["pstree.remy@1.1.8", "", {}, "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="],

"pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],

"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
Expand Down Expand Up @@ -2674,6 +2684,8 @@

"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],

"touch": ["touch@3.1.1", "", { "bin": { "nodetouch": "bin/nodetouch.js" } }, "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA=="],

"tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],

"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
Expand Down Expand Up @@ -2724,6 +2736,8 @@

"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],

"undefsafe": ["undefsafe@2.0.5", "", {}, "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="],

"undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],

"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
Expand Down Expand Up @@ -3042,8 +3056,6 @@

"find-process/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],

"find-process/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],

"foreground-child/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],

"form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
Expand Down Expand Up @@ -3184,6 +3196,10 @@

"mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],

"nodemon/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],

"nodemon/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],

"nyc/convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="],

"nyc/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
Expand Down Expand Up @@ -3252,6 +3268,8 @@

"ts-jest/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],

"tsc-alias/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],

"unzip-crx-3/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="],

"vite/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
Expand Down Expand Up @@ -3524,6 +3542,8 @@

"mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],

"nodemon/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],

"nyc/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],

"nyc/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="],
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,14 @@
"devDependencies": {
"@eslint/js": "^9.36.0",
"@playwright/test": "^1.56.0",
"@storybook/addon-docs": "^10.0.0",
"@storybook/addon-links": "^10.0.0",
"@storybook/react-vite": "^10.0.0",
"@storybook/test-runner": "^0.24.0",
"@tailwindcss/vite": "^4.1.15",
"@testing-library/react": "^16.3.0",
"@types/bun": "^1.2.23",
"@types/commander": "^2.12.5",
"@types/cors": "^2.8.19",
"@types/diff": "^8.0.0",
"@types/escape-html": "^1.0.4",
Expand Down Expand Up @@ -120,9 +122,11 @@
"eslint": "^9.36.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-storybook": "10.0.0",
"eslint-plugin-tailwindcss": "4.0.0-beta.0",
"jest": "^30.1.3",
"mermaid": "^11.12.0",
"nodemon": "^3.1.10",
"playwright": "^1.56.0",
"postcss": "^8.5.6",
"posthog-js": "^1.276.0",
Expand All @@ -146,9 +150,7 @@
"typescript-eslint": "^8.45.0",
"vite": "^7.1.11",
"vite-plugin-svgr": "^4.5.0",
"vite-plugin-top-level-await": "^1.6.0",
"eslint-plugin-storybook": "10.0.0",
"@storybook/addon-docs": "^10.0.0"
"vite-plugin-top-level-await": "^1.6.0"
},
"files": [
"dist/**/*.js",
Expand Down
4 changes: 3 additions & 1 deletion src/browser/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import { IPC_CHANNELS, getChatChannel } from "@/constants/ipc-constants";
import type { IPCApi } from "@/types/ipc";

const API_BASE = window.location.origin;
// Backend URL - defaults to same origin, but can be overridden via VITE_BACKEND_URL
// This allows frontend (Vite :8080) to connect to backend (:3000) in dev mode
const API_BASE = import.meta.env.VITE_BACKEND_URL ?? window.location.origin;
const WS_BASE = API_BASE.replace("http://", "ws://").replace("https://", "wss://");

interface InvokeResponse<T> {
Expand Down
28 changes: 6 additions & 22 deletions src/components/AIView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,11 @@ const AIViewInner: React.FC<AIViewProps> = ({
undefined
);

// Auto-retry state (persisted per workspace, with cross-component sync)
// Semantics:
// true (default): System errors should auto-retry
// false: User stopped this (Ctrl+C), don't auto-retry until user re-engages
// State transitions are EXPLICIT only:
// - User presses Ctrl+C → false
// - User sends a message → true (clear intent: "I'm using this workspace")
// - User clicks manual retry button → true
// No automatic resets on stream events - prevents initialization bugs
const [autoRetry, setAutoRetry] = usePersistedState<boolean>(
getAutoRetryKey(workspaceId),
true, // Default to true
{ listener: true } // Enable cross-component synchronization
);
// Auto-retry state - minimal setter for keybinds and message sent handler
// RetryBarrier manages its own state, but we need this for Ctrl+C keybind
const [, setAutoRetry] = usePersistedState<boolean>(getAutoRetryKey(workspaceId), true, {
listener: true,
});

// Use auto-scroll hook for scroll management
const {
Expand Down Expand Up @@ -408,14 +399,7 @@ const AIViewInner: React.FC<AIViewProps> = ({
);
})}
{/* Show RetryBarrier after the last message if needed */}
{showRetryBarrier && (
<RetryBarrier
workspaceId={workspaceId}
autoRetry={autoRetry}
onStopAutoRetry={() => setAutoRetry(false)}
onResetAutoRetry={() => setAutoRetry(true)}
/>
)}
{showRetryBarrier && <RetryBarrier workspaceId={workspaceId} />}
</>
)}
<PinnedTodoList workspaceId={workspaceId} />
Expand Down
29 changes: 19 additions & 10 deletions src/components/ChatInputToasts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Toast } from "./ChatInputToast";
import { SolutionLabel } from "./ChatInputToast";
import type { ParsedCommand } from "@/utils/slashCommands/types";
import type { SendMessageError as SendMessageErrorType } from "@/types/errors";
import { formatSendMessageError } from "@/utils/errors/formatSendError";

/**
* Creates a toast message for command-related errors and help messages
Expand Down Expand Up @@ -146,55 +147,63 @@ export const createCommandToast = (parsed: ParsedCommand): Toast | null => {
*/
export const createErrorToast = (error: SendMessageErrorType): Toast => {
switch (error.type) {
case "api_key_not_found":
case "api_key_not_found": {
const formatted = formatSendMessageError(error);
return {
id: Date.now().toString(),
type: "error",
title: "API Key Not Found",
message: `The ${error.provider} provider requires an API key to function.`,
solution: (
solution: formatted.providerCommand ? (
<>
<SolutionLabel>Quick Fix:</SolutionLabel>
/providers set {error.provider} apiKey YOUR_API_KEY
{formatted.providerCommand}
</>
),
) : undefined,
};
}

case "provider_not_supported":
case "provider_not_supported": {
const formatted = formatSendMessageError(error);
return {
id: Date.now().toString(),
type: "error",
title: "Provider Not Supported",
message: `The ${error.provider} provider is not supported yet.`,
message: formatted.message,
solution: (
<>
<SolutionLabel>Try This:</SolutionLabel>
Use an available provider from /providers list
</>
),
};
}

case "invalid_model_string":
case "invalid_model_string": {
const formatted = formatSendMessageError(error);
return {
id: Date.now().toString(),
type: "error",
title: "Invalid Model Format",
message: error.message,
message: formatted.message,
solution: (
<>
<SolutionLabel>Expected Format:</SolutionLabel>
provider:model-name (e.g., anthropic:claude-opus-4-1)
</>
),
};
}

case "unknown":
default:
default: {
const formatted = formatSendMessageError(error);
return {
id: Date.now().toString(),
type: "error",
title: "Message Send Failed",
message: error.raw || "An unexpected error occurred while sending your message.",
message: formatted.message,
};
}
}
};
6 changes: 2 additions & 4 deletions src/components/CommandPalette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useCommandRegistry } from "@/contexts/CommandRegistryContext";
import type { CommandAction } from "@/contexts/CommandRegistryContext";
import { formatKeybind, KEYBINDS, isEditableElement, matchesKeybind } from "@/utils/ui/keybinds";
import { getSlashCommandSuggestions } from "@/utils/slashCommands/suggestions";
import { CUSTOM_EVENTS } from "@/constants/events";
import { CUSTOM_EVENTS, createCustomEvent } from "@/constants/events";

interface CommandPaletteProps {
getSlashContext?: () => { providerNames: string[]; workspaceId?: string };
Expand Down Expand Up @@ -189,9 +189,7 @@ export const CommandPalette: React.FC<CommandPaletteProps> = ({ getSlashContext
shortcutHint: `${formatKeybind(KEYBINDS.SEND_MESSAGE)} to insert`,
run: () => {
const text = s.replacement;
window.dispatchEvent(
new CustomEvent(CUSTOM_EVENTS.INSERT_TO_CHAT_INPUT, { detail: { text } })
);
window.dispatchEvent(createCustomEvent(CUSTOM_EVENTS.INSERT_TO_CHAT_INPUT, { text }));
},
})),
},
Expand Down
Loading