osc633Parser.ts ×8

Frontier kind: Code frontier

unlabeled · c_563ca1a907d4

1064 tests · 3517 LOC · 19 files · introduces 0 tests · 139 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
8 ranges139 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
488 ranges3517 lines · 19 files · Browse complete extent
All tests (intent)
1064 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 139 introduced LOC across 8 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/osc633Parser.ts 139 introduced LOC · 8 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- osc633Parser.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > /**
7 > * Lightweight parser for OSC 633 (VS Code shell integration) sequences in raw
8 > * PTY output. Designed for the agent host where we don't have a full xterm.js
9 > * instance - it scans data chunks for the sequences, extracts events, and
10 > * removes the sequences from the data stream.
11 > *
12 > * Handles partial sequences that span across data chunk boundaries.
13 > */
14 >
15 > /** OSC 633 event types we care about. */
16 > export const enum Osc633EventType {
17 > /** 633;A - Prompt start. Used to detect shell integration is active. */
18 > PromptStart,
19 > /** 633;B - Command start (where user inputs command). */
20 > CommandStart,
21 > /** 633;C - Command executed (output begins). */
22 > CommandExecuted,
23 > /** 633;D[;exitCode] - Command finished. */
24 > CommandFinished,
25 > /** 633;E;commandLine[;nonce] - Explicit command line. */
26 > CommandLine,
27 > /** 633;P;Key=Value - Property (e.g. Cwd). */
28 > Property,
29 > }
30 >
31 > export interface IOsc633PromptStartEvent {
32 > type: Osc633EventType.PromptStart;
33 > }
34 >
35 > export interface IOsc633CommandStartEvent {
36 > type: Osc633EventType.CommandStart;
37 > }
38 >
39 > export interface IOsc633CommandExecutedEvent {
40 > type: Osc633EventType.CommandExecuted;
41 > }
42 >
43 > export interface IOsc633CommandFinishedEvent {
44 > type: Osc633EventType.CommandFinished;
45 > exitCode: number | undefined;
46 > }
47 >
48 > export interface IOsc633CommandLineEvent {
49 > type: Osc633EventType.CommandLine;
50 > commandLine: string;
51 > nonce: string | undefined;
52 > }
53 >
54 > export interface IOsc633PropertyEvent {
55 > type: Osc633EventType.Property;
56 > key: string;
57 > value: string;
58 > }
59 >
60 > export type Osc633Event =
61 > | IOsc633PromptStartEvent
62 > | IOsc633CommandStartEvent
63 > | IOsc633CommandExecutedEvent
64 > | IOsc633CommandFinishedEvent
65 > | IOsc633CommandLineEvent
66 > | IOsc633PropertyEvent;
67 >
68 > export interface IOsc633ParseResult {
69 > /** Data with all OSC 633 sequences stripped. */
70 > cleanedData: string;
71 > /** Parsed events in order of appearance. */
72 > events: Osc633Event[];
73 > }
74 >
75 > /**
76 > * A single segment of parsed PTY data: either a run of cleaned output data or
77 > * an OSC 633 event. Segments are emitted in stream order so that output which
78 > * arrives before an event (e.g. a `CommandFinished` marker) can be attributed
79 > * to the command before the event is handled — see {@link Osc633Parser.parseSegments}.
80 > */
81 > export type Osc633ParseSegment =
82 > | { readonly kind: 'data'; readonly data: string }
83 > | { readonly kind: 'event'; readonly event: Osc633Event };
84 >
85 > /**
86 > * Decode escaped values in OSC 633 messages.
87 > * Handles `\\` -> `\` and `\xAB` -> character with code 0xAB.
88 > */
89 function deserializeOscMessage(message: string): string {
90 if (message.indexOf('\\') === -1) {
96 );
97 }
99 function parseOsc633Payload(payload: string): Osc633Event | undefined {
100 const semiIdx = payload.indexOf(';');
142 }
143 }
145 > // OSC introducer is ESC ] (0x1b 0x5d)
146 > const ESC = '\x1b';
147 > const OSC_START = ESC + ']';
148 > // Terminators: BEL (0x07) or ST (ESC \)
149 > const BEL = '\x07';
150 > const ST = ESC + '\\';
151 >
152 > /**
153 > * Stateful parser that handles data chunks, correctly dealing with
154 > * partial sequences that span multiple chunks.
155 > */
156 > export class Osc633Parser {
157 /** Buffer for an incomplete OSC sequence (from ESC] up to but not including the terminator). */
158 private _pendingOsc = '';
161 /** Set when the previous chunk ended with ESC inside an OSC body (potential ST start). */
162 private _pendingEscInOsc = false;
164 > /**
165 > * Parse a chunk of PTY data.
166 > * Returns cleaned data (all OSC 633 sequences removed) and extracted events.
167 > *
168 > * This is a convenience view over {@link parseSegments} that concatenates the
169 > * cleaned-data segments and collects the events. Callers that need to know
170 > * whether a run of output arrived before or after an event (for correct
171 > * command-output attribution) should use {@link parseSegments} instead.
172 > */
173 > parse(data: string): IOsc633ParseResult {
174 const events: Osc633Event[] = [];
175 let cleanedData = '';
183 return { cleanedData, events };
184 }
186 > /**
187 > * Parse a chunk of PTY data into an ordered list of segments, preserving the
188 > * relative order of cleaned output data and OSC 633 events as they appear in
189 > * the stream. Handles partial sequences that span multiple chunks.
190 > *
191 > * Preserving order matters because a single PTY read frequently contains a
192 > * command's output immediately followed by its `CommandFinished` marker;
193 > * consumers must append that output to the command before handling the
194 > * finished event, otherwise the output is lost from the command result.
195 > */
196 > parseSegments(data: string): Osc633ParseSegment[] {
197 const segments: Osc633ParseSegment[] = [];
198 let pending = '';
291 return segments;
292 }
294 > /**
295 > * Consume characters from the OSC body, appending to _pendingOsc until a
296 > * terminator (BEL or ST) is found.
297 > */
298 > private _consumeOscBody(data: string, startIdx: number): { nextIndex: number; complete: boolean; pendingEsc?: boolean; terminator?: string } {
299 const belIdx = data.indexOf(BEL, startIdx);
300 const escIdx = data.indexOf(ESC, startIdx);
322 return { nextIndex: data.length, complete: false };
323 }
325 > /**
326 > * Process a complete OSC payload. If it's a 633; sequence, extract the
327 > * event via {@link emitEvent}. Otherwise, reconstruct the original bytes and
328 > * pass them through to the cleaned output via {@link appendData}.
329 > */
330 > private _handleOscPayload(
331 payload: string,
332 emitEvent: (event: Osc633Event) => void,