From a7f29d19b0edd95ead8be2fa47312bcab407ec51 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 28 Dec 2025 11:11:39 -0800 Subject: [PATCH 1/4] fix(desktop): suppress focus in/out terminal sequences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CSI handlers for 'I' (focus in) and 'O' (focus out) sequences that are sent when focus reporting mode (1004) is enabled by programs like vim/neovim. These should be suppressed, not displayed as text. ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../TabsContent/Terminal/suppressQueryResponses.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts index bb0fec9296e..d627673d364 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts @@ -25,6 +25,14 @@ export function suppressQueryResponses(terminal: Terminal): () => void { // CPR: ESC[24;1R (row;column) disposables.push(parser.registerCsiHandler({ final: "R" }, () => true)); + // CSI sequences ending in 'I' - Focus In report + // Sent when terminal gains focus (mode 1004 enabled) + disposables.push(parser.registerCsiHandler({ final: "I" }, () => true)); + + // CSI sequences ending in 'O' - Focus Out report + // Sent when terminal loses focus (mode 1004 enabled) + disposables.push(parser.registerCsiHandler({ final: "O" }, () => true)); + // CSI sequences ending in 'y' with '$' intermediate - Mode Reports // DECRPM: ESC[?1;2$y (private mode report) // Standard mode report: ESC[12;2$y From 042cfa6df769348fedc422c777ac0e4a9dad42e5 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 28 Dec 2025 11:15:11 -0800 Subject: [PATCH 2/4] fix(desktop): suppress terminal query response sequences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add parser hooks to prevent query responses from displaying as text: - CSI 'I'/'O' - Focus in/out reports (mode 1004) - OSC 4 - Indexed color palette queries ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../TabsContent/Terminal/suppressQueryResponses.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts index d627673d364..6e648bdfbe3 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts @@ -42,6 +42,10 @@ export function suppressQueryResponses(terminal: Terminal): () => void { }), ); + // OSC 4 - Indexed color palette query responses + // OSC 4;index;rgb:rrrr/gggg/bbbb (palette color for index) + disposables.push(parser.registerOscHandler(4, () => true)); + // OSC 10-19 - Color query responses // OSC 10: foreground color (ESC]10;rgb:ffff/ffff/ffff BEL) // OSC 11: background color From fb0b1d394585d85cf9c8d74dd556040862efa242 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 28 Dec 2025 11:23:36 -0800 Subject: [PATCH 3/4] fix(desktop): only suppress safe terminal response sequences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove handlers that could break terminal functionality: - CSI 'c' removed (breaks DA queries) - CSI 't' removed (breaks window commands) - OSC 4/10-19 removed (breaks color setting) Keep only response-only sequences where query has different format: - CSI 'R' (CPR response, query ends in 'n') - CSI 'I'/'O' (focus reports, no query) - CSI '$y' (mode report, query ends in '$p') ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../Terminal/suppressQueryResponses.ts | 63 +++++++------------ 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts index 6e648bdfbe3..74cd9afc04d 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/suppressQueryResponses.ts @@ -3,10 +3,19 @@ import type { Terminal } from "@xterm/xterm"; /** * Registers parser hooks to suppress terminal query responses from being displayed. * - * When programs query terminal capabilities (DA1, DA2, CPR, etc.), the terminal - * responds with escape sequences. These responses should be handled internally, - * not displayed as visible text. xterm.js's parser hooks let us intercept and - * suppress these sequences at the display layer. + * These handlers intercept specific response-only sequences that should not appear + * as visible text. We only suppress sequences where the response has a DIFFERENT + * format than the query, ensuring we don't break terminal functionality. + * + * SAFE to suppress (response-only, query uses different format): + * - CSI R: CPR response (query is CSI 6n) + * - CSI I/O: Focus reports (no query, just mode enable) + * - CSI $y: Mode report (query is CSI $p) + * + * NOT suppressed (would break queries/commands): + * - CSI c: DA query AND response both end in 'c' + * - CSI t: Window query AND response both end in 't' + * - OSC colors: Set command AND response have same format * * @param terminal - The xterm.js Terminal instance * @returns Cleanup function to dispose all registered handlers @@ -15,50 +24,26 @@ export function suppressQueryResponses(terminal: Terminal): () => void { const disposables: { dispose: () => void }[] = []; const parser = terminal.parser; - // CSI sequences ending in 'c' - Device Attributes responses - // DA1: ESC[?1;2c (primary device attributes) - // DA2: ESC[>0;276;0c (secondary device attributes) - // Also handles ESC[0;276;0c (without ? or > prefix) - disposables.push(parser.registerCsiHandler({ final: "c" }, () => true)); - - // CSI sequences ending in 'R' - Cursor Position Report - // CPR: ESC[24;1R (row;column) + // CSI sequences ending in 'R' - Cursor Position Report (SAFE) + // Query: ESC[6n (ends in 'n'), Response: ESC[24;1R (ends in 'R') + // Different final bytes, so suppressing 'R' only catches responses disposables.push(parser.registerCsiHandler({ final: "R" }, () => true)); - // CSI sequences ending in 'I' - Focus In report - // Sent when terminal gains focus (mode 1004 enabled) + // CSI sequences ending in 'I' - Focus In report (SAFE) + // No query - this is sent when terminal gains focus (mode 1004) disposables.push(parser.registerCsiHandler({ final: "I" }, () => true)); - // CSI sequences ending in 'O' - Focus Out report - // Sent when terminal loses focus (mode 1004 enabled) + // CSI sequences ending in 'O' - Focus Out report (SAFE) + // No query - this is sent when terminal loses focus (mode 1004) disposables.push(parser.registerCsiHandler({ final: "O" }, () => true)); - // CSI sequences ending in 'y' with '$' intermediate - Mode Reports - // DECRPM: ESC[?1;2$y (private mode report) - // Standard mode report: ESC[12;2$y + // CSI sequences ending in 'y' with '$' intermediate - Mode Reports (SAFE) + // Query: ESC[?Ps$p (ends in 'p'), Response: ESC[?Ps;Pm$y (ends in 'y') + // Different final bytes, so suppressing '$y' only catches responses disposables.push( - parser.registerCsiHandler({ intermediates: "$", final: "y" }, () => { - return true; // Suppress - don't display - }), + parser.registerCsiHandler({ intermediates: "$", final: "y" }, () => true), ); - // OSC 4 - Indexed color palette query responses - // OSC 4;index;rgb:rrrr/gggg/bbbb (palette color for index) - disposables.push(parser.registerOscHandler(4, () => true)); - - // OSC 10-19 - Color query responses - // OSC 10: foreground color (ESC]10;rgb:ffff/ffff/ffff BEL) - // OSC 11: background color - // OSC 12: cursor color - // etc. - for (let i = 10; i <= 19; i++) { - disposables.push( - parser.registerOscHandler(i, () => { - return true; // Suppress - don't display - }), - ); - } - return () => { for (const disposable of disposables) { disposable.dispose(); From ccb409b95c6d230ddc77310f71bff25cefa24d79 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 28 Dec 2025 11:27:21 -0800 Subject: [PATCH 4/4] remove slop code --- .superset/setup.sh | 21 ------------------- .superset/teardown.sh | 15 ------------- .../api/integrations/linear/callback/route.ts | 1 - .../api/integrations/linear/webhook/route.ts | 2 +- 4 files changed, 1 insertion(+), 38 deletions(-) diff --git a/.superset/setup.sh b/.superset/setup.sh index a2313431fe3..4c030e086b4 100755 --- a/.superset/setup.sh +++ b/.superset/setup.sh @@ -54,9 +54,6 @@ print_summary() { [ ${#FAILED_STEPS[@]} -eq 0 ] } -# ============================================================ -# Step 1: Load environment variables -# ============================================================ step_load_env() { echo "๐Ÿ“‚ Loading environment variables..." @@ -79,9 +76,6 @@ step_load_env() { return 0 } -# ============================================================ -# Step 2: Check dependencies -# ============================================================ step_check_dependencies() { echo "๐Ÿ” Checking dependencies..." local missing=() @@ -114,9 +108,6 @@ step_check_dependencies() { return 0 } -# ============================================================ -# Step 3: Install dependencies -# ============================================================ step_install_dependencies() { echo "๐Ÿ“ฅ Installing dependencies..." @@ -134,9 +125,6 @@ step_install_dependencies() { return 0 } -# ============================================================ -# Step 4: Setup Neon branch -# ============================================================ step_setup_neon_branch() { echo "๐Ÿ—„๏ธ Setting up Neon branch..." @@ -201,9 +189,6 @@ step_setup_neon_branch() { return 0 } -# ============================================================ -# Step 5: Start Electric SQL container -# ============================================================ step_start_electric() { echo "โšก Starting Electric SQL container..." @@ -271,9 +256,6 @@ step_start_electric() { return 0 } -# ============================================================ -# Step 6: Write .env file -# ============================================================ step_write_env() { echo "๐Ÿ“ Writing .env file..." @@ -322,9 +304,6 @@ step_write_env() { return 0 } -# ============================================================ -# Main execution -# ============================================================ main() { echo "๐Ÿš€ Setting up Superset workspace..." echo "" diff --git a/.superset/teardown.sh b/.superset/teardown.sh index 73b80c62ea4..3254d80aa08 100755 --- a/.superset/teardown.sh +++ b/.superset/teardown.sh @@ -54,9 +54,6 @@ print_summary() { [ ${#FAILED_STEPS[@]} -eq 0 ] } -# ============================================================ -# Step 1: Load environment variables -# ============================================================ step_load_env() { echo "๐Ÿ“‚ Loading environment variables..." @@ -74,9 +71,6 @@ step_load_env() { return 0 } -# ============================================================ -# Step 2: Check dependencies -# ============================================================ step_check_dependencies() { echo "๐Ÿ” Checking dependencies..." local missing=() @@ -101,9 +95,6 @@ step_check_dependencies() { return 0 } -# ============================================================ -# Step 3: Stop Electric SQL container -# ============================================================ step_stop_electric() { echo "โšก Stopping Electric SQL container..." @@ -133,9 +124,6 @@ step_stop_electric() { return 0 } -# ============================================================ -# Step 4: Delete Neon branch -# ============================================================ step_delete_neon_branch() { echo "๐Ÿ—„๏ธ Deleting Neon branch..." @@ -167,9 +155,6 @@ step_delete_neon_branch() { return 0 } -# ============================================================ -# Main execution -# ============================================================ main() { echo "๐Ÿงน Tearing down Superset workspace..." echo "" diff --git a/apps/api/src/app/api/integrations/linear/callback/route.ts b/apps/api/src/app/api/integrations/linear/callback/route.ts index b6a21486261..f41e4954d00 100644 --- a/apps/api/src/app/api/integrations/linear/callback/route.ts +++ b/apps/api/src/app/api/integrations/linear/callback/route.ts @@ -108,7 +108,6 @@ export async function GET(request: Request) { }); } catch (error) { console.error("Failed to queue initial sync job:", error); - // Connection saved successfully, just sync failed - redirect with warning return Response.redirect( `${env.NEXT_PUBLIC_WEB_URL}/integrations/linear?warning=sync_queued_failed`, ); diff --git a/apps/api/src/app/api/integrations/linear/webhook/route.ts b/apps/api/src/app/api/integrations/linear/webhook/route.ts index e89d40f3b02..d820c6a626e 100644 --- a/apps/api/src/app/api/integrations/linear/webhook/route.ts +++ b/apps/api/src/app/api/integrations/linear/webhook/route.ts @@ -33,7 +33,7 @@ export async function POST(request: Request) { provider: "linear", eventId: `${payload.organizationId}-${payload.webhookTimestamp}`, eventType: `${payload.type}.${payload.action}`, - payload: payload as unknown as Record, + payload, status: "pending", }) .returning();