restty 0.1.23 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import type { InputHandler, MouseMode } from "../input";
1
+ import type { DesktopNotification, InputHandler, MouseMode } from "../input";
2
2
  import type { GhosttyTheme } from "../theme";
3
3
  import { type CreateResttyAppPaneManagerOptions, type ResttyManagedAppPane, type ResttyManagedPaneStyleOptions, type ResttyPaneAppOptionsInput } from "./pane-app-manager";
4
4
  import type { ResttyPaneManager, ResttyPaneSplitDirection } from "./panes";
@@ -11,6 +11,10 @@ export type ResttyOptions = Omit<CreateResttyAppPaneManagerOptions, "appOptions"
11
11
  appOptions?: CreateResttyAppPaneManagerOptions["appOptions"];
12
12
  /** Font sources applied to every pane. */
13
13
  fontSources?: ResttyPaneAppOptionsInput["fontSources"];
14
+ /** Global handler for desktop notifications emitted by any pane. */
15
+ onDesktopNotification?: (notification: DesktopNotification & {
16
+ paneId: number;
17
+ }) => void;
14
18
  /** Whether to create the first pane automatically (default true). */
15
19
  createInitialPane?: boolean | {
16
20
  focus?: boolean;
@@ -1,4 +1,4 @@
1
- import type { InputHandler, MouseMode } from "../input";
1
+ import type { DesktopNotification, InputHandler, MouseMode } from "../input";
2
2
  import type { PtyTransport } from "../pty";
3
3
  import type { WebGPUCoreState } from "../renderer";
4
4
  import type { GhosttyTheme } from "../theme";
@@ -85,6 +85,8 @@ export type ResttyAppCallbacks = {
85
85
  onPtyStatus?: (status: string) => void;
86
86
  /** Mouse mode/status changed. */
87
87
  onMouseStatus?: (status: string) => void;
88
+ /** Terminal requested a desktop notification via OSC 9 / OSC 777. */
89
+ onDesktopNotification?: (notification: DesktopNotification) => void;
88
90
  };
89
91
  /** Raw font data as an ArrayBuffer or typed-array view. */
90
92
  export type ResttyFontBufferData = ArrayBuffer | ArrayBufferView;
@@ -8576,6 +8576,7 @@ class OutputFilter {
8576
8576
  clipboardWrite;
8577
8577
  clipboardRead;
8578
8578
  getDefaultColors;
8579
+ desktopNotificationHandler;
8579
8580
  semanticPromptSeen = false;
8580
8581
  promptClickEvents = false;
8581
8582
  promptInputActive = false;
@@ -8589,6 +8590,7 @@ class OutputFilter {
8589
8590
  this.clipboardRead = options.onClipboardRead;
8590
8591
  this.windowOpHandler = options.onWindowOp;
8591
8592
  this.getWindowMetrics = options.getWindowMetrics;
8593
+ this.desktopNotificationHandler = options.onDesktopNotification;
8592
8594
  }
8593
8595
  setCursorProvider(fn) {
8594
8596
  this.getCursorPosition = fn;
@@ -8696,6 +8698,39 @@ class OutputFilter {
8696
8698
  const content = seq.slice(2);
8697
8699
  const parts = content.split(";");
8698
8700
  const code = parts[0] ?? "";
8701
+ if (code === "9") {
8702
+ const firstSep = content.indexOf(";");
8703
+ const body = firstSep >= 0 ? content.slice(firstSep + 1) : "";
8704
+ if (/^(?:[2-9]|1[0-2]?)(?:;|$)/.test(body)) {
8705
+ return true;
8706
+ }
8707
+ this.desktopNotificationHandler?.({
8708
+ title: "",
8709
+ body,
8710
+ source: "osc9",
8711
+ raw: seq
8712
+ });
8713
+ return true;
8714
+ }
8715
+ if (code === "777") {
8716
+ const firstSep = content.indexOf(";");
8717
+ const rest = firstSep >= 0 ? content.slice(firstSep + 1) : "";
8718
+ if (!rest.startsWith("notify;")) {
8719
+ return true;
8720
+ }
8721
+ const payload = rest.slice("notify;".length);
8722
+ const titleSep = payload.indexOf(";");
8723
+ if (titleSep < 0) {
8724
+ return true;
8725
+ }
8726
+ this.desktopNotificationHandler?.({
8727
+ title: payload.slice(0, titleSep),
8728
+ body: payload.slice(titleSep + 1),
8729
+ source: "osc777",
8730
+ raw: seq
8731
+ });
8732
+ return true;
8733
+ }
8699
8734
  if (code === "52") {
8700
8735
  const target = parts[1] ?? "c";
8701
8736
  const payload = parts.slice(2).join(";");
@@ -8904,7 +8939,8 @@ function createInputHandler(options = {}) {
8904
8939
  onClipboardRead: options.onClipboardRead,
8905
8940
  onClipboardWrite: options.onClipboardWrite,
8906
8941
  onWindowOp: options.onWindowOp,
8907
- getWindowMetrics: options.getWindowMetrics
8942
+ getWindowMetrics: options.getWindowMetrics,
8943
+ onDesktopNotification: options.onDesktopNotification
8908
8944
  });
8909
8945
  return {
8910
8946
  sequences,
@@ -51508,7 +51544,8 @@ function createResttyApp(options) {
51508
51544
  },
51509
51545
  onWindowOp: (op) => {
51510
51546
  appendLog(`[term] window op ${op.type} ${op.params.join(";")}`);
51511
- }
51547
+ },
51548
+ onDesktopNotification: callbacks?.onDesktopNotification
51512
51549
  });
51513
51550
  inputHandler.setMouseMode("auto");
51514
51551
  function clearSelection() {
@@ -56858,6 +56895,7 @@ class Restty {
56858
56895
  createInitialPane = true,
56859
56896
  appOptions,
56860
56897
  fontSources,
56898
+ onDesktopNotification,
56861
56899
  onPaneCreated,
56862
56900
  onPaneClosed,
56863
56901
  onPaneSplit,
@@ -56870,9 +56908,17 @@ class Restty {
56870
56908
  const resolved = typeof appOptions === "function" ? appOptions(context) : appOptions ?? {};
56871
56909
  const resolvedBeforeInput = resolved.beforeInput;
56872
56910
  const resolvedBeforeRenderOutput = resolved.beforeRenderOutput;
56911
+ const resolvedCallbacks = resolved.callbacks;
56873
56912
  return {
56874
56913
  ...resolved,
56875
56914
  ...this.fontSources ? { fontSources: this.fontSources } : {},
56915
+ callbacks: onDesktopNotification || resolvedCallbacks?.onDesktopNotification ? {
56916
+ ...resolvedCallbacks,
56917
+ onDesktopNotification: (notification) => {
56918
+ resolvedCallbacks?.onDesktopNotification?.(notification);
56919
+ onDesktopNotification?.({ ...notification, paneId: context.id });
56920
+ }
56921
+ } : resolvedCallbacks,
56876
56922
  beforeInput: ({ text, source }) => {
56877
56923
  const maybeUserText = resolvedBeforeInput?.({ text, source });
56878
56924
  if (maybeUserText === null)
@@ -3,4 +3,4 @@ import type { InputHandler, InputHandlerOptions } from "./types";
3
3
  * Create a terminal input handler with key, IME, PTY, and mouse support.
4
4
  */
5
5
  export declare function createInputHandler(options?: InputHandlerOptions): InputHandler;
6
- export type { CellPosition, CursorPosition, InputHandler, InputHandlerConfig, InputHandlerOptions, MouseMode, MouseStatus, } from "./types";
6
+ export type { CellPosition, CursorPosition, InputHandler, InputHandlerConfig, InputHandlerOptions, MouseMode, MouseStatus, DesktopNotification, } from "./types";
@@ -1,4 +1,4 @@
1
- import type { CellPosition, CursorPosition, WindowOp } from "./types";
1
+ import type { CellPosition, CursorPosition, DesktopNotification, WindowOp } from "./types";
2
2
  import type { MouseController } from "./mouse";
3
3
  /**
4
4
  * Construction options for OutputFilter.
@@ -31,6 +31,8 @@ export type OutputFilterOptions = {
31
31
  cellWidthPx: number;
32
32
  cellHeightPx: number;
33
33
  };
34
+ /** Handler for desktop notifications (OSC 9 / OSC 777). */
35
+ onDesktopNotification?: (notification: DesktopNotification) => void;
34
36
  };
35
37
  /**
36
38
  * Parses output for control queries (CPR/DA) and mouse mode toggles,
@@ -50,6 +52,7 @@ export declare class OutputFilter {
50
52
  private clipboardWrite?;
51
53
  private clipboardRead?;
52
54
  private getDefaultColors?;
55
+ private desktopNotificationHandler?;
53
56
  private semanticPromptSeen;
54
57
  private promptClickEvents;
55
58
  private promptInputActive;
@@ -59,6 +59,15 @@ export type WindowOp = {
59
59
  params: number[];
60
60
  raw: string;
61
61
  };
62
+ /**
63
+ * Desktop notification payload parsed from terminal OSC sequences.
64
+ */
65
+ export type DesktopNotification = {
66
+ title: string;
67
+ body: string;
68
+ source: "osc9" | "osc777";
69
+ raw: string;
70
+ };
62
71
  /**
63
72
  * Input handler construction options.
64
73
  */
@@ -103,6 +112,10 @@ export type InputHandlerOptions = {
103
112
  */
104
113
  onClipboardWrite?: (text: string) => void | Promise<void>;
105
114
  onClipboardRead?: () => string | null | Promise<string | null>;
115
+ /**
116
+ * Optional handler for desktop notifications (OSC 9 / OSC 777).
117
+ */
118
+ onDesktopNotification?: (notification: DesktopNotification) => void;
106
119
  /**
107
120
  * Return active Kitty keyboard protocol flags (CSI ? u query result).
108
121
  */
package/dist/internal.js CHANGED
@@ -89,7 +89,7 @@ import {
89
89
  updateComposition,
90
90
  updateGridState,
91
91
  updateImePosition
92
- } from "./chunk-mkkhfg0z.js";
92
+ } from "./chunk-68qdtczc.js";
93
93
  // src/selection/selection.ts
94
94
  function createSelectionState() {
95
95
  return {
package/dist/restty.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  isBuiltinThemeName,
9
9
  listBuiltinThemeNames,
10
10
  parseGhosttyTheme
11
- } from "./chunk-mkkhfg0z.js";
11
+ } from "./chunk-68qdtczc.js";
12
12
  export {
13
13
  parseGhosttyTheme,
14
14
  listBuiltinThemeNames,
package/dist/xterm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createRestty
3
- } from "./chunk-mkkhfg0z.js";
3
+ } from "./chunk-68qdtczc.js";
4
4
 
5
5
  // src/xterm.ts
6
6
  class Terminal {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "restty",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Browser terminal rendering library powered by WASM, WebGPU/WebGL2, and TypeScript text shaping.",
5
5
  "keywords": [
6
6
  "terminal",