diff --git a/.github/workflows/copilot-sdk-ci.yml b/.github/workflows/copilot-sdk-ci.yml index a3fc4aa2c87..0388558a8af 100644 --- a/.github/workflows/copilot-sdk-ci.yml +++ b/.github/workflows/copilot-sdk-ci.yml @@ -98,8 +98,8 @@ jobs: } EOF - # Run the client - DEBUG=copilot-client cat /tmp/test/config.json | node dist/cli.js + # Run the client (using index.js which exports main()) + DEBUG=copilot-client cat /tmp/test/config.json | node -e "import('./dist/index.js').then(m => m.main())" # Verify event log was created if [ ! -f /tmp/test/events.jsonl ]; then diff --git a/Makefile b/Makefile index 84ecea52ba1..b1838ee5401 100644 --- a/Makefile +++ b/Makefile @@ -651,7 +651,7 @@ sync-action-scripts: # Recompile all workflow files .PHONY: recompile -recompile: build +recompile: build copilot-client ./$(BINARY_NAME) init --codespaces ./$(BINARY_NAME) compile --validate --verbose --purge --stats # ./$(BINARY_NAME) compile --dir pkg/cli/workflows --validate --verbose --purge diff --git a/actions/setup/js/copilot-client.js b/actions/setup/js/copilot-client.js new file mode 100644 index 00000000000..ce93fd16a6f --- /dev/null +++ b/actions/setup/js/copilot-client.js @@ -0,0 +1,5484 @@ +import { spawn } from 'child_process'; +import { mkdirSync, readFileSync, appendFileSync, existsSync } from 'fs'; +import { Socket } from 'net'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] +}) : x)(function(x) { + if (typeof require !== "undefined") return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); +}); +var __commonJS = (cb, mod) => function __require2() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + __defProp(target, "default", { value: mod, enumerable: true }) , + mod +)); + +// node_modules/vscode-jsonrpc/lib/common/is.js +var require_is = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/is.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.stringArray = exports$1.array = exports$1.func = exports$1.error = exports$1.number = exports$1.string = exports$1.boolean = void 0; + function boolean(value) { + return value === true || value === false; + } + exports$1.boolean = boolean; + function string(value) { + return typeof value === "string" || value instanceof String; + } + exports$1.string = string; + function number(value) { + return typeof value === "number" || value instanceof Number; + } + exports$1.number = number; + function error(value) { + return value instanceof Error; + } + exports$1.error = error; + function func(value) { + return typeof value === "function"; + } + exports$1.func = func; + function array(value) { + return Array.isArray(value); + } + exports$1.array = array; + function stringArray(value) { + return array(value) && value.every((elem) => string(elem)); + } + exports$1.stringArray = stringArray; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/messages.js +var require_messages = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/messages.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.Message = exports$1.NotificationType9 = exports$1.NotificationType8 = exports$1.NotificationType7 = exports$1.NotificationType6 = exports$1.NotificationType5 = exports$1.NotificationType4 = exports$1.NotificationType3 = exports$1.NotificationType2 = exports$1.NotificationType1 = exports$1.NotificationType0 = exports$1.NotificationType = exports$1.RequestType9 = exports$1.RequestType8 = exports$1.RequestType7 = exports$1.RequestType6 = exports$1.RequestType5 = exports$1.RequestType4 = exports$1.RequestType3 = exports$1.RequestType2 = exports$1.RequestType1 = exports$1.RequestType = exports$1.RequestType0 = exports$1.AbstractMessageSignature = exports$1.ParameterStructures = exports$1.ResponseError = exports$1.ErrorCodes = void 0; + var is = require_is(); + var ErrorCodes; + (function(ErrorCodes2) { + ErrorCodes2.ParseError = -32700; + ErrorCodes2.InvalidRequest = -32600; + ErrorCodes2.MethodNotFound = -32601; + ErrorCodes2.InvalidParams = -32602; + ErrorCodes2.InternalError = -32603; + ErrorCodes2.jsonrpcReservedErrorRangeStart = -32099; + ErrorCodes2.serverErrorStart = -32099; + ErrorCodes2.MessageWriteError = -32099; + ErrorCodes2.MessageReadError = -32098; + ErrorCodes2.PendingResponseRejected = -32097; + ErrorCodes2.ConnectionInactive = -32096; + ErrorCodes2.ServerNotInitialized = -32002; + ErrorCodes2.UnknownErrorCode = -32001; + ErrorCodes2.jsonrpcReservedErrorRangeEnd = -32e3; + ErrorCodes2.serverErrorEnd = -32e3; + })(ErrorCodes || (exports$1.ErrorCodes = ErrorCodes = {})); + var ResponseError = class _ResponseError extends Error { + constructor(code, message, data) { + super(message); + this.code = is.number(code) ? code : ErrorCodes.UnknownErrorCode; + this.data = data; + Object.setPrototypeOf(this, _ResponseError.prototype); + } + toJson() { + const result = { + code: this.code, + message: this.message + }; + if (this.data !== void 0) { + result.data = this.data; + } + return result; + } + }; + exports$1.ResponseError = ResponseError; + var ParameterStructures = class _ParameterStructures { + constructor(kind) { + this.kind = kind; + } + static is(value) { + return value === _ParameterStructures.auto || value === _ParameterStructures.byName || value === _ParameterStructures.byPosition; + } + toString() { + return this.kind; + } + }; + exports$1.ParameterStructures = ParameterStructures; + ParameterStructures.auto = new ParameterStructures("auto"); + ParameterStructures.byPosition = new ParameterStructures("byPosition"); + ParameterStructures.byName = new ParameterStructures("byName"); + var AbstractMessageSignature = class { + constructor(method, numberOfParams) { + this.method = method; + this.numberOfParams = numberOfParams; + } + get parameterStructures() { + return ParameterStructures.auto; + } + }; + exports$1.AbstractMessageSignature = AbstractMessageSignature; + var RequestType0 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 0); + } + }; + exports$1.RequestType0 = RequestType0; + var RequestType = class extends AbstractMessageSignature { + constructor(method, _parameterStructures = ParameterStructures.auto) { + super(method, 1); + this._parameterStructures = _parameterStructures; + } + get parameterStructures() { + return this._parameterStructures; + } + }; + exports$1.RequestType = RequestType; + var RequestType1 = class extends AbstractMessageSignature { + constructor(method, _parameterStructures = ParameterStructures.auto) { + super(method, 1); + this._parameterStructures = _parameterStructures; + } + get parameterStructures() { + return this._parameterStructures; + } + }; + exports$1.RequestType1 = RequestType1; + var RequestType2 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 2); + } + }; + exports$1.RequestType2 = RequestType2; + var RequestType3 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 3); + } + }; + exports$1.RequestType3 = RequestType3; + var RequestType4 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 4); + } + }; + exports$1.RequestType4 = RequestType4; + var RequestType5 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 5); + } + }; + exports$1.RequestType5 = RequestType5; + var RequestType6 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 6); + } + }; + exports$1.RequestType6 = RequestType6; + var RequestType7 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 7); + } + }; + exports$1.RequestType7 = RequestType7; + var RequestType8 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 8); + } + }; + exports$1.RequestType8 = RequestType8; + var RequestType9 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 9); + } + }; + exports$1.RequestType9 = RequestType9; + var NotificationType = class extends AbstractMessageSignature { + constructor(method, _parameterStructures = ParameterStructures.auto) { + super(method, 1); + this._parameterStructures = _parameterStructures; + } + get parameterStructures() { + return this._parameterStructures; + } + }; + exports$1.NotificationType = NotificationType; + var NotificationType0 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 0); + } + }; + exports$1.NotificationType0 = NotificationType0; + var NotificationType1 = class extends AbstractMessageSignature { + constructor(method, _parameterStructures = ParameterStructures.auto) { + super(method, 1); + this._parameterStructures = _parameterStructures; + } + get parameterStructures() { + return this._parameterStructures; + } + }; + exports$1.NotificationType1 = NotificationType1; + var NotificationType2 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 2); + } + }; + exports$1.NotificationType2 = NotificationType2; + var NotificationType3 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 3); + } + }; + exports$1.NotificationType3 = NotificationType3; + var NotificationType4 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 4); + } + }; + exports$1.NotificationType4 = NotificationType4; + var NotificationType5 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 5); + } + }; + exports$1.NotificationType5 = NotificationType5; + var NotificationType6 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 6); + } + }; + exports$1.NotificationType6 = NotificationType6; + var NotificationType7 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 7); + } + }; + exports$1.NotificationType7 = NotificationType7; + var NotificationType8 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 8); + } + }; + exports$1.NotificationType8 = NotificationType8; + var NotificationType9 = class extends AbstractMessageSignature { + constructor(method) { + super(method, 9); + } + }; + exports$1.NotificationType9 = NotificationType9; + var Message; + (function(Message2) { + function isRequest(message) { + const candidate = message; + return candidate && is.string(candidate.method) && (is.string(candidate.id) || is.number(candidate.id)); + } + Message2.isRequest = isRequest; + function isNotification(message) { + const candidate = message; + return candidate && is.string(candidate.method) && message.id === void 0; + } + Message2.isNotification = isNotification; + function isResponse(message) { + const candidate = message; + return candidate && (candidate.result !== void 0 || !!candidate.error) && (is.string(candidate.id) || is.number(candidate.id) || candidate.id === null); + } + Message2.isResponse = isResponse; + })(Message || (exports$1.Message = Message = {})); + } +}); + +// node_modules/vscode-jsonrpc/lib/common/linkedMap.js +var require_linkedMap = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/linkedMap.js"(exports$1) { + var _a; + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.LRUCache = exports$1.LinkedMap = exports$1.Touch = void 0; + var Touch; + (function(Touch2) { + Touch2.None = 0; + Touch2.First = 1; + Touch2.AsOld = Touch2.First; + Touch2.Last = 2; + Touch2.AsNew = Touch2.Last; + })(Touch || (exports$1.Touch = Touch = {})); + var LinkedMap = class { + constructor() { + this[_a] = "LinkedMap"; + this._map = /* @__PURE__ */ new Map(); + this._head = void 0; + this._tail = void 0; + this._size = 0; + this._state = 0; + } + clear() { + this._map.clear(); + this._head = void 0; + this._tail = void 0; + this._size = 0; + this._state++; + } + isEmpty() { + return !this._head && !this._tail; + } + get size() { + return this._size; + } + get first() { + return this._head?.value; + } + get last() { + return this._tail?.value; + } + has(key) { + return this._map.has(key); + } + get(key, touch = Touch.None) { + const item = this._map.get(key); + if (!item) { + return void 0; + } + if (touch !== Touch.None) { + this.touch(item, touch); + } + return item.value; + } + set(key, value, touch = Touch.None) { + let item = this._map.get(key); + if (item) { + item.value = value; + if (touch !== Touch.None) { + this.touch(item, touch); + } + } else { + item = { key, value, next: void 0, previous: void 0 }; + switch (touch) { + case Touch.None: + this.addItemLast(item); + break; + case Touch.First: + this.addItemFirst(item); + break; + case Touch.Last: + this.addItemLast(item); + break; + default: + this.addItemLast(item); + break; + } + this._map.set(key, item); + this._size++; + } + return this; + } + delete(key) { + return !!this.remove(key); + } + remove(key) { + const item = this._map.get(key); + if (!item) { + return void 0; + } + this._map.delete(key); + this.removeItem(item); + this._size--; + return item.value; + } + shift() { + if (!this._head && !this._tail) { + return void 0; + } + if (!this._head || !this._tail) { + throw new Error("Invalid list"); + } + const item = this._head; + this._map.delete(item.key); + this.removeItem(item); + this._size--; + return item.value; + } + forEach(callbackfn, thisArg) { + const state = this._state; + let current = this._head; + while (current) { + if (thisArg) { + callbackfn.bind(thisArg)(current.value, current.key, this); + } else { + callbackfn(current.value, current.key, this); + } + if (this._state !== state) { + throw new Error(`LinkedMap got modified during iteration.`); + } + current = current.next; + } + } + keys() { + const state = this._state; + let current = this._head; + const iterator = { + [Symbol.iterator]: () => { + return iterator; + }, + next: () => { + if (this._state !== state) { + throw new Error(`LinkedMap got modified during iteration.`); + } + if (current) { + const result = { value: current.key, done: false }; + current = current.next; + return result; + } else { + return { value: void 0, done: true }; + } + } + }; + return iterator; + } + values() { + const state = this._state; + let current = this._head; + const iterator = { + [Symbol.iterator]: () => { + return iterator; + }, + next: () => { + if (this._state !== state) { + throw new Error(`LinkedMap got modified during iteration.`); + } + if (current) { + const result = { value: current.value, done: false }; + current = current.next; + return result; + } else { + return { value: void 0, done: true }; + } + } + }; + return iterator; + } + entries() { + const state = this._state; + let current = this._head; + const iterator = { + [Symbol.iterator]: () => { + return iterator; + }, + next: () => { + if (this._state !== state) { + throw new Error(`LinkedMap got modified during iteration.`); + } + if (current) { + const result = { value: [current.key, current.value], done: false }; + current = current.next; + return result; + } else { + return { value: void 0, done: true }; + } + } + }; + return iterator; + } + [(_a = Symbol.toStringTag, Symbol.iterator)]() { + return this.entries(); + } + trimOld(newSize) { + if (newSize >= this.size) { + return; + } + if (newSize === 0) { + this.clear(); + return; + } + let current = this._head; + let currentSize = this.size; + while (current && currentSize > newSize) { + this._map.delete(current.key); + current = current.next; + currentSize--; + } + this._head = current; + this._size = currentSize; + if (current) { + current.previous = void 0; + } + this._state++; + } + addItemFirst(item) { + if (!this._head && !this._tail) { + this._tail = item; + } else if (!this._head) { + throw new Error("Invalid list"); + } else { + item.next = this._head; + this._head.previous = item; + } + this._head = item; + this._state++; + } + addItemLast(item) { + if (!this._head && !this._tail) { + this._head = item; + } else if (!this._tail) { + throw new Error("Invalid list"); + } else { + item.previous = this._tail; + this._tail.next = item; + } + this._tail = item; + this._state++; + } + removeItem(item) { + if (item === this._head && item === this._tail) { + this._head = void 0; + this._tail = void 0; + } else if (item === this._head) { + if (!item.next) { + throw new Error("Invalid list"); + } + item.next.previous = void 0; + this._head = item.next; + } else if (item === this._tail) { + if (!item.previous) { + throw new Error("Invalid list"); + } + item.previous.next = void 0; + this._tail = item.previous; + } else { + const next = item.next; + const previous = item.previous; + if (!next || !previous) { + throw new Error("Invalid list"); + } + next.previous = previous; + previous.next = next; + } + item.next = void 0; + item.previous = void 0; + this._state++; + } + touch(item, touch) { + if (!this._head || !this._tail) { + throw new Error("Invalid list"); + } + if (touch !== Touch.First && touch !== Touch.Last) { + return; + } + if (touch === Touch.First) { + if (item === this._head) { + return; + } + const next = item.next; + const previous = item.previous; + if (item === this._tail) { + previous.next = void 0; + this._tail = previous; + } else { + next.previous = previous; + previous.next = next; + } + item.previous = void 0; + item.next = this._head; + this._head.previous = item; + this._head = item; + this._state++; + } else if (touch === Touch.Last) { + if (item === this._tail) { + return; + } + const next = item.next; + const previous = item.previous; + if (item === this._head) { + next.previous = void 0; + this._head = next; + } else { + next.previous = previous; + previous.next = next; + } + item.next = void 0; + item.previous = this._tail; + this._tail.next = item; + this._tail = item; + this._state++; + } + } + toJSON() { + const data = []; + this.forEach((value, key) => { + data.push([key, value]); + }); + return data; + } + fromJSON(data) { + this.clear(); + for (const [key, value] of data) { + this.set(key, value); + } + } + }; + exports$1.LinkedMap = LinkedMap; + var LRUCache = class extends LinkedMap { + constructor(limit, ratio = 1) { + super(); + this._limit = limit; + this._ratio = Math.min(Math.max(0, ratio), 1); + } + get limit() { + return this._limit; + } + set limit(limit) { + this._limit = limit; + this.checkTrim(); + } + get ratio() { + return this._ratio; + } + set ratio(ratio) { + this._ratio = Math.min(Math.max(0, ratio), 1); + this.checkTrim(); + } + get(key, touch = Touch.AsNew) { + return super.get(key, touch); + } + peek(key) { + return super.get(key, Touch.None); + } + set(key, value) { + super.set(key, value, Touch.Last); + this.checkTrim(); + return this; + } + checkTrim() { + if (this.size > this._limit) { + this.trimOld(Math.round(this._limit * this._ratio)); + } + } + }; + exports$1.LRUCache = LRUCache; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/disposable.js +var require_disposable = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/disposable.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.Disposable = void 0; + var Disposable; + (function(Disposable2) { + function create(func) { + return { + dispose: func + }; + } + Disposable2.create = create; + })(Disposable || (exports$1.Disposable = Disposable = {})); + } +}); + +// node_modules/vscode-jsonrpc/lib/common/ral.js +var require_ral = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/ral.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + var _ral; + function RAL() { + if (_ral === void 0) { + throw new Error(`No runtime abstraction layer installed`); + } + return _ral; + } + (function(RAL2) { + function install(ral) { + if (ral === void 0) { + throw new Error(`No runtime abstraction layer provided`); + } + _ral = ral; + } + RAL2.install = install; + })(RAL || (RAL = {})); + exports$1.default = RAL; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/events.js +var require_events = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/events.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.Emitter = exports$1.Event = void 0; + var ral_1 = require_ral(); + var Event; + (function(Event2) { + const _disposable = { dispose() { + } }; + Event2.None = function() { + return _disposable; + }; + })(Event || (exports$1.Event = Event = {})); + var CallbackList = class { + add(callback, context = null, bucket) { + if (!this._callbacks) { + this._callbacks = []; + this._contexts = []; + } + this._callbacks.push(callback); + this._contexts.push(context); + if (Array.isArray(bucket)) { + bucket.push({ dispose: () => this.remove(callback, context) }); + } + } + remove(callback, context = null) { + if (!this._callbacks) { + return; + } + let foundCallbackWithDifferentContext = false; + for (let i = 0, len = this._callbacks.length; i < len; i++) { + if (this._callbacks[i] === callback) { + if (this._contexts[i] === context) { + this._callbacks.splice(i, 1); + this._contexts.splice(i, 1); + return; + } else { + foundCallbackWithDifferentContext = true; + } + } + } + if (foundCallbackWithDifferentContext) { + throw new Error("When adding a listener with a context, you should remove it with the same context"); + } + } + invoke(...args) { + if (!this._callbacks) { + return []; + } + const ret = [], callbacks = this._callbacks.slice(0), contexts = this._contexts.slice(0); + for (let i = 0, len = callbacks.length; i < len; i++) { + try { + ret.push(callbacks[i].apply(contexts[i], args)); + } catch (e) { + (0, ral_1.default)().console.error(e); + } + } + return ret; + } + isEmpty() { + return !this._callbacks || this._callbacks.length === 0; + } + dispose() { + this._callbacks = void 0; + this._contexts = void 0; + } + }; + var Emitter = class _Emitter { + constructor(_options) { + this._options = _options; + } + /** + * For the public to allow to subscribe + * to events from this Emitter + */ + get event() { + if (!this._event) { + this._event = (listener, thisArgs, disposables) => { + if (!this._callbacks) { + this._callbacks = new CallbackList(); + } + if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) { + this._options.onFirstListenerAdd(this); + } + this._callbacks.add(listener, thisArgs); + const result = { + dispose: () => { + if (!this._callbacks) { + return; + } + this._callbacks.remove(listener, thisArgs); + result.dispose = _Emitter._noop; + if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) { + this._options.onLastListenerRemove(this); + } + } + }; + if (Array.isArray(disposables)) { + disposables.push(result); + } + return result; + }; + } + return this._event; + } + /** + * To be kept private to fire an event to + * subscribers + */ + fire(event) { + if (this._callbacks) { + this._callbacks.invoke.call(this._callbacks, event); + } + } + dispose() { + if (this._callbacks) { + this._callbacks.dispose(); + this._callbacks = void 0; + } + } + }; + exports$1.Emitter = Emitter; + Emitter._noop = function() { + }; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/cancellation.js +var require_cancellation = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/cancellation.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.CancellationTokenSource = exports$1.CancellationToken = void 0; + var ral_1 = require_ral(); + var Is = require_is(); + var events_1 = require_events(); + var CancellationToken; + (function(CancellationToken2) { + CancellationToken2.None = Object.freeze({ + isCancellationRequested: false, + onCancellationRequested: events_1.Event.None + }); + CancellationToken2.Cancelled = Object.freeze({ + isCancellationRequested: true, + onCancellationRequested: events_1.Event.None + }); + function is(value) { + const candidate = value; + return candidate && (candidate === CancellationToken2.None || candidate === CancellationToken2.Cancelled || Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested); + } + CancellationToken2.is = is; + })(CancellationToken || (exports$1.CancellationToken = CancellationToken = {})); + var shortcutEvent = Object.freeze(function(callback, context) { + const handle = (0, ral_1.default)().timer.setTimeout(callback.bind(context), 0); + return { dispose() { + handle.dispose(); + } }; + }); + var MutableToken = class { + constructor() { + this._isCancelled = false; + } + cancel() { + if (!this._isCancelled) { + this._isCancelled = true; + if (this._emitter) { + this._emitter.fire(void 0); + this.dispose(); + } + } + } + get isCancellationRequested() { + return this._isCancelled; + } + get onCancellationRequested() { + if (this._isCancelled) { + return shortcutEvent; + } + if (!this._emitter) { + this._emitter = new events_1.Emitter(); + } + return this._emitter.event; + } + dispose() { + if (this._emitter) { + this._emitter.dispose(); + this._emitter = void 0; + } + } + }; + var CancellationTokenSource = class { + get token() { + if (!this._token) { + this._token = new MutableToken(); + } + return this._token; + } + cancel() { + if (!this._token) { + this._token = CancellationToken.Cancelled; + } else { + this._token.cancel(); + } + } + dispose() { + if (!this._token) { + this._token = CancellationToken.None; + } else if (this._token instanceof MutableToken) { + this._token.dispose(); + } + } + }; + exports$1.CancellationTokenSource = CancellationTokenSource; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.js +var require_sharedArrayCancellation = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.SharedArrayReceiverStrategy = exports$1.SharedArraySenderStrategy = void 0; + var cancellation_1 = require_cancellation(); + var CancellationState; + (function(CancellationState2) { + CancellationState2.Continue = 0; + CancellationState2.Cancelled = 1; + })(CancellationState || (CancellationState = {})); + var SharedArraySenderStrategy = class { + constructor() { + this.buffers = /* @__PURE__ */ new Map(); + } + enableCancellation(request) { + if (request.id === null) { + return; + } + const buffer = new SharedArrayBuffer(4); + const data = new Int32Array(buffer, 0, 1); + data[0] = CancellationState.Continue; + this.buffers.set(request.id, buffer); + request.$cancellationData = buffer; + } + async sendCancellation(_conn, id) { + const buffer = this.buffers.get(id); + if (buffer === void 0) { + return; + } + const data = new Int32Array(buffer, 0, 1); + Atomics.store(data, 0, CancellationState.Cancelled); + } + cleanup(id) { + this.buffers.delete(id); + } + dispose() { + this.buffers.clear(); + } + }; + exports$1.SharedArraySenderStrategy = SharedArraySenderStrategy; + var SharedArrayBufferCancellationToken = class { + constructor(buffer) { + this.data = new Int32Array(buffer, 0, 1); + } + get isCancellationRequested() { + return Atomics.load(this.data, 0) === CancellationState.Cancelled; + } + get onCancellationRequested() { + throw new Error(`Cancellation over SharedArrayBuffer doesn't support cancellation events`); + } + }; + var SharedArrayBufferCancellationTokenSource = class { + constructor(buffer) { + this.token = new SharedArrayBufferCancellationToken(buffer); + } + cancel() { + } + dispose() { + } + }; + var SharedArrayReceiverStrategy = class { + constructor() { + this.kind = "request"; + } + createCancellationTokenSource(request) { + const buffer = request.$cancellationData; + if (buffer === void 0) { + return new cancellation_1.CancellationTokenSource(); + } + return new SharedArrayBufferCancellationTokenSource(buffer); + } + }; + exports$1.SharedArrayReceiverStrategy = SharedArrayReceiverStrategy; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/semaphore.js +var require_semaphore = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/semaphore.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.Semaphore = void 0; + var ral_1 = require_ral(); + var Semaphore = class { + constructor(capacity = 1) { + if (capacity <= 0) { + throw new Error("Capacity must be greater than 0"); + } + this._capacity = capacity; + this._active = 0; + this._waiting = []; + } + lock(thunk) { + return new Promise((resolve, reject) => { + this._waiting.push({ thunk, resolve, reject }); + this.runNext(); + }); + } + get active() { + return this._active; + } + runNext() { + if (this._waiting.length === 0 || this._active === this._capacity) { + return; + } + (0, ral_1.default)().timer.setImmediate(() => this.doRunNext()); + } + doRunNext() { + if (this._waiting.length === 0 || this._active === this._capacity) { + return; + } + const next = this._waiting.shift(); + this._active++; + if (this._active > this._capacity) { + throw new Error(`To many thunks active`); + } + try { + const result = next.thunk(); + if (result instanceof Promise) { + result.then((value) => { + this._active--; + next.resolve(value); + this.runNext(); + }, (err) => { + this._active--; + next.reject(err); + this.runNext(); + }); + } else { + this._active--; + next.resolve(result); + this.runNext(); + } + } catch (err) { + this._active--; + next.reject(err); + this.runNext(); + } + } + }; + exports$1.Semaphore = Semaphore; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/messageReader.js +var require_messageReader = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/messageReader.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.ReadableStreamMessageReader = exports$1.AbstractMessageReader = exports$1.MessageReader = void 0; + var ral_1 = require_ral(); + var Is = require_is(); + var events_1 = require_events(); + var semaphore_1 = require_semaphore(); + var MessageReader; + (function(MessageReader2) { + function is(value) { + let candidate = value; + return candidate && Is.func(candidate.listen) && Is.func(candidate.dispose) && Is.func(candidate.onError) && Is.func(candidate.onClose) && Is.func(candidate.onPartialMessage); + } + MessageReader2.is = is; + })(MessageReader || (exports$1.MessageReader = MessageReader = {})); + var AbstractMessageReader = class { + constructor() { + this.errorEmitter = new events_1.Emitter(); + this.closeEmitter = new events_1.Emitter(); + this.partialMessageEmitter = new events_1.Emitter(); + } + dispose() { + this.errorEmitter.dispose(); + this.closeEmitter.dispose(); + } + get onError() { + return this.errorEmitter.event; + } + fireError(error) { + this.errorEmitter.fire(this.asError(error)); + } + get onClose() { + return this.closeEmitter.event; + } + fireClose() { + this.closeEmitter.fire(void 0); + } + get onPartialMessage() { + return this.partialMessageEmitter.event; + } + firePartialMessage(info) { + this.partialMessageEmitter.fire(info); + } + asError(error) { + if (error instanceof Error) { + return error; + } else { + return new Error(`Reader received error. Reason: ${Is.string(error.message) ? error.message : "unknown"}`); + } + } + }; + exports$1.AbstractMessageReader = AbstractMessageReader; + var ResolvedMessageReaderOptions; + (function(ResolvedMessageReaderOptions2) { + function fromOptions(options) { + let charset; + let contentDecoder; + const contentDecoders = /* @__PURE__ */ new Map(); + let contentTypeDecoder; + const contentTypeDecoders = /* @__PURE__ */ new Map(); + if (options === void 0 || typeof options === "string") { + charset = options ?? "utf-8"; + } else { + charset = options.charset ?? "utf-8"; + if (options.contentDecoder !== void 0) { + contentDecoder = options.contentDecoder; + contentDecoders.set(contentDecoder.name, contentDecoder); + } + if (options.contentDecoders !== void 0) { + for (const decoder of options.contentDecoders) { + contentDecoders.set(decoder.name, decoder); + } + } + if (options.contentTypeDecoder !== void 0) { + contentTypeDecoder = options.contentTypeDecoder; + contentTypeDecoders.set(contentTypeDecoder.name, contentTypeDecoder); + } + if (options.contentTypeDecoders !== void 0) { + for (const decoder of options.contentTypeDecoders) { + contentTypeDecoders.set(decoder.name, decoder); + } + } + } + if (contentTypeDecoder === void 0) { + contentTypeDecoder = (0, ral_1.default)().applicationJson.decoder; + contentTypeDecoders.set(contentTypeDecoder.name, contentTypeDecoder); + } + return { charset, contentDecoder, contentDecoders, contentTypeDecoder, contentTypeDecoders }; + } + ResolvedMessageReaderOptions2.fromOptions = fromOptions; + })(ResolvedMessageReaderOptions || (ResolvedMessageReaderOptions = {})); + var ReadableStreamMessageReader = class extends AbstractMessageReader { + constructor(readable, options) { + super(); + this.readable = readable; + this.options = ResolvedMessageReaderOptions.fromOptions(options); + this.buffer = (0, ral_1.default)().messageBuffer.create(this.options.charset); + this._partialMessageTimeout = 1e4; + this.nextMessageLength = -1; + this.messageToken = 0; + this.readSemaphore = new semaphore_1.Semaphore(1); + } + set partialMessageTimeout(timeout) { + this._partialMessageTimeout = timeout; + } + get partialMessageTimeout() { + return this._partialMessageTimeout; + } + listen(callback) { + this.nextMessageLength = -1; + this.messageToken = 0; + this.partialMessageTimer = void 0; + this.callback = callback; + const result = this.readable.onData((data) => { + this.onData(data); + }); + this.readable.onError((error) => this.fireError(error)); + this.readable.onClose(() => this.fireClose()); + return result; + } + onData(data) { + try { + this.buffer.append(data); + while (true) { + if (this.nextMessageLength === -1) { + const headers = this.buffer.tryReadHeaders(true); + if (!headers) { + return; + } + const contentLength = headers.get("content-length"); + if (!contentLength) { + this.fireError(new Error(`Header must provide a Content-Length property. +${JSON.stringify(Object.fromEntries(headers))}`)); + return; + } + const length = parseInt(contentLength); + if (isNaN(length)) { + this.fireError(new Error(`Content-Length value must be a number. Got ${contentLength}`)); + return; + } + this.nextMessageLength = length; + } + const body = this.buffer.tryReadBody(this.nextMessageLength); + if (body === void 0) { + this.setPartialMessageTimer(); + return; + } + this.clearPartialMessageTimer(); + this.nextMessageLength = -1; + this.readSemaphore.lock(async () => { + const bytes = this.options.contentDecoder !== void 0 ? await this.options.contentDecoder.decode(body) : body; + const message = await this.options.contentTypeDecoder.decode(bytes, this.options); + this.callback(message); + }).catch((error) => { + this.fireError(error); + }); + } + } catch (error) { + this.fireError(error); + } + } + clearPartialMessageTimer() { + if (this.partialMessageTimer) { + this.partialMessageTimer.dispose(); + this.partialMessageTimer = void 0; + } + } + setPartialMessageTimer() { + this.clearPartialMessageTimer(); + if (this._partialMessageTimeout <= 0) { + return; + } + this.partialMessageTimer = (0, ral_1.default)().timer.setTimeout((token, timeout) => { + this.partialMessageTimer = void 0; + if (token === this.messageToken) { + this.firePartialMessage({ messageToken: token, waitingTime: timeout }); + this.setPartialMessageTimer(); + } + }, this._partialMessageTimeout, this.messageToken, this._partialMessageTimeout); + } + }; + exports$1.ReadableStreamMessageReader = ReadableStreamMessageReader; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/messageWriter.js +var require_messageWriter = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/messageWriter.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.WriteableStreamMessageWriter = exports$1.AbstractMessageWriter = exports$1.MessageWriter = void 0; + var ral_1 = require_ral(); + var Is = require_is(); + var semaphore_1 = require_semaphore(); + var events_1 = require_events(); + var ContentLength = "Content-Length: "; + var CRLF = "\r\n"; + var MessageWriter; + (function(MessageWriter2) { + function is(value) { + let candidate = value; + return candidate && Is.func(candidate.dispose) && Is.func(candidate.onClose) && Is.func(candidate.onError) && Is.func(candidate.write); + } + MessageWriter2.is = is; + })(MessageWriter || (exports$1.MessageWriter = MessageWriter = {})); + var AbstractMessageWriter = class { + constructor() { + this.errorEmitter = new events_1.Emitter(); + this.closeEmitter = new events_1.Emitter(); + } + dispose() { + this.errorEmitter.dispose(); + this.closeEmitter.dispose(); + } + get onError() { + return this.errorEmitter.event; + } + fireError(error, message, count) { + this.errorEmitter.fire([this.asError(error), message, count]); + } + get onClose() { + return this.closeEmitter.event; + } + fireClose() { + this.closeEmitter.fire(void 0); + } + asError(error) { + if (error instanceof Error) { + return error; + } else { + return new Error(`Writer received error. Reason: ${Is.string(error.message) ? error.message : "unknown"}`); + } + } + }; + exports$1.AbstractMessageWriter = AbstractMessageWriter; + var ResolvedMessageWriterOptions; + (function(ResolvedMessageWriterOptions2) { + function fromOptions(options) { + if (options === void 0 || typeof options === "string") { + return { charset: options ?? "utf-8", contentTypeEncoder: (0, ral_1.default)().applicationJson.encoder }; + } else { + return { charset: options.charset ?? "utf-8", contentEncoder: options.contentEncoder, contentTypeEncoder: options.contentTypeEncoder ?? (0, ral_1.default)().applicationJson.encoder }; + } + } + ResolvedMessageWriterOptions2.fromOptions = fromOptions; + })(ResolvedMessageWriterOptions || (ResolvedMessageWriterOptions = {})); + var WriteableStreamMessageWriter = class extends AbstractMessageWriter { + constructor(writable, options) { + super(); + this.writable = writable; + this.options = ResolvedMessageWriterOptions.fromOptions(options); + this.errorCount = 0; + this.writeSemaphore = new semaphore_1.Semaphore(1); + this.writable.onError((error) => this.fireError(error)); + this.writable.onClose(() => this.fireClose()); + } + async write(msg) { + return this.writeSemaphore.lock(async () => { + const payload = this.options.contentTypeEncoder.encode(msg, this.options).then((buffer) => { + if (this.options.contentEncoder !== void 0) { + return this.options.contentEncoder.encode(buffer); + } else { + return buffer; + } + }); + return payload.then((buffer) => { + const headers = []; + headers.push(ContentLength, buffer.byteLength.toString(), CRLF); + headers.push(CRLF); + return this.doWrite(msg, headers, buffer); + }, (error) => { + this.fireError(error); + throw error; + }); + }); + } + async doWrite(msg, headers, data) { + try { + await this.writable.write(headers.join(""), "ascii"); + return this.writable.write(data); + } catch (error) { + this.handleError(error, msg); + return Promise.reject(error); + } + } + handleError(error, msg) { + this.errorCount++; + this.fireError(error, msg, this.errorCount); + } + end() { + this.writable.end(); + } + }; + exports$1.WriteableStreamMessageWriter = WriteableStreamMessageWriter; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/messageBuffer.js +var require_messageBuffer = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/messageBuffer.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.AbstractMessageBuffer = void 0; + var CR = 13; + var LF = 10; + var CRLF = "\r\n"; + var AbstractMessageBuffer = class { + constructor(encoding = "utf-8") { + this._encoding = encoding; + this._chunks = []; + this._totalLength = 0; + } + get encoding() { + return this._encoding; + } + append(chunk) { + const toAppend = typeof chunk === "string" ? this.fromString(chunk, this._encoding) : chunk; + this._chunks.push(toAppend); + this._totalLength += toAppend.byteLength; + } + tryReadHeaders(lowerCaseKeys = false) { + if (this._chunks.length === 0) { + return void 0; + } + let state = 0; + let chunkIndex = 0; + let offset = 0; + let chunkBytesRead = 0; + row: while (chunkIndex < this._chunks.length) { + const chunk = this._chunks[chunkIndex]; + offset = 0; + while (offset < chunk.length) { + const value = chunk[offset]; + switch (value) { + case CR: + switch (state) { + case 0: + state = 1; + break; + case 2: + state = 3; + break; + default: + state = 0; + } + break; + case LF: + switch (state) { + case 1: + state = 2; + break; + case 3: + state = 4; + offset++; + break row; + default: + state = 0; + } + break; + default: + state = 0; + } + offset++; + } + chunkBytesRead += chunk.byteLength; + chunkIndex++; + } + if (state !== 4) { + return void 0; + } + const buffer = this._read(chunkBytesRead + offset); + const result = /* @__PURE__ */ new Map(); + const headers = this.toString(buffer, "ascii").split(CRLF); + if (headers.length < 2) { + return result; + } + for (let i = 0; i < headers.length - 2; i++) { + const header = headers[i]; + const index = header.indexOf(":"); + if (index === -1) { + throw new Error(`Message header must separate key and value using ':' +${header}`); + } + const key = header.substr(0, index); + const value = header.substr(index + 1).trim(); + result.set(lowerCaseKeys ? key.toLowerCase() : key, value); + } + return result; + } + tryReadBody(length) { + if (this._totalLength < length) { + return void 0; + } + return this._read(length); + } + get numberOfBytes() { + return this._totalLength; + } + _read(byteCount) { + if (byteCount === 0) { + return this.emptyBuffer(); + } + if (byteCount > this._totalLength) { + throw new Error(`Cannot read so many bytes!`); + } + if (this._chunks[0].byteLength === byteCount) { + const chunk = this._chunks[0]; + this._chunks.shift(); + this._totalLength -= byteCount; + return this.asNative(chunk); + } + if (this._chunks[0].byteLength > byteCount) { + const chunk = this._chunks[0]; + const result2 = this.asNative(chunk, byteCount); + this._chunks[0] = chunk.slice(byteCount); + this._totalLength -= byteCount; + return result2; + } + const result = this.allocNative(byteCount); + let resultOffset = 0; + let chunkIndex = 0; + while (byteCount > 0) { + const chunk = this._chunks[chunkIndex]; + if (chunk.byteLength > byteCount) { + const chunkPart = chunk.slice(0, byteCount); + result.set(chunkPart, resultOffset); + resultOffset += byteCount; + this._chunks[chunkIndex] = chunk.slice(byteCount); + this._totalLength -= byteCount; + byteCount -= byteCount; + } else { + result.set(chunk, resultOffset); + resultOffset += chunk.byteLength; + this._chunks.shift(); + this._totalLength -= chunk.byteLength; + byteCount -= chunk.byteLength; + } + } + return result; + } + }; + exports$1.AbstractMessageBuffer = AbstractMessageBuffer; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/connection.js +var require_connection = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/connection.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.createMessageConnection = exports$1.ConnectionOptions = exports$1.MessageStrategy = exports$1.CancellationStrategy = exports$1.CancellationSenderStrategy = exports$1.CancellationReceiverStrategy = exports$1.RequestCancellationReceiverStrategy = exports$1.IdCancellationReceiverStrategy = exports$1.ConnectionStrategy = exports$1.ConnectionError = exports$1.ConnectionErrors = exports$1.LogTraceNotification = exports$1.SetTraceNotification = exports$1.TraceFormat = exports$1.TraceValues = exports$1.Trace = exports$1.NullLogger = exports$1.ProgressType = exports$1.ProgressToken = void 0; + var ral_1 = require_ral(); + var Is = require_is(); + var messages_1 = require_messages(); + var linkedMap_1 = require_linkedMap(); + var events_1 = require_events(); + var cancellation_1 = require_cancellation(); + var CancelNotification; + (function(CancelNotification2) { + CancelNotification2.type = new messages_1.NotificationType("$/cancelRequest"); + })(CancelNotification || (CancelNotification = {})); + var ProgressToken; + (function(ProgressToken2) { + function is(value) { + return typeof value === "string" || typeof value === "number"; + } + ProgressToken2.is = is; + })(ProgressToken || (exports$1.ProgressToken = ProgressToken = {})); + var ProgressNotification; + (function(ProgressNotification2) { + ProgressNotification2.type = new messages_1.NotificationType("$/progress"); + })(ProgressNotification || (ProgressNotification = {})); + var ProgressType = class { + constructor() { + } + }; + exports$1.ProgressType = ProgressType; + var StarRequestHandler; + (function(StarRequestHandler2) { + function is(value) { + return Is.func(value); + } + StarRequestHandler2.is = is; + })(StarRequestHandler || (StarRequestHandler = {})); + exports$1.NullLogger = Object.freeze({ + error: () => { + }, + warn: () => { + }, + info: () => { + }, + log: () => { + } + }); + var Trace; + (function(Trace2) { + Trace2[Trace2["Off"] = 0] = "Off"; + Trace2[Trace2["Messages"] = 1] = "Messages"; + Trace2[Trace2["Compact"] = 2] = "Compact"; + Trace2[Trace2["Verbose"] = 3] = "Verbose"; + })(Trace || (exports$1.Trace = Trace = {})); + var TraceValues; + (function(TraceValues2) { + TraceValues2.Off = "off"; + TraceValues2.Messages = "messages"; + TraceValues2.Compact = "compact"; + TraceValues2.Verbose = "verbose"; + })(TraceValues || (exports$1.TraceValues = TraceValues = {})); + (function(Trace2) { + function fromString(value) { + if (!Is.string(value)) { + return Trace2.Off; + } + value = value.toLowerCase(); + switch (value) { + case "off": + return Trace2.Off; + case "messages": + return Trace2.Messages; + case "compact": + return Trace2.Compact; + case "verbose": + return Trace2.Verbose; + default: + return Trace2.Off; + } + } + Trace2.fromString = fromString; + function toString(value) { + switch (value) { + case Trace2.Off: + return "off"; + case Trace2.Messages: + return "messages"; + case Trace2.Compact: + return "compact"; + case Trace2.Verbose: + return "verbose"; + default: + return "off"; + } + } + Trace2.toString = toString; + })(Trace || (exports$1.Trace = Trace = {})); + var TraceFormat; + (function(TraceFormat2) { + TraceFormat2["Text"] = "text"; + TraceFormat2["JSON"] = "json"; + })(TraceFormat || (exports$1.TraceFormat = TraceFormat = {})); + (function(TraceFormat2) { + function fromString(value) { + if (!Is.string(value)) { + return TraceFormat2.Text; + } + value = value.toLowerCase(); + if (value === "json") { + return TraceFormat2.JSON; + } else { + return TraceFormat2.Text; + } + } + TraceFormat2.fromString = fromString; + })(TraceFormat || (exports$1.TraceFormat = TraceFormat = {})); + var SetTraceNotification; + (function(SetTraceNotification2) { + SetTraceNotification2.type = new messages_1.NotificationType("$/setTrace"); + })(SetTraceNotification || (exports$1.SetTraceNotification = SetTraceNotification = {})); + var LogTraceNotification; + (function(LogTraceNotification2) { + LogTraceNotification2.type = new messages_1.NotificationType("$/logTrace"); + })(LogTraceNotification || (exports$1.LogTraceNotification = LogTraceNotification = {})); + var ConnectionErrors; + (function(ConnectionErrors2) { + ConnectionErrors2[ConnectionErrors2["Closed"] = 1] = "Closed"; + ConnectionErrors2[ConnectionErrors2["Disposed"] = 2] = "Disposed"; + ConnectionErrors2[ConnectionErrors2["AlreadyListening"] = 3] = "AlreadyListening"; + })(ConnectionErrors || (exports$1.ConnectionErrors = ConnectionErrors = {})); + var ConnectionError = class _ConnectionError extends Error { + constructor(code, message) { + super(message); + this.code = code; + Object.setPrototypeOf(this, _ConnectionError.prototype); + } + }; + exports$1.ConnectionError = ConnectionError; + var ConnectionStrategy; + (function(ConnectionStrategy2) { + function is(value) { + const candidate = value; + return candidate && Is.func(candidate.cancelUndispatched); + } + ConnectionStrategy2.is = is; + })(ConnectionStrategy || (exports$1.ConnectionStrategy = ConnectionStrategy = {})); + var IdCancellationReceiverStrategy; + (function(IdCancellationReceiverStrategy2) { + function is(value) { + const candidate = value; + return candidate && (candidate.kind === void 0 || candidate.kind === "id") && Is.func(candidate.createCancellationTokenSource) && (candidate.dispose === void 0 || Is.func(candidate.dispose)); + } + IdCancellationReceiverStrategy2.is = is; + })(IdCancellationReceiverStrategy || (exports$1.IdCancellationReceiverStrategy = IdCancellationReceiverStrategy = {})); + var RequestCancellationReceiverStrategy; + (function(RequestCancellationReceiverStrategy2) { + function is(value) { + const candidate = value; + return candidate && candidate.kind === "request" && Is.func(candidate.createCancellationTokenSource) && (candidate.dispose === void 0 || Is.func(candidate.dispose)); + } + RequestCancellationReceiverStrategy2.is = is; + })(RequestCancellationReceiverStrategy || (exports$1.RequestCancellationReceiverStrategy = RequestCancellationReceiverStrategy = {})); + var CancellationReceiverStrategy; + (function(CancellationReceiverStrategy2) { + CancellationReceiverStrategy2.Message = Object.freeze({ + createCancellationTokenSource(_) { + return new cancellation_1.CancellationTokenSource(); + } + }); + function is(value) { + return IdCancellationReceiverStrategy.is(value) || RequestCancellationReceiverStrategy.is(value); + } + CancellationReceiverStrategy2.is = is; + })(CancellationReceiverStrategy || (exports$1.CancellationReceiverStrategy = CancellationReceiverStrategy = {})); + var CancellationSenderStrategy; + (function(CancellationSenderStrategy2) { + CancellationSenderStrategy2.Message = Object.freeze({ + sendCancellation(conn, id) { + return conn.sendNotification(CancelNotification.type, { id }); + }, + cleanup(_) { + } + }); + function is(value) { + const candidate = value; + return candidate && Is.func(candidate.sendCancellation) && Is.func(candidate.cleanup); + } + CancellationSenderStrategy2.is = is; + })(CancellationSenderStrategy || (exports$1.CancellationSenderStrategy = CancellationSenderStrategy = {})); + var CancellationStrategy; + (function(CancellationStrategy2) { + CancellationStrategy2.Message = Object.freeze({ + receiver: CancellationReceiverStrategy.Message, + sender: CancellationSenderStrategy.Message + }); + function is(value) { + const candidate = value; + return candidate && CancellationReceiverStrategy.is(candidate.receiver) && CancellationSenderStrategy.is(candidate.sender); + } + CancellationStrategy2.is = is; + })(CancellationStrategy || (exports$1.CancellationStrategy = CancellationStrategy = {})); + var MessageStrategy; + (function(MessageStrategy2) { + function is(value) { + const candidate = value; + return candidate && Is.func(candidate.handleMessage); + } + MessageStrategy2.is = is; + })(MessageStrategy || (exports$1.MessageStrategy = MessageStrategy = {})); + var ConnectionOptions; + (function(ConnectionOptions2) { + function is(value) { + const candidate = value; + return candidate && (CancellationStrategy.is(candidate.cancellationStrategy) || ConnectionStrategy.is(candidate.connectionStrategy) || MessageStrategy.is(candidate.messageStrategy)); + } + ConnectionOptions2.is = is; + })(ConnectionOptions || (exports$1.ConnectionOptions = ConnectionOptions = {})); + var ConnectionState; + (function(ConnectionState2) { + ConnectionState2[ConnectionState2["New"] = 1] = "New"; + ConnectionState2[ConnectionState2["Listening"] = 2] = "Listening"; + ConnectionState2[ConnectionState2["Closed"] = 3] = "Closed"; + ConnectionState2[ConnectionState2["Disposed"] = 4] = "Disposed"; + })(ConnectionState || (ConnectionState = {})); + function createMessageConnection2(messageReader, messageWriter, _logger, options) { + const logger = _logger !== void 0 ? _logger : exports$1.NullLogger; + let sequenceNumber = 0; + let notificationSequenceNumber = 0; + let unknownResponseSequenceNumber = 0; + const version = "2.0"; + let starRequestHandler = void 0; + const requestHandlers = /* @__PURE__ */ new Map(); + let starNotificationHandler = void 0; + const notificationHandlers = /* @__PURE__ */ new Map(); + const progressHandlers = /* @__PURE__ */ new Map(); + let timer; + let messageQueue = new linkedMap_1.LinkedMap(); + let responsePromises = /* @__PURE__ */ new Map(); + let knownCanceledRequests = /* @__PURE__ */ new Set(); + let requestTokens = /* @__PURE__ */ new Map(); + let trace = Trace.Off; + let traceFormat = TraceFormat.Text; + let tracer; + let state = ConnectionState.New; + const errorEmitter = new events_1.Emitter(); + const closeEmitter = new events_1.Emitter(); + const unhandledNotificationEmitter = new events_1.Emitter(); + const unhandledProgressEmitter = new events_1.Emitter(); + const disposeEmitter = new events_1.Emitter(); + const cancellationStrategy = options && options.cancellationStrategy ? options.cancellationStrategy : CancellationStrategy.Message; + function createRequestQueueKey(id) { + if (id === null) { + throw new Error(`Can't send requests with id null since the response can't be correlated.`); + } + return "req-" + id.toString(); + } + function createResponseQueueKey(id) { + if (id === null) { + return "res-unknown-" + (++unknownResponseSequenceNumber).toString(); + } else { + return "res-" + id.toString(); + } + } + function createNotificationQueueKey() { + return "not-" + (++notificationSequenceNumber).toString(); + } + function addMessageToQueue(queue, message) { + if (messages_1.Message.isRequest(message)) { + queue.set(createRequestQueueKey(message.id), message); + } else if (messages_1.Message.isResponse(message)) { + queue.set(createResponseQueueKey(message.id), message); + } else { + queue.set(createNotificationQueueKey(), message); + } + } + function cancelUndispatched(_message) { + return void 0; + } + function isListening() { + return state === ConnectionState.Listening; + } + function isClosed() { + return state === ConnectionState.Closed; + } + function isDisposed() { + return state === ConnectionState.Disposed; + } + function closeHandler() { + if (state === ConnectionState.New || state === ConnectionState.Listening) { + state = ConnectionState.Closed; + closeEmitter.fire(void 0); + } + } + function readErrorHandler(error) { + errorEmitter.fire([error, void 0, void 0]); + } + function writeErrorHandler(data) { + errorEmitter.fire(data); + } + messageReader.onClose(closeHandler); + messageReader.onError(readErrorHandler); + messageWriter.onClose(closeHandler); + messageWriter.onError(writeErrorHandler); + function triggerMessageQueue() { + if (timer || messageQueue.size === 0) { + return; + } + timer = (0, ral_1.default)().timer.setImmediate(() => { + timer = void 0; + processMessageQueue(); + }); + } + function handleMessage(message) { + if (messages_1.Message.isRequest(message)) { + handleRequest(message); + } else if (messages_1.Message.isNotification(message)) { + handleNotification(message); + } else if (messages_1.Message.isResponse(message)) { + handleResponse(message); + } else { + handleInvalidMessage(message); + } + } + function processMessageQueue() { + if (messageQueue.size === 0) { + return; + } + const message = messageQueue.shift(); + try { + const messageStrategy = options?.messageStrategy; + if (MessageStrategy.is(messageStrategy)) { + messageStrategy.handleMessage(message, handleMessage); + } else { + handleMessage(message); + } + } finally { + triggerMessageQueue(); + } + } + const callback = (message) => { + try { + if (messages_1.Message.isNotification(message) && message.method === CancelNotification.type.method) { + const cancelId = message.params.id; + const key = createRequestQueueKey(cancelId); + const toCancel = messageQueue.get(key); + if (messages_1.Message.isRequest(toCancel)) { + const strategy = options?.connectionStrategy; + const response = strategy && strategy.cancelUndispatched ? strategy.cancelUndispatched(toCancel, cancelUndispatched) : cancelUndispatched(toCancel); + if (response && (response.error !== void 0 || response.result !== void 0)) { + messageQueue.delete(key); + requestTokens.delete(cancelId); + response.id = toCancel.id; + traceSendingResponse(response, message.method, Date.now()); + messageWriter.write(response).catch(() => logger.error(`Sending response for canceled message failed.`)); + return; + } + } + const cancellationToken = requestTokens.get(cancelId); + if (cancellationToken !== void 0) { + cancellationToken.cancel(); + traceReceivedNotification(message); + return; + } else { + knownCanceledRequests.add(cancelId); + } + } + addMessageToQueue(messageQueue, message); + } finally { + triggerMessageQueue(); + } + }; + function handleRequest(requestMessage) { + if (isDisposed()) { + return; + } + function reply(resultOrError, method, startTime2) { + const message = { + jsonrpc: version, + id: requestMessage.id + }; + if (resultOrError instanceof messages_1.ResponseError) { + message.error = resultOrError.toJson(); + } else { + message.result = resultOrError === void 0 ? null : resultOrError; + } + traceSendingResponse(message, method, startTime2); + messageWriter.write(message).catch(() => logger.error(`Sending response failed.`)); + } + function replyError(error, method, startTime2) { + const message = { + jsonrpc: version, + id: requestMessage.id, + error: error.toJson() + }; + traceSendingResponse(message, method, startTime2); + messageWriter.write(message).catch(() => logger.error(`Sending response failed.`)); + } + function replySuccess(result, method, startTime2) { + if (result === void 0) { + result = null; + } + const message = { + jsonrpc: version, + id: requestMessage.id, + result + }; + traceSendingResponse(message, method, startTime2); + messageWriter.write(message).catch(() => logger.error(`Sending response failed.`)); + } + traceReceivedRequest(requestMessage); + const element = requestHandlers.get(requestMessage.method); + let type; + let requestHandler; + if (element) { + type = element.type; + requestHandler = element.handler; + } + const startTime = Date.now(); + if (requestHandler || starRequestHandler) { + const tokenKey = requestMessage.id ?? String(Date.now()); + const cancellationSource = IdCancellationReceiverStrategy.is(cancellationStrategy.receiver) ? cancellationStrategy.receiver.createCancellationTokenSource(tokenKey) : cancellationStrategy.receiver.createCancellationTokenSource(requestMessage); + if (requestMessage.id !== null && knownCanceledRequests.has(requestMessage.id)) { + cancellationSource.cancel(); + } + if (requestMessage.id !== null) { + requestTokens.set(tokenKey, cancellationSource); + } + try { + let handlerResult; + if (requestHandler) { + if (requestMessage.params === void 0) { + if (type !== void 0 && type.numberOfParams !== 0) { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InvalidParams, `Request ${requestMessage.method} defines ${type.numberOfParams} params but received none.`), requestMessage.method, startTime); + return; + } + handlerResult = requestHandler(cancellationSource.token); + } else if (Array.isArray(requestMessage.params)) { + if (type !== void 0 && type.parameterStructures === messages_1.ParameterStructures.byName) { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InvalidParams, `Request ${requestMessage.method} defines parameters by name but received parameters by position`), requestMessage.method, startTime); + return; + } + handlerResult = requestHandler(...requestMessage.params, cancellationSource.token); + } else { + if (type !== void 0 && type.parameterStructures === messages_1.ParameterStructures.byPosition) { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InvalidParams, `Request ${requestMessage.method} defines parameters by position but received parameters by name`), requestMessage.method, startTime); + return; + } + handlerResult = requestHandler(requestMessage.params, cancellationSource.token); + } + } else if (starRequestHandler) { + handlerResult = starRequestHandler(requestMessage.method, requestMessage.params, cancellationSource.token); + } + const promise = handlerResult; + if (!handlerResult) { + requestTokens.delete(tokenKey); + replySuccess(handlerResult, requestMessage.method, startTime); + } else if (promise.then) { + promise.then((resultOrError) => { + requestTokens.delete(tokenKey); + reply(resultOrError, requestMessage.method, startTime); + }, (error) => { + requestTokens.delete(tokenKey); + if (error instanceof messages_1.ResponseError) { + replyError(error, requestMessage.method, startTime); + } else if (error && Is.string(error.message)) { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime); + } else { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime); + } + }); + } else { + requestTokens.delete(tokenKey); + reply(handlerResult, requestMessage.method, startTime); + } + } catch (error) { + requestTokens.delete(tokenKey); + if (error instanceof messages_1.ResponseError) { + reply(error, requestMessage.method, startTime); + } else if (error && Is.string(error.message)) { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`), requestMessage.method, startTime); + } else { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`), requestMessage.method, startTime); + } + } + } else { + replyError(new messages_1.ResponseError(messages_1.ErrorCodes.MethodNotFound, `Unhandled method ${requestMessage.method}`), requestMessage.method, startTime); + } + } + function handleResponse(responseMessage) { + if (isDisposed()) { + return; + } + if (responseMessage.id === null) { + if (responseMessage.error) { + logger.error(`Received response message without id: Error is: +${JSON.stringify(responseMessage.error, void 0, 4)}`); + } else { + logger.error(`Received response message without id. No further error information provided.`); + } + } else { + const key = responseMessage.id; + const responsePromise = responsePromises.get(key); + traceReceivedResponse(responseMessage, responsePromise); + if (responsePromise !== void 0) { + responsePromises.delete(key); + try { + if (responseMessage.error) { + const error = responseMessage.error; + responsePromise.reject(new messages_1.ResponseError(error.code, error.message, error.data)); + } else if (responseMessage.result !== void 0) { + responsePromise.resolve(responseMessage.result); + } else { + throw new Error("Should never happen."); + } + } catch (error) { + if (error.message) { + logger.error(`Response handler '${responsePromise.method}' failed with message: ${error.message}`); + } else { + logger.error(`Response handler '${responsePromise.method}' failed unexpectedly.`); + } + } + } + } + } + function handleNotification(message) { + if (isDisposed()) { + return; + } + let type = void 0; + let notificationHandler; + if (message.method === CancelNotification.type.method) { + const cancelId = message.params.id; + knownCanceledRequests.delete(cancelId); + traceReceivedNotification(message); + return; + } else { + const element = notificationHandlers.get(message.method); + if (element) { + notificationHandler = element.handler; + type = element.type; + } + } + if (notificationHandler || starNotificationHandler) { + try { + traceReceivedNotification(message); + if (notificationHandler) { + if (message.params === void 0) { + if (type !== void 0) { + if (type.numberOfParams !== 0 && type.parameterStructures !== messages_1.ParameterStructures.byName) { + logger.error(`Notification ${message.method} defines ${type.numberOfParams} params but received none.`); + } + } + notificationHandler(); + } else if (Array.isArray(message.params)) { + const params = message.params; + if (message.method === ProgressNotification.type.method && params.length === 2 && ProgressToken.is(params[0])) { + notificationHandler({ token: params[0], value: params[1] }); + } else { + if (type !== void 0) { + if (type.parameterStructures === messages_1.ParameterStructures.byName) { + logger.error(`Notification ${message.method} defines parameters by name but received parameters by position`); + } + if (type.numberOfParams !== message.params.length) { + logger.error(`Notification ${message.method} defines ${type.numberOfParams} params but received ${params.length} arguments`); + } + } + notificationHandler(...params); + } + } else { + if (type !== void 0 && type.parameterStructures === messages_1.ParameterStructures.byPosition) { + logger.error(`Notification ${message.method} defines parameters by position but received parameters by name`); + } + notificationHandler(message.params); + } + } else if (starNotificationHandler) { + starNotificationHandler(message.method, message.params); + } + } catch (error) { + if (error.message) { + logger.error(`Notification handler '${message.method}' failed with message: ${error.message}`); + } else { + logger.error(`Notification handler '${message.method}' failed unexpectedly.`); + } + } + } else { + unhandledNotificationEmitter.fire(message); + } + } + function handleInvalidMessage(message) { + if (!message) { + logger.error("Received empty message."); + return; + } + logger.error(`Received message which is neither a response nor a notification message: +${JSON.stringify(message, null, 4)}`); + const responseMessage = message; + if (Is.string(responseMessage.id) || Is.number(responseMessage.id)) { + const key = responseMessage.id; + const responseHandler = responsePromises.get(key); + if (responseHandler) { + responseHandler.reject(new Error("The received response has neither a result nor an error property.")); + } + } + } + function stringifyTrace(params) { + if (params === void 0 || params === null) { + return void 0; + } + switch (trace) { + case Trace.Verbose: + return JSON.stringify(params, null, 4); + case Trace.Compact: + return JSON.stringify(params); + default: + return void 0; + } + } + function traceSendingRequest(message) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = void 0; + if ((trace === Trace.Verbose || trace === Trace.Compact) && message.params) { + data = `Params: ${stringifyTrace(message.params)} + +`; + } + tracer.log(`Sending request '${message.method} - (${message.id})'.`, data); + } else { + logLSPMessage("send-request", message); + } + } + function traceSendingNotification(message) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = void 0; + if (trace === Trace.Verbose || trace === Trace.Compact) { + if (message.params) { + data = `Params: ${stringifyTrace(message.params)} + +`; + } else { + data = "No parameters provided.\n\n"; + } + } + tracer.log(`Sending notification '${message.method}'.`, data); + } else { + logLSPMessage("send-notification", message); + } + } + function traceSendingResponse(message, method, startTime) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = void 0; + if (trace === Trace.Verbose || trace === Trace.Compact) { + if (message.error && message.error.data) { + data = `Error data: ${stringifyTrace(message.error.data)} + +`; + } else { + if (message.result) { + data = `Result: ${stringifyTrace(message.result)} + +`; + } else if (message.error === void 0) { + data = "No result returned.\n\n"; + } + } + } + tracer.log(`Sending response '${method} - (${message.id})'. Processing request took ${Date.now() - startTime}ms`, data); + } else { + logLSPMessage("send-response", message); + } + } + function traceReceivedRequest(message) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = void 0; + if ((trace === Trace.Verbose || trace === Trace.Compact) && message.params) { + data = `Params: ${stringifyTrace(message.params)} + +`; + } + tracer.log(`Received request '${message.method} - (${message.id})'.`, data); + } else { + logLSPMessage("receive-request", message); + } + } + function traceReceivedNotification(message) { + if (trace === Trace.Off || !tracer || message.method === LogTraceNotification.type.method) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = void 0; + if (trace === Trace.Verbose || trace === Trace.Compact) { + if (message.params) { + data = `Params: ${stringifyTrace(message.params)} + +`; + } else { + data = "No parameters provided.\n\n"; + } + } + tracer.log(`Received notification '${message.method}'.`, data); + } else { + logLSPMessage("receive-notification", message); + } + } + function traceReceivedResponse(message, responsePromise) { + if (trace === Trace.Off || !tracer) { + return; + } + if (traceFormat === TraceFormat.Text) { + let data = void 0; + if (trace === Trace.Verbose || trace === Trace.Compact) { + if (message.error && message.error.data) { + data = `Error data: ${stringifyTrace(message.error.data)} + +`; + } else { + if (message.result) { + data = `Result: ${stringifyTrace(message.result)} + +`; + } else if (message.error === void 0) { + data = "No result returned.\n\n"; + } + } + } + if (responsePromise) { + const error = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : ""; + tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error}`, data); + } else { + tracer.log(`Received response ${message.id} without active response promise.`, data); + } + } else { + logLSPMessage("receive-response", message); + } + } + function logLSPMessage(type, message) { + if (!tracer || trace === Trace.Off) { + return; + } + const lspMessage = { + isLSPMessage: true, + type, + message, + timestamp: Date.now() + }; + tracer.log(lspMessage); + } + function throwIfClosedOrDisposed() { + if (isClosed()) { + throw new ConnectionError(ConnectionErrors.Closed, "Connection is closed."); + } + if (isDisposed()) { + throw new ConnectionError(ConnectionErrors.Disposed, "Connection is disposed."); + } + } + function throwIfListening() { + if (isListening()) { + throw new ConnectionError(ConnectionErrors.AlreadyListening, "Connection is already listening"); + } + } + function throwIfNotListening() { + if (!isListening()) { + throw new Error("Call listen() first."); + } + } + function undefinedToNull(param) { + if (param === void 0) { + return null; + } else { + return param; + } + } + function nullToUndefined(param) { + if (param === null) { + return void 0; + } else { + return param; + } + } + function isNamedParam(param) { + return param !== void 0 && param !== null && !Array.isArray(param) && typeof param === "object"; + } + function computeSingleParam(parameterStructures, param) { + switch (parameterStructures) { + case messages_1.ParameterStructures.auto: + if (isNamedParam(param)) { + return nullToUndefined(param); + } else { + return [undefinedToNull(param)]; + } + case messages_1.ParameterStructures.byName: + if (!isNamedParam(param)) { + throw new Error(`Received parameters by name but param is not an object literal.`); + } + return nullToUndefined(param); + case messages_1.ParameterStructures.byPosition: + return [undefinedToNull(param)]; + default: + throw new Error(`Unknown parameter structure ${parameterStructures.toString()}`); + } + } + function computeMessageParams(type, params) { + let result; + const numberOfParams = type.numberOfParams; + switch (numberOfParams) { + case 0: + result = void 0; + break; + case 1: + result = computeSingleParam(type.parameterStructures, params[0]); + break; + default: + result = []; + for (let i = 0; i < params.length && i < numberOfParams; i++) { + result.push(undefinedToNull(params[i])); + } + if (params.length < numberOfParams) { + for (let i = params.length; i < numberOfParams; i++) { + result.push(null); + } + } + break; + } + return result; + } + const connection = { + sendNotification: (type, ...args) => { + throwIfClosedOrDisposed(); + let method; + let messageParams; + if (Is.string(type)) { + method = type; + const first = args[0]; + let paramStart = 0; + let parameterStructures = messages_1.ParameterStructures.auto; + if (messages_1.ParameterStructures.is(first)) { + paramStart = 1; + parameterStructures = first; + } + let paramEnd = args.length; + const numberOfParams = paramEnd - paramStart; + switch (numberOfParams) { + case 0: + messageParams = void 0; + break; + case 1: + messageParams = computeSingleParam(parameterStructures, args[paramStart]); + break; + default: + if (parameterStructures === messages_1.ParameterStructures.byName) { + throw new Error(`Received ${numberOfParams} parameters for 'by Name' notification parameter structure.`); + } + messageParams = args.slice(paramStart, paramEnd).map((value) => undefinedToNull(value)); + break; + } + } else { + const params = args; + method = type.method; + messageParams = computeMessageParams(type, params); + } + const notificationMessage = { + jsonrpc: version, + method, + params: messageParams + }; + traceSendingNotification(notificationMessage); + return messageWriter.write(notificationMessage).catch((error) => { + logger.error(`Sending notification failed.`); + throw error; + }); + }, + onNotification: (type, handler) => { + throwIfClosedOrDisposed(); + let method; + if (Is.func(type)) { + starNotificationHandler = type; + } else if (handler) { + if (Is.string(type)) { + method = type; + notificationHandlers.set(type, { type: void 0, handler }); + } else { + method = type.method; + notificationHandlers.set(type.method, { type, handler }); + } + } + return { + dispose: () => { + if (method !== void 0) { + notificationHandlers.delete(method); + } else { + starNotificationHandler = void 0; + } + } + }; + }, + onProgress: (_type, token, handler) => { + if (progressHandlers.has(token)) { + throw new Error(`Progress handler for token ${token} already registered`); + } + progressHandlers.set(token, handler); + return { + dispose: () => { + progressHandlers.delete(token); + } + }; + }, + sendProgress: (_type, token, value) => { + return connection.sendNotification(ProgressNotification.type, { token, value }); + }, + onUnhandledProgress: unhandledProgressEmitter.event, + sendRequest: (type, ...args) => { + throwIfClosedOrDisposed(); + throwIfNotListening(); + let method; + let messageParams; + let token = void 0; + if (Is.string(type)) { + method = type; + const first = args[0]; + const last = args[args.length - 1]; + let paramStart = 0; + let parameterStructures = messages_1.ParameterStructures.auto; + if (messages_1.ParameterStructures.is(first)) { + paramStart = 1; + parameterStructures = first; + } + let paramEnd = args.length; + if (cancellation_1.CancellationToken.is(last)) { + paramEnd = paramEnd - 1; + token = last; + } + const numberOfParams = paramEnd - paramStart; + switch (numberOfParams) { + case 0: + messageParams = void 0; + break; + case 1: + messageParams = computeSingleParam(parameterStructures, args[paramStart]); + break; + default: + if (parameterStructures === messages_1.ParameterStructures.byName) { + throw new Error(`Received ${numberOfParams} parameters for 'by Name' request parameter structure.`); + } + messageParams = args.slice(paramStart, paramEnd).map((value) => undefinedToNull(value)); + break; + } + } else { + const params = args; + method = type.method; + messageParams = computeMessageParams(type, params); + const numberOfParams = type.numberOfParams; + token = cancellation_1.CancellationToken.is(params[numberOfParams]) ? params[numberOfParams] : void 0; + } + const id = sequenceNumber++; + let disposable; + if (token) { + disposable = token.onCancellationRequested(() => { + const p = cancellationStrategy.sender.sendCancellation(connection, id); + if (p === void 0) { + logger.log(`Received no promise from cancellation strategy when cancelling id ${id}`); + return Promise.resolve(); + } else { + return p.catch(() => { + logger.log(`Sending cancellation messages for id ${id} failed`); + }); + } + }); + } + const requestMessage = { + jsonrpc: version, + id, + method, + params: messageParams + }; + traceSendingRequest(requestMessage); + if (typeof cancellationStrategy.sender.enableCancellation === "function") { + cancellationStrategy.sender.enableCancellation(requestMessage); + } + return new Promise(async (resolve, reject) => { + const resolveWithCleanup = (r) => { + resolve(r); + cancellationStrategy.sender.cleanup(id); + disposable?.dispose(); + }; + const rejectWithCleanup = (r) => { + reject(r); + cancellationStrategy.sender.cleanup(id); + disposable?.dispose(); + }; + const responsePromise = { method, timerStart: Date.now(), resolve: resolveWithCleanup, reject: rejectWithCleanup }; + try { + responsePromises.set(id, responsePromise); + await messageWriter.write(requestMessage); + } catch (error) { + responsePromises.delete(id); + responsePromise.reject(new messages_1.ResponseError(messages_1.ErrorCodes.MessageWriteError, error.message ? error.message : "Unknown reason")); + logger.error(`Sending request failed.`); + throw error; + } + }); + }, + onRequest: (type, handler) => { + throwIfClosedOrDisposed(); + let method = null; + if (StarRequestHandler.is(type)) { + method = void 0; + starRequestHandler = type; + } else if (Is.string(type)) { + method = null; + if (handler !== void 0) { + method = type; + requestHandlers.set(type, { handler, type: void 0 }); + } + } else { + if (handler !== void 0) { + method = type.method; + requestHandlers.set(type.method, { type, handler }); + } + } + return { + dispose: () => { + if (method === null) { + return; + } + if (method !== void 0) { + requestHandlers.delete(method); + } else { + starRequestHandler = void 0; + } + } + }; + }, + hasPendingResponse: () => { + return responsePromises.size > 0; + }, + trace: async (_value, _tracer, sendNotificationOrTraceOptions) => { + let _sendNotification = false; + let _traceFormat = TraceFormat.Text; + if (sendNotificationOrTraceOptions !== void 0) { + if (Is.boolean(sendNotificationOrTraceOptions)) { + _sendNotification = sendNotificationOrTraceOptions; + } else { + _sendNotification = sendNotificationOrTraceOptions.sendNotification || false; + _traceFormat = sendNotificationOrTraceOptions.traceFormat || TraceFormat.Text; + } + } + trace = _value; + traceFormat = _traceFormat; + if (trace === Trace.Off) { + tracer = void 0; + } else { + tracer = _tracer; + } + if (_sendNotification && !isClosed() && !isDisposed()) { + await connection.sendNotification(SetTraceNotification.type, { value: Trace.toString(_value) }); + } + }, + onError: errorEmitter.event, + onClose: closeEmitter.event, + onUnhandledNotification: unhandledNotificationEmitter.event, + onDispose: disposeEmitter.event, + end: () => { + messageWriter.end(); + }, + dispose: () => { + if (isDisposed()) { + return; + } + state = ConnectionState.Disposed; + disposeEmitter.fire(void 0); + const error = new messages_1.ResponseError(messages_1.ErrorCodes.PendingResponseRejected, "Pending response rejected since connection got disposed"); + for (const promise of responsePromises.values()) { + promise.reject(error); + } + responsePromises = /* @__PURE__ */ new Map(); + requestTokens = /* @__PURE__ */ new Map(); + knownCanceledRequests = /* @__PURE__ */ new Set(); + messageQueue = new linkedMap_1.LinkedMap(); + if (Is.func(messageWriter.dispose)) { + messageWriter.dispose(); + } + if (Is.func(messageReader.dispose)) { + messageReader.dispose(); + } + }, + listen: () => { + throwIfClosedOrDisposed(); + throwIfListening(); + state = ConnectionState.Listening; + messageReader.listen(callback); + }, + inspect: () => { + (0, ral_1.default)().console.log("inspect"); + } + }; + connection.onNotification(LogTraceNotification.type, (params) => { + if (trace === Trace.Off || !tracer) { + return; + } + const verbose = trace === Trace.Verbose || trace === Trace.Compact; + tracer.log(params.message, verbose ? params.verbose : void 0); + }); + connection.onNotification(ProgressNotification.type, (params) => { + const handler = progressHandlers.get(params.token); + if (handler) { + handler(params.value); + } else { + unhandledProgressEmitter.fire(params); + } + }); + return connection; + } + exports$1.createMessageConnection = createMessageConnection2; + } +}); + +// node_modules/vscode-jsonrpc/lib/common/api.js +var require_api = __commonJS({ + "node_modules/vscode-jsonrpc/lib/common/api.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.ProgressType = exports$1.ProgressToken = exports$1.createMessageConnection = exports$1.NullLogger = exports$1.ConnectionOptions = exports$1.ConnectionStrategy = exports$1.AbstractMessageBuffer = exports$1.WriteableStreamMessageWriter = exports$1.AbstractMessageWriter = exports$1.MessageWriter = exports$1.ReadableStreamMessageReader = exports$1.AbstractMessageReader = exports$1.MessageReader = exports$1.SharedArrayReceiverStrategy = exports$1.SharedArraySenderStrategy = exports$1.CancellationToken = exports$1.CancellationTokenSource = exports$1.Emitter = exports$1.Event = exports$1.Disposable = exports$1.LRUCache = exports$1.Touch = exports$1.LinkedMap = exports$1.ParameterStructures = exports$1.NotificationType9 = exports$1.NotificationType8 = exports$1.NotificationType7 = exports$1.NotificationType6 = exports$1.NotificationType5 = exports$1.NotificationType4 = exports$1.NotificationType3 = exports$1.NotificationType2 = exports$1.NotificationType1 = exports$1.NotificationType0 = exports$1.NotificationType = exports$1.ErrorCodes = exports$1.ResponseError = exports$1.RequestType9 = exports$1.RequestType8 = exports$1.RequestType7 = exports$1.RequestType6 = exports$1.RequestType5 = exports$1.RequestType4 = exports$1.RequestType3 = exports$1.RequestType2 = exports$1.RequestType1 = exports$1.RequestType0 = exports$1.RequestType = exports$1.Message = exports$1.RAL = void 0; + exports$1.MessageStrategy = exports$1.CancellationStrategy = exports$1.CancellationSenderStrategy = exports$1.CancellationReceiverStrategy = exports$1.ConnectionError = exports$1.ConnectionErrors = exports$1.LogTraceNotification = exports$1.SetTraceNotification = exports$1.TraceFormat = exports$1.TraceValues = exports$1.Trace = void 0; + var messages_1 = require_messages(); + Object.defineProperty(exports$1, "Message", { enumerable: true, get: function() { + return messages_1.Message; + } }); + Object.defineProperty(exports$1, "RequestType", { enumerable: true, get: function() { + return messages_1.RequestType; + } }); + Object.defineProperty(exports$1, "RequestType0", { enumerable: true, get: function() { + return messages_1.RequestType0; + } }); + Object.defineProperty(exports$1, "RequestType1", { enumerable: true, get: function() { + return messages_1.RequestType1; + } }); + Object.defineProperty(exports$1, "RequestType2", { enumerable: true, get: function() { + return messages_1.RequestType2; + } }); + Object.defineProperty(exports$1, "RequestType3", { enumerable: true, get: function() { + return messages_1.RequestType3; + } }); + Object.defineProperty(exports$1, "RequestType4", { enumerable: true, get: function() { + return messages_1.RequestType4; + } }); + Object.defineProperty(exports$1, "RequestType5", { enumerable: true, get: function() { + return messages_1.RequestType5; + } }); + Object.defineProperty(exports$1, "RequestType6", { enumerable: true, get: function() { + return messages_1.RequestType6; + } }); + Object.defineProperty(exports$1, "RequestType7", { enumerable: true, get: function() { + return messages_1.RequestType7; + } }); + Object.defineProperty(exports$1, "RequestType8", { enumerable: true, get: function() { + return messages_1.RequestType8; + } }); + Object.defineProperty(exports$1, "RequestType9", { enumerable: true, get: function() { + return messages_1.RequestType9; + } }); + Object.defineProperty(exports$1, "ResponseError", { enumerable: true, get: function() { + return messages_1.ResponseError; + } }); + Object.defineProperty(exports$1, "ErrorCodes", { enumerable: true, get: function() { + return messages_1.ErrorCodes; + } }); + Object.defineProperty(exports$1, "NotificationType", { enumerable: true, get: function() { + return messages_1.NotificationType; + } }); + Object.defineProperty(exports$1, "NotificationType0", { enumerable: true, get: function() { + return messages_1.NotificationType0; + } }); + Object.defineProperty(exports$1, "NotificationType1", { enumerable: true, get: function() { + return messages_1.NotificationType1; + } }); + Object.defineProperty(exports$1, "NotificationType2", { enumerable: true, get: function() { + return messages_1.NotificationType2; + } }); + Object.defineProperty(exports$1, "NotificationType3", { enumerable: true, get: function() { + return messages_1.NotificationType3; + } }); + Object.defineProperty(exports$1, "NotificationType4", { enumerable: true, get: function() { + return messages_1.NotificationType4; + } }); + Object.defineProperty(exports$1, "NotificationType5", { enumerable: true, get: function() { + return messages_1.NotificationType5; + } }); + Object.defineProperty(exports$1, "NotificationType6", { enumerable: true, get: function() { + return messages_1.NotificationType6; + } }); + Object.defineProperty(exports$1, "NotificationType7", { enumerable: true, get: function() { + return messages_1.NotificationType7; + } }); + Object.defineProperty(exports$1, "NotificationType8", { enumerable: true, get: function() { + return messages_1.NotificationType8; + } }); + Object.defineProperty(exports$1, "NotificationType9", { enumerable: true, get: function() { + return messages_1.NotificationType9; + } }); + Object.defineProperty(exports$1, "ParameterStructures", { enumerable: true, get: function() { + return messages_1.ParameterStructures; + } }); + var linkedMap_1 = require_linkedMap(); + Object.defineProperty(exports$1, "LinkedMap", { enumerable: true, get: function() { + return linkedMap_1.LinkedMap; + } }); + Object.defineProperty(exports$1, "LRUCache", { enumerable: true, get: function() { + return linkedMap_1.LRUCache; + } }); + Object.defineProperty(exports$1, "Touch", { enumerable: true, get: function() { + return linkedMap_1.Touch; + } }); + var disposable_1 = require_disposable(); + Object.defineProperty(exports$1, "Disposable", { enumerable: true, get: function() { + return disposable_1.Disposable; + } }); + var events_1 = require_events(); + Object.defineProperty(exports$1, "Event", { enumerable: true, get: function() { + return events_1.Event; + } }); + Object.defineProperty(exports$1, "Emitter", { enumerable: true, get: function() { + return events_1.Emitter; + } }); + var cancellation_1 = require_cancellation(); + Object.defineProperty(exports$1, "CancellationTokenSource", { enumerable: true, get: function() { + return cancellation_1.CancellationTokenSource; + } }); + Object.defineProperty(exports$1, "CancellationToken", { enumerable: true, get: function() { + return cancellation_1.CancellationToken; + } }); + var sharedArrayCancellation_1 = require_sharedArrayCancellation(); + Object.defineProperty(exports$1, "SharedArraySenderStrategy", { enumerable: true, get: function() { + return sharedArrayCancellation_1.SharedArraySenderStrategy; + } }); + Object.defineProperty(exports$1, "SharedArrayReceiverStrategy", { enumerable: true, get: function() { + return sharedArrayCancellation_1.SharedArrayReceiverStrategy; + } }); + var messageReader_1 = require_messageReader(); + Object.defineProperty(exports$1, "MessageReader", { enumerable: true, get: function() { + return messageReader_1.MessageReader; + } }); + Object.defineProperty(exports$1, "AbstractMessageReader", { enumerable: true, get: function() { + return messageReader_1.AbstractMessageReader; + } }); + Object.defineProperty(exports$1, "ReadableStreamMessageReader", { enumerable: true, get: function() { + return messageReader_1.ReadableStreamMessageReader; + } }); + var messageWriter_1 = require_messageWriter(); + Object.defineProperty(exports$1, "MessageWriter", { enumerable: true, get: function() { + return messageWriter_1.MessageWriter; + } }); + Object.defineProperty(exports$1, "AbstractMessageWriter", { enumerable: true, get: function() { + return messageWriter_1.AbstractMessageWriter; + } }); + Object.defineProperty(exports$1, "WriteableStreamMessageWriter", { enumerable: true, get: function() { + return messageWriter_1.WriteableStreamMessageWriter; + } }); + var messageBuffer_1 = require_messageBuffer(); + Object.defineProperty(exports$1, "AbstractMessageBuffer", { enumerable: true, get: function() { + return messageBuffer_1.AbstractMessageBuffer; + } }); + var connection_1 = require_connection(); + Object.defineProperty(exports$1, "ConnectionStrategy", { enumerable: true, get: function() { + return connection_1.ConnectionStrategy; + } }); + Object.defineProperty(exports$1, "ConnectionOptions", { enumerable: true, get: function() { + return connection_1.ConnectionOptions; + } }); + Object.defineProperty(exports$1, "NullLogger", { enumerable: true, get: function() { + return connection_1.NullLogger; + } }); + Object.defineProperty(exports$1, "createMessageConnection", { enumerable: true, get: function() { + return connection_1.createMessageConnection; + } }); + Object.defineProperty(exports$1, "ProgressToken", { enumerable: true, get: function() { + return connection_1.ProgressToken; + } }); + Object.defineProperty(exports$1, "ProgressType", { enumerable: true, get: function() { + return connection_1.ProgressType; + } }); + Object.defineProperty(exports$1, "Trace", { enumerable: true, get: function() { + return connection_1.Trace; + } }); + Object.defineProperty(exports$1, "TraceValues", { enumerable: true, get: function() { + return connection_1.TraceValues; + } }); + Object.defineProperty(exports$1, "TraceFormat", { enumerable: true, get: function() { + return connection_1.TraceFormat; + } }); + Object.defineProperty(exports$1, "SetTraceNotification", { enumerable: true, get: function() { + return connection_1.SetTraceNotification; + } }); + Object.defineProperty(exports$1, "LogTraceNotification", { enumerable: true, get: function() { + return connection_1.LogTraceNotification; + } }); + Object.defineProperty(exports$1, "ConnectionErrors", { enumerable: true, get: function() { + return connection_1.ConnectionErrors; + } }); + Object.defineProperty(exports$1, "ConnectionError", { enumerable: true, get: function() { + return connection_1.ConnectionError; + } }); + Object.defineProperty(exports$1, "CancellationReceiverStrategy", { enumerable: true, get: function() { + return connection_1.CancellationReceiverStrategy; + } }); + Object.defineProperty(exports$1, "CancellationSenderStrategy", { enumerable: true, get: function() { + return connection_1.CancellationSenderStrategy; + } }); + Object.defineProperty(exports$1, "CancellationStrategy", { enumerable: true, get: function() { + return connection_1.CancellationStrategy; + } }); + Object.defineProperty(exports$1, "MessageStrategy", { enumerable: true, get: function() { + return connection_1.MessageStrategy; + } }); + var ral_1 = require_ral(); + exports$1.RAL = ral_1.default; + } +}); + +// node_modules/vscode-jsonrpc/lib/node/ril.js +var require_ril = __commonJS({ + "node_modules/vscode-jsonrpc/lib/node/ril.js"(exports$1) { + Object.defineProperty(exports$1, "__esModule", { value: true }); + var util_1 = __require("util"); + var api_1 = require_api(); + var MessageBuffer = class _MessageBuffer extends api_1.AbstractMessageBuffer { + constructor(encoding = "utf-8") { + super(encoding); + } + emptyBuffer() { + return _MessageBuffer.emptyBuffer; + } + fromString(value, encoding) { + return Buffer.from(value, encoding); + } + toString(value, encoding) { + if (value instanceof Buffer) { + return value.toString(encoding); + } else { + return new util_1.TextDecoder(encoding).decode(value); + } + } + asNative(buffer, length) { + if (length === void 0) { + return buffer instanceof Buffer ? buffer : Buffer.from(buffer); + } else { + return buffer instanceof Buffer ? buffer.slice(0, length) : Buffer.from(buffer, 0, length); + } + } + allocNative(length) { + return Buffer.allocUnsafe(length); + } + }; + MessageBuffer.emptyBuffer = Buffer.allocUnsafe(0); + var ReadableStreamWrapper = class { + constructor(stream) { + this.stream = stream; + } + onClose(listener) { + this.stream.on("close", listener); + return api_1.Disposable.create(() => this.stream.off("close", listener)); + } + onError(listener) { + this.stream.on("error", listener); + return api_1.Disposable.create(() => this.stream.off("error", listener)); + } + onEnd(listener) { + this.stream.on("end", listener); + return api_1.Disposable.create(() => this.stream.off("end", listener)); + } + onData(listener) { + this.stream.on("data", listener); + return api_1.Disposable.create(() => this.stream.off("data", listener)); + } + }; + var WritableStreamWrapper = class { + constructor(stream) { + this.stream = stream; + } + onClose(listener) { + this.stream.on("close", listener); + return api_1.Disposable.create(() => this.stream.off("close", listener)); + } + onError(listener) { + this.stream.on("error", listener); + return api_1.Disposable.create(() => this.stream.off("error", listener)); + } + onEnd(listener) { + this.stream.on("end", listener); + return api_1.Disposable.create(() => this.stream.off("end", listener)); + } + write(data, encoding) { + return new Promise((resolve, reject) => { + const callback = (error) => { + if (error === void 0 || error === null) { + resolve(); + } else { + reject(error); + } + }; + if (typeof data === "string") { + this.stream.write(data, encoding, callback); + } else { + this.stream.write(data, callback); + } + }); + } + end() { + this.stream.end(); + } + }; + var _ril = Object.freeze({ + messageBuffer: Object.freeze({ + create: (encoding) => new MessageBuffer(encoding) + }), + applicationJson: Object.freeze({ + encoder: Object.freeze({ + name: "application/json", + encode: (msg, options) => { + try { + return Promise.resolve(Buffer.from(JSON.stringify(msg, void 0, 0), options.charset)); + } catch (err) { + return Promise.reject(err); + } + } + }), + decoder: Object.freeze({ + name: "application/json", + decode: (buffer, options) => { + try { + if (buffer instanceof Buffer) { + return Promise.resolve(JSON.parse(buffer.toString(options.charset))); + } else { + return Promise.resolve(JSON.parse(new util_1.TextDecoder(options.charset).decode(buffer))); + } + } catch (err) { + return Promise.reject(err); + } + } + }) + }), + stream: Object.freeze({ + asReadableStream: (stream) => new ReadableStreamWrapper(stream), + asWritableStream: (stream) => new WritableStreamWrapper(stream) + }), + console, + timer: Object.freeze({ + setTimeout(callback, ms, ...args) { + const handle = setTimeout(callback, ms, ...args); + return { dispose: () => clearTimeout(handle) }; + }, + setImmediate(callback, ...args) { + const handle = setImmediate(callback, ...args); + return { dispose: () => clearImmediate(handle) }; + }, + setInterval(callback, ms, ...args) { + const handle = setInterval(callback, ms, ...args); + return { dispose: () => clearInterval(handle) }; + } + }) + }); + function RIL() { + return _ril; + } + (function(RIL2) { + function install() { + api_1.RAL.install(_ril); + } + RIL2.install = install; + })(RIL || (RIL = {})); + exports$1.default = RIL; + } +}); + +// node_modules/vscode-jsonrpc/lib/node/main.js +var require_main = __commonJS({ + "node_modules/vscode-jsonrpc/lib/node/main.js"(exports$1) { + var __createBinding = exports$1 && exports$1.__createBinding || (Object.create ? (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === void 0) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = exports$1 && exports$1.__exportStar || function(m, exports2) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p); + }; + Object.defineProperty(exports$1, "__esModule", { value: true }); + exports$1.createMessageConnection = exports$1.createServerSocketTransport = exports$1.createClientSocketTransport = exports$1.createServerPipeTransport = exports$1.createClientPipeTransport = exports$1.generateRandomPipeName = exports$1.StreamMessageWriter = exports$1.StreamMessageReader = exports$1.SocketMessageWriter = exports$1.SocketMessageReader = exports$1.PortMessageWriter = exports$1.PortMessageReader = exports$1.IPCMessageWriter = exports$1.IPCMessageReader = void 0; + var ril_1 = require_ril(); + ril_1.default.install(); + var path = __require("path"); + var os = __require("os"); + var crypto_1 = __require("crypto"); + var net_1 = __require("net"); + var api_1 = require_api(); + __exportStar(require_api(), exports$1); + var IPCMessageReader = class extends api_1.AbstractMessageReader { + constructor(process2) { + super(); + this.process = process2; + let eventEmitter = this.process; + eventEmitter.on("error", (error) => this.fireError(error)); + eventEmitter.on("close", () => this.fireClose()); + } + listen(callback) { + this.process.on("message", callback); + return api_1.Disposable.create(() => this.process.off("message", callback)); + } + }; + exports$1.IPCMessageReader = IPCMessageReader; + var IPCMessageWriter = class extends api_1.AbstractMessageWriter { + constructor(process2) { + super(); + this.process = process2; + this.errorCount = 0; + const eventEmitter = this.process; + eventEmitter.on("error", (error) => this.fireError(error)); + eventEmitter.on("close", () => this.fireClose); + } + write(msg) { + try { + if (typeof this.process.send === "function") { + this.process.send(msg, void 0, void 0, (error) => { + if (error) { + this.errorCount++; + this.handleError(error, msg); + } else { + this.errorCount = 0; + } + }); + } + return Promise.resolve(); + } catch (error) { + this.handleError(error, msg); + return Promise.reject(error); + } + } + handleError(error, msg) { + this.errorCount++; + this.fireError(error, msg, this.errorCount); + } + end() { + } + }; + exports$1.IPCMessageWriter = IPCMessageWriter; + var PortMessageReader = class extends api_1.AbstractMessageReader { + constructor(port) { + super(); + this.onData = new api_1.Emitter(); + port.on("close", () => this.fireClose); + port.on("error", (error) => this.fireError(error)); + port.on("message", (message) => { + this.onData.fire(message); + }); + } + listen(callback) { + return this.onData.event(callback); + } + }; + exports$1.PortMessageReader = PortMessageReader; + var PortMessageWriter = class extends api_1.AbstractMessageWriter { + constructor(port) { + super(); + this.port = port; + this.errorCount = 0; + port.on("close", () => this.fireClose()); + port.on("error", (error) => this.fireError(error)); + } + write(msg) { + try { + this.port.postMessage(msg); + return Promise.resolve(); + } catch (error) { + this.handleError(error, msg); + return Promise.reject(error); + } + } + handleError(error, msg) { + this.errorCount++; + this.fireError(error, msg, this.errorCount); + } + end() { + } + }; + exports$1.PortMessageWriter = PortMessageWriter; + var SocketMessageReader = class extends api_1.ReadableStreamMessageReader { + constructor(socket, encoding = "utf-8") { + super((0, ril_1.default)().stream.asReadableStream(socket), encoding); + } + }; + exports$1.SocketMessageReader = SocketMessageReader; + var SocketMessageWriter = class extends api_1.WriteableStreamMessageWriter { + constructor(socket, options) { + super((0, ril_1.default)().stream.asWritableStream(socket), options); + this.socket = socket; + } + dispose() { + super.dispose(); + this.socket.destroy(); + } + }; + exports$1.SocketMessageWriter = SocketMessageWriter; + var StreamMessageReader2 = class extends api_1.ReadableStreamMessageReader { + constructor(readable, encoding) { + super((0, ril_1.default)().stream.asReadableStream(readable), encoding); + } + }; + exports$1.StreamMessageReader = StreamMessageReader2; + var StreamMessageWriter2 = class extends api_1.WriteableStreamMessageWriter { + constructor(writable, options) { + super((0, ril_1.default)().stream.asWritableStream(writable), options); + } + }; + exports$1.StreamMessageWriter = StreamMessageWriter2; + var XDG_RUNTIME_DIR = process.env["XDG_RUNTIME_DIR"]; + var safeIpcPathLengths = /* @__PURE__ */ new Map([ + ["linux", 107], + ["darwin", 103] + ]); + function generateRandomPipeName() { + const randomSuffix = (0, crypto_1.randomBytes)(21).toString("hex"); + if (process.platform === "win32") { + return `\\\\.\\pipe\\vscode-jsonrpc-${randomSuffix}-sock`; + } + let result; + if (XDG_RUNTIME_DIR) { + result = path.join(XDG_RUNTIME_DIR, `vscode-ipc-${randomSuffix}.sock`); + } else { + result = path.join(os.tmpdir(), `vscode-${randomSuffix}.sock`); + } + const limit = safeIpcPathLengths.get(process.platform); + if (limit !== void 0 && result.length > limit) { + (0, ril_1.default)().console.warn(`WARNING: IPC handle "${result}" is longer than ${limit} characters.`); + } + return result; + } + exports$1.generateRandomPipeName = generateRandomPipeName; + function createClientPipeTransport(pipeName, encoding = "utf-8") { + let connectResolve; + const connected = new Promise((resolve, _reject) => { + connectResolve = resolve; + }); + return new Promise((resolve, reject) => { + let server = (0, net_1.createServer)((socket) => { + server.close(); + connectResolve([ + new SocketMessageReader(socket, encoding), + new SocketMessageWriter(socket, encoding) + ]); + }); + server.on("error", reject); + server.listen(pipeName, () => { + server.removeListener("error", reject); + resolve({ + onConnected: () => { + return connected; + } + }); + }); + }); + } + exports$1.createClientPipeTransport = createClientPipeTransport; + function createServerPipeTransport(pipeName, encoding = "utf-8") { + const socket = (0, net_1.createConnection)(pipeName); + return [ + new SocketMessageReader(socket, encoding), + new SocketMessageWriter(socket, encoding) + ]; + } + exports$1.createServerPipeTransport = createServerPipeTransport; + function createClientSocketTransport(port, encoding = "utf-8") { + let connectResolve; + const connected = new Promise((resolve, _reject) => { + connectResolve = resolve; + }); + return new Promise((resolve, reject) => { + const server = (0, net_1.createServer)((socket) => { + server.close(); + connectResolve([ + new SocketMessageReader(socket, encoding), + new SocketMessageWriter(socket, encoding) + ]); + }); + server.on("error", reject); + server.listen(port, "127.0.0.1", () => { + server.removeListener("error", reject); + resolve({ + onConnected: () => { + return connected; + } + }); + }); + }); + } + exports$1.createClientSocketTransport = createClientSocketTransport; + function createServerSocketTransport(port, encoding = "utf-8") { + const socket = (0, net_1.createConnection)(port, "127.0.0.1"); + return [ + new SocketMessageReader(socket, encoding), + new SocketMessageWriter(socket, encoding) + ]; + } + exports$1.createServerSocketTransport = createServerSocketTransport; + function isReadableStream(value) { + const candidate = value; + return candidate.read !== void 0 && candidate.addListener !== void 0; + } + function isWritableStream(value) { + const candidate = value; + return candidate.write !== void 0 && candidate.addListener !== void 0; + } + function createMessageConnection2(input, output, logger, options) { + if (!logger) { + logger = api_1.NullLogger; + } + const reader = isReadableStream(input) ? new StreamMessageReader2(input) : input; + const writer = isWritableStream(output) ? new StreamMessageWriter2(output) : output; + if (api_1.ConnectionStrategy.is(options)) { + options = { connectionStrategy: options }; + } + return (0, api_1.createMessageConnection)(reader, writer, logger, options); + } + exports$1.createMessageConnection = createMessageConnection2; + } +}); + +// node_modules/vscode-jsonrpc/node.js +var require_node = __commonJS({ + "node_modules/vscode-jsonrpc/node.js"(exports$1, module) { + module.exports = require_main(); + } +}); + +// node_modules/ms/index.js +var require_ms = __commonJS({ + "node_modules/ms/index.js"(exports$1, module) { + var s = 1e3; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var w = d * 7; + var y = d * 365.25; + module.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === "string" && val.length > 0) { + return parse(val); + } else if (type === "number" && isFinite(val)) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + "val is not a non-empty string or a valid number. val=" + JSON.stringify(val) + ); + }; + function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || "ms").toLowerCase(); + switch (type) { + case "years": + case "year": + case "yrs": + case "yr": + case "y": + return n * y; + case "weeks": + case "week": + case "w": + return n * w; + case "days": + case "day": + case "d": + return n * d; + case "hours": + case "hour": + case "hrs": + case "hr": + case "h": + return n * h; + case "minutes": + case "minute": + case "mins": + case "min": + case "m": + return n * m; + case "seconds": + case "second": + case "secs": + case "sec": + case "s": + return n * s; + case "milliseconds": + case "millisecond": + case "msecs": + case "msec": + case "ms": + return n; + default: + return void 0; + } + } + function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + "d"; + } + if (msAbs >= h) { + return Math.round(ms / h) + "h"; + } + if (msAbs >= m) { + return Math.round(ms / m) + "m"; + } + if (msAbs >= s) { + return Math.round(ms / s) + "s"; + } + return ms + "ms"; + } + function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, "day"); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, "hour"); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, "minute"); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, "second"); + } + return ms + " ms"; + } + function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + " " + name + (isPlural ? "s" : ""); + } + } +}); + +// node_modules/debug/src/common.js +var require_common = __commonJS({ + "node_modules/debug/src/common.js"(exports$1, module) { + function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require_ms(); + createDebug.destroy = destroy; + Object.keys(env).forEach((key) => { + createDebug[key] = env[key]; + }); + createDebug.names = []; + createDebug.skips = []; + createDebug.formatters = {}; + function selectColor(namespace) { + let hash = 0; + for (let i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + function createDebug(namespace) { + let prevTime; + let enableOverride = null; + let namespacesCache; + let enabledCache; + function debug2(...args) { + if (!debug2.enabled) { + return; + } + const self = debug2; + const curr = Number(/* @__PURE__ */ new Date()); + const ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + if (typeof args[0] !== "string") { + args.unshift("%O"); + } + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + if (match === "%%") { + return "%"; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === "function") { + const val = args[index]; + match = formatter.call(self, val); + args.splice(index, 1); + index--; + } + return match; + }); + createDebug.formatArgs.call(self, args); + const logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + debug2.namespace = namespace; + debug2.useColors = createDebug.useColors(); + debug2.color = createDebug.selectColor(namespace); + debug2.extend = extend; + debug2.destroy = createDebug.destroy; + Object.defineProperty(debug2, "enabled", { + enumerable: true, + configurable: false, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + return enabledCache; + }, + set: (v) => { + enableOverride = v; + } + }); + if (typeof createDebug.init === "function") { + createDebug.init(debug2); + } + return debug2; + } + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.namespaces = namespaces; + createDebug.names = []; + createDebug.skips = []; + const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean); + for (const ns of split) { + if (ns[0] === "-") { + createDebug.skips.push(ns.slice(1)); + } else { + createDebug.names.push(ns); + } + } + } + function matchesTemplate(search, template) { + let searchIndex = 0; + let templateIndex = 0; + let starIndex = -1; + let matchIndex = 0; + while (searchIndex < search.length) { + if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) { + if (template[templateIndex] === "*") { + starIndex = templateIndex; + matchIndex = searchIndex; + templateIndex++; + } else { + searchIndex++; + templateIndex++; + } + } else if (starIndex !== -1) { + templateIndex = starIndex + 1; + matchIndex++; + searchIndex = matchIndex; + } else { + return false; + } + } + while (templateIndex < template.length && template[templateIndex] === "*") { + templateIndex++; + } + return templateIndex === template.length; + } + function disable() { + const namespaces = [ + ...createDebug.names, + ...createDebug.skips.map((namespace) => "-" + namespace) + ].join(","); + createDebug.enable(""); + return namespaces; + } + function enabled(name) { + for (const skip of createDebug.skips) { + if (matchesTemplate(name, skip)) { + return false; + } + } + for (const ns of createDebug.names) { + if (matchesTemplate(name, ns)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + function destroy() { + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + createDebug.enable(createDebug.load()); + return createDebug; + } + module.exports = setup; + } +}); + +// node_modules/debug/src/browser.js +var require_browser = __commonJS({ + "node_modules/debug/src/browser.js"(exports$1, module) { + exports$1.formatArgs = formatArgs; + exports$1.save = save; + exports$1.load = load; + exports$1.useColors = useColors; + exports$1.storage = localstorage(); + exports$1.destroy = /* @__PURE__ */ (() => { + let warned = false; + return () => { + if (!warned) { + warned = true; + console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); + } + }; + })(); + exports$1.colors = [ + "#0000CC", + "#0000FF", + "#0033CC", + "#0033FF", + "#0066CC", + "#0066FF", + "#0099CC", + "#0099FF", + "#00CC00", + "#00CC33", + "#00CC66", + "#00CC99", + "#00CCCC", + "#00CCFF", + "#3300CC", + "#3300FF", + "#3333CC", + "#3333FF", + "#3366CC", + "#3366FF", + "#3399CC", + "#3399FF", + "#33CC00", + "#33CC33", + "#33CC66", + "#33CC99", + "#33CCCC", + "#33CCFF", + "#6600CC", + "#6600FF", + "#6633CC", + "#6633FF", + "#66CC00", + "#66CC33", + "#9900CC", + "#9900FF", + "#9933CC", + "#9933FF", + "#99CC00", + "#99CC33", + "#CC0000", + "#CC0033", + "#CC0066", + "#CC0099", + "#CC00CC", + "#CC00FF", + "#CC3300", + "#CC3333", + "#CC3366", + "#CC3399", + "#CC33CC", + "#CC33FF", + "#CC6600", + "#CC6633", + "#CC9900", + "#CC9933", + "#CCCC00", + "#CCCC33", + "#FF0000", + "#FF0033", + "#FF0066", + "#FF0099", + "#FF00CC", + "#FF00FF", + "#FF3300", + "#FF3333", + "#FF3366", + "#FF3399", + "#FF33CC", + "#FF33FF", + "#FF6600", + "#FF6633", + "#FF9900", + "#FF9933", + "#FFCC00", + "#FFCC33" + ]; + function useColors() { + if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) { + return true; + } + if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + let m; + return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker + typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + function formatArgs(args) { + args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module.exports.humanize(this.diff); + if (!this.useColors) { + return; + } + const c = "color: " + this.color; + args.splice(1, 0, c, "color: inherit"); + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, (match) => { + if (match === "%%") { + return; + } + index++; + if (match === "%c") { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + exports$1.log = console.debug || console.log || (() => { + }); + function save(namespaces) { + try { + if (namespaces) { + exports$1.storage.setItem("debug", namespaces); + } else { + exports$1.storage.removeItem("debug"); + } + } catch (error) { + } + } + function load() { + let r; + try { + r = exports$1.storage.getItem("debug") || exports$1.storage.getItem("DEBUG"); + } catch (error) { + } + if (!r && typeof process !== "undefined" && "env" in process) { + r = process.env.DEBUG; + } + return r; + } + function localstorage() { + try { + return localStorage; + } catch (error) { + } + } + module.exports = require_common()(exports$1); + var { formatters } = module.exports; + formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (error) { + return "[UnexpectedJSONParseError]: " + error.message; + } + }; + } +}); + +// node_modules/debug/src/node.js +var require_node2 = __commonJS({ + "node_modules/debug/src/node.js"(exports$1, module) { + var tty = __require("tty"); + var util = __require("util"); + exports$1.init = init; + exports$1.log = log; + exports$1.formatArgs = formatArgs; + exports$1.save = save; + exports$1.load = load; + exports$1.useColors = useColors; + exports$1.destroy = util.deprecate( + () => { + }, + "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`." + ); + exports$1.colors = [6, 2, 3, 4, 5, 1]; + try { + const supportsColor = __require("supports-color"); + if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { + exports$1.colors = [ + 20, + 21, + 26, + 27, + 32, + 33, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 56, + 57, + 62, + 63, + 68, + 69, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 92, + 93, + 98, + 99, + 112, + 113, + 128, + 129, + 134, + 135, + 148, + 149, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 178, + 179, + 184, + 185, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 214, + 215, + 220, + 221 + ]; + } + } catch (error) { + } + exports$1.inspectOpts = Object.keys(process.env).filter((key) => { + return /^debug_/i.test(key); + }).reduce((obj, key) => { + const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_, k) => { + return k.toUpperCase(); + }); + let val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) { + val = true; + } else if (/^(no|off|false|disabled)$/i.test(val)) { + val = false; + } else if (val === "null") { + val = null; + } else { + val = Number(val); + } + obj[prop] = val; + return obj; + }, {}); + function useColors() { + return "colors" in exports$1.inspectOpts ? Boolean(exports$1.inspectOpts.colors) : tty.isatty(process.stderr.fd); + } + function formatArgs(args) { + const { namespace: name, useColors: useColors2 } = this; + if (useColors2) { + const c = this.color; + const colorCode = "\x1B[3" + (c < 8 ? c : "8;5;" + c); + const prefix = ` ${colorCode};1m${name} \x1B[0m`; + args[0] = prefix + args[0].split("\n").join("\n" + prefix); + args.push(colorCode + "m+" + module.exports.humanize(this.diff) + "\x1B[0m"); + } else { + args[0] = getDate() + name + " " + args[0]; + } + } + function getDate() { + if (exports$1.inspectOpts.hideDate) { + return ""; + } + return (/* @__PURE__ */ new Date()).toISOString() + " "; + } + function log(...args) { + return process.stderr.write(util.formatWithOptions(exports$1.inspectOpts, ...args) + "\n"); + } + function save(namespaces) { + if (namespaces) { + process.env.DEBUG = namespaces; + } else { + delete process.env.DEBUG; + } + } + function load() { + return process.env.DEBUG; + } + function init(debug2) { + debug2.inspectOpts = {}; + const keys = Object.keys(exports$1.inspectOpts); + for (let i = 0; i < keys.length; i++) { + debug2.inspectOpts[keys[i]] = exports$1.inspectOpts[keys[i]]; + } + } + module.exports = require_common()(exports$1); + var { formatters } = module.exports; + formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts).split("\n").map((str) => str.trim()).join(" "); + }; + formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); + }; + } +}); + +// node_modules/debug/src/index.js +var require_src = __commonJS({ + "node_modules/debug/src/index.js"(exports$1, module) { + if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) { + module.exports = require_browser(); + } else { + module.exports = require_node2(); + } + } +}); + +// node_modules/@github/copilot-sdk/dist/client.js +var import_node = __toESM(require_node()); + +// node_modules/@github/copilot-sdk/dist/sdkProtocolVersion.js +var SDK_PROTOCOL_VERSION = 2; +function getSdkProtocolVersion() { + return SDK_PROTOCOL_VERSION; +} + +// node_modules/@github/copilot-sdk/dist/session.js +var CopilotSession = class { + /** + * Creates a new CopilotSession instance. + * + * @param sessionId - The unique identifier for this session + * @param connection - The JSON-RPC message connection to the Copilot CLI + * @param workspacePath - Path to the session workspace directory (when infinite sessions enabled) + * @internal This constructor is internal. Use {@link CopilotClient.createSession} to create sessions. + */ + constructor(sessionId, connection, _workspacePath) { + this.sessionId = sessionId; + this.connection = connection; + this._workspacePath = _workspacePath; + } + eventHandlers = /* @__PURE__ */ new Set(); + typedEventHandlers = /* @__PURE__ */ new Map(); + toolHandlers = /* @__PURE__ */ new Map(); + permissionHandler; + userInputHandler; + hooks; + /** + * Path to the session workspace directory when infinite sessions are enabled. + * Contains checkpoints/, plan.md, and files/ subdirectories. + * Undefined if infinite sessions are disabled. + */ + get workspacePath() { + return this._workspacePath; + } + /** + * Sends a message to this session and waits for the response. + * + * The message is processed asynchronously. Subscribe to events via {@link on} + * to receive streaming responses and other session events. + * + * @param options - The message options including the prompt and optional attachments + * @returns A promise that resolves with the message ID of the response + * @throws Error if the session has been destroyed or the connection fails + * + * @example + * ```typescript + * const messageId = await session.send({ + * prompt: "Explain this code", + * attachments: [{ type: "file", path: "./src/index.ts" }] + * }); + * ``` + */ + async send(options) { + const response = await this.connection.sendRequest("session.send", { + sessionId: this.sessionId, + prompt: options.prompt, + attachments: options.attachments, + mode: options.mode + }); + return response.messageId; + } + /** + * Sends a message to this session and waits until the session becomes idle. + * + * This is a convenience method that combines {@link send} with waiting for + * the `session.idle` event. Use this when you want to block until the + * assistant has finished processing the message. + * + * Events are still delivered to handlers registered via {@link on} while waiting. + * + * @param options - The message options including the prompt and optional attachments + * @param timeout - Timeout in milliseconds (default: 60000). Controls how long to wait; does not abort in-flight agent work. + * @returns A promise that resolves with the final assistant message when the session becomes idle, + * or undefined if no assistant message was received + * @throws Error if the timeout is reached before the session becomes idle + * @throws Error if the session has been destroyed or the connection fails + * + * @example + * ```typescript + * // Send and wait for completion with default 60s timeout + * const response = await session.sendAndWait({ prompt: "What is 2+2?" }); + * console.log(response?.data.content); // "4" + * ``` + */ + async sendAndWait(options, timeout) { + const effectiveTimeout = timeout ?? 6e4; + let resolveIdle; + let rejectWithError; + const idlePromise = new Promise((resolve, reject) => { + resolveIdle = resolve; + rejectWithError = reject; + }); + let lastAssistantMessage; + const unsubscribe = this.on((event) => { + if (event.type === "assistant.message") { + lastAssistantMessage = event; + } else if (event.type === "session.idle") { + resolveIdle(); + } else if (event.type === "session.error") { + const error = new Error(event.data.message); + error.stack = event.data.stack; + rejectWithError(error); + } + }); + let timeoutId; + try { + await this.send(options); + const timeoutPromise = new Promise((_, reject) => { + timeoutId = setTimeout( + () => reject( + new Error( + `Timeout after ${effectiveTimeout}ms waiting for session.idle` + ) + ), + effectiveTimeout + ); + }); + await Promise.race([idlePromise, timeoutPromise]); + return lastAssistantMessage; + } finally { + if (timeoutId !== void 0) { + clearTimeout(timeoutId); + } + unsubscribe(); + } + } + on(eventTypeOrHandler, handler) { + if (typeof eventTypeOrHandler === "string" && handler) { + const eventType = eventTypeOrHandler; + if (!this.typedEventHandlers.has(eventType)) { + this.typedEventHandlers.set(eventType, /* @__PURE__ */ new Set()); + } + const storedHandler = handler; + this.typedEventHandlers.get(eventType).add(storedHandler); + return () => { + const handlers = this.typedEventHandlers.get(eventType); + if (handlers) { + handlers.delete(storedHandler); + } + }; + } + const wildcardHandler = eventTypeOrHandler; + this.eventHandlers.add(wildcardHandler); + return () => { + this.eventHandlers.delete(wildcardHandler); + }; + } + /** + * Dispatches an event to all registered handlers. + * + * @param event - The session event to dispatch + * @internal This method is for internal use by the SDK. + */ + _dispatchEvent(event) { + const typedHandlers = this.typedEventHandlers.get(event.type); + if (typedHandlers) { + for (const handler of typedHandlers) { + try { + handler(event); + } catch (_error) { + } + } + } + for (const handler of this.eventHandlers) { + try { + handler(event); + } catch (_error) { + } + } + } + /** + * Registers custom tool handlers for this session. + * + * Tools allow the assistant to execute custom functions. When the assistant + * invokes a tool, the corresponding handler is called with the tool arguments. + * + * @param tools - An array of tool definitions with their handlers, or undefined to clear all tools + * @internal This method is typically called internally when creating a session with tools. + */ + registerTools(tools) { + this.toolHandlers.clear(); + if (!tools) { + return; + } + for (const tool of tools) { + this.toolHandlers.set(tool.name, tool.handler); + } + } + /** + * Retrieves a registered tool handler by name. + * + * @param name - The name of the tool to retrieve + * @returns The tool handler if found, or undefined + * @internal This method is for internal use by the SDK. + */ + getToolHandler(name) { + return this.toolHandlers.get(name); + } + /** + * Registers a handler for permission requests. + * + * When the assistant needs permission to perform certain actions (e.g., file operations), + * this handler is called to approve or deny the request. + * + * @param handler - The permission handler function, or undefined to remove the handler + * @internal This method is typically called internally when creating a session. + */ + registerPermissionHandler(handler) { + this.permissionHandler = handler; + } + /** + * Registers a user input handler for ask_user requests. + * + * When the agent needs input from the user (via ask_user tool), + * this handler is called to provide the response. + * + * @param handler - The user input handler function, or undefined to remove the handler + * @internal This method is typically called internally when creating a session. + */ + registerUserInputHandler(handler) { + this.userInputHandler = handler; + } + /** + * Registers hook handlers for session lifecycle events. + * + * Hooks allow custom logic to be executed at various points during + * the session lifecycle (before/after tool use, session start/end, etc.). + * + * @param hooks - The hook handlers object, or undefined to remove all hooks + * @internal This method is typically called internally when creating a session. + */ + registerHooks(hooks) { + this.hooks = hooks; + } + /** + * Handles a permission request from the Copilot CLI. + * + * @param request - The permission request data from the CLI + * @returns A promise that resolves with the permission decision + * @internal This method is for internal use by the SDK. + */ + async _handlePermissionRequest(request) { + if (!this.permissionHandler) { + return { kind: "denied-no-approval-rule-and-could-not-request-from-user" }; + } + try { + const result = await this.permissionHandler(request, { + sessionId: this.sessionId + }); + return result; + } catch (_error) { + return { kind: "denied-no-approval-rule-and-could-not-request-from-user" }; + } + } + /** + * Handles a user input request from the Copilot CLI. + * + * @param request - The user input request data from the CLI + * @returns A promise that resolves with the user's response + * @internal This method is for internal use by the SDK. + */ + async _handleUserInputRequest(request) { + if (!this.userInputHandler) { + throw new Error("User input requested but no handler registered"); + } + try { + const result = await this.userInputHandler(request, { + sessionId: this.sessionId + }); + return result; + } catch (error) { + throw error; + } + } + /** + * Handles a hooks invocation from the Copilot CLI. + * + * @param hookType - The type of hook being invoked + * @param input - The input data for the hook + * @returns A promise that resolves with the hook output, or undefined + * @internal This method is for internal use by the SDK. + */ + async _handleHooksInvoke(hookType, input) { + if (!this.hooks) { + return void 0; + } + const handlerMap = { + preToolUse: this.hooks.onPreToolUse, + postToolUse: this.hooks.onPostToolUse, + userPromptSubmitted: this.hooks.onUserPromptSubmitted, + sessionStart: this.hooks.onSessionStart, + sessionEnd: this.hooks.onSessionEnd, + errorOccurred: this.hooks.onErrorOccurred + }; + const handler = handlerMap[hookType]; + if (!handler) { + return void 0; + } + try { + const result = await handler(input, { sessionId: this.sessionId }); + return result; + } catch (_error) { + return void 0; + } + } + /** + * Retrieves all events and messages from this session's history. + * + * This returns the complete conversation history including user messages, + * assistant responses, tool executions, and other session events. + * + * @returns A promise that resolves with an array of all session events + * @throws Error if the session has been destroyed or the connection fails + * + * @example + * ```typescript + * const events = await session.getMessages(); + * for (const event of events) { + * if (event.type === "assistant.message") { + * console.log("Assistant:", event.data.content); + * } + * } + * ``` + */ + async getMessages() { + const response = await this.connection.sendRequest("session.getMessages", { + sessionId: this.sessionId + }); + return response.events; + } + /** + * Destroys this session and releases all associated resources. + * + * After calling this method, the session can no longer be used. All event + * handlers and tool handlers are cleared. To continue the conversation, + * use {@link CopilotClient.resumeSession} with the session ID. + * + * @returns A promise that resolves when the session is destroyed + * @throws Error if the connection fails + * + * @example + * ```typescript + * // Clean up when done + * await session.destroy(); + * ``` + */ + async destroy() { + await this.connection.sendRequest("session.destroy", { + sessionId: this.sessionId + }); + this.eventHandlers.clear(); + this.typedEventHandlers.clear(); + this.toolHandlers.clear(); + this.permissionHandler = void 0; + } + /** + * Aborts the currently processing message in this session. + * + * Use this to cancel a long-running request. The session remains valid + * and can continue to be used for new messages. + * + * @returns A promise that resolves when the abort request is acknowledged + * @throws Error if the session has been destroyed or the connection fails + * + * @example + * ```typescript + * // Start a long-running request + * const messagePromise = session.send({ prompt: "Write a very long story..." }); + * + * // Abort after 5 seconds + * setTimeout(async () => { + * await session.abort(); + * }, 5000); + * ``` + */ + async abort() { + await this.connection.sendRequest("session.abort", { + sessionId: this.sessionId + }); + } +}; + +// node_modules/@github/copilot-sdk/dist/client.js +function isZodSchema(value) { + return value != null && typeof value === "object" && "toJSONSchema" in value && typeof value.toJSONSchema === "function"; +} +function toJsonSchema(parameters) { + if (!parameters) return void 0; + if (isZodSchema(parameters)) { + return parameters.toJSONSchema(); + } + return parameters; +} +function getBundledCliPath() { + const sdkUrl = import.meta.resolve("@github/copilot/sdk"); + const sdkPath = fileURLToPath(sdkUrl); + return join(dirname(dirname(sdkPath)), "index.js"); +} +var CopilotClient = class { + cliProcess = null; + connection = null; + socket = null; + actualPort = null; + actualHost = "localhost"; + state = "disconnected"; + sessions = /* @__PURE__ */ new Map(); + options; + isExternalServer = false; + forceStopping = false; + modelsCache = null; + modelsCacheLock = Promise.resolve(); + sessionLifecycleHandlers = /* @__PURE__ */ new Set(); + typedLifecycleHandlers = /* @__PURE__ */ new Map(); + /** + * Creates a new CopilotClient instance. + * + * @param options - Configuration options for the client + * @throws Error if mutually exclusive options are provided (e.g., cliUrl with useStdio or cliPath) + * + * @example + * ```typescript + * // Default options - spawns CLI server using stdio + * const client = new CopilotClient(); + * + * // Connect to an existing server + * const client = new CopilotClient({ cliUrl: "localhost:3000" }); + * + * // Custom CLI path with specific log level + * const client = new CopilotClient({ + * cliPath: "/usr/local/bin/copilot", + * logLevel: "debug" + * }); + * ``` + */ + constructor(options = {}) { + if (options.cliUrl && (options.useStdio === true || options.cliPath)) { + throw new Error("cliUrl is mutually exclusive with useStdio and cliPath"); + } + if (options.cliUrl && (options.githubToken || options.useLoggedInUser !== void 0)) { + throw new Error( + "githubToken and useLoggedInUser cannot be used with cliUrl (external server manages its own auth)" + ); + } + if (options.cliUrl) { + const { host, port } = this.parseCliUrl(options.cliUrl); + this.actualHost = host; + this.actualPort = port; + this.isExternalServer = true; + } + this.options = { + cliPath: options.cliPath || getBundledCliPath(), + cliArgs: options.cliArgs ?? [], + cwd: options.cwd ?? process.cwd(), + port: options.port || 0, + useStdio: options.cliUrl ? false : options.useStdio ?? true, + // Default to stdio unless cliUrl is provided + cliUrl: options.cliUrl, + logLevel: options.logLevel || "debug", + autoStart: options.autoStart ?? true, + autoRestart: options.autoRestart ?? true, + env: options.env ?? process.env, + githubToken: options.githubToken, + // Default useLoggedInUser to false when githubToken is provided, otherwise true + useLoggedInUser: options.useLoggedInUser ?? (options.githubToken ? false : true) + }; + } + /** + * Parse CLI URL into host and port + * Supports formats: "host:port", "http://host:port", "https://host:port", or just "port" + */ + parseCliUrl(url) { + let cleanUrl = url.replace(/^https?:\/\//, ""); + if (/^\d+$/.test(cleanUrl)) { + return { host: "localhost", port: parseInt(cleanUrl, 10) }; + } + const parts = cleanUrl.split(":"); + if (parts.length !== 2) { + throw new Error( + `Invalid cliUrl format: ${url}. Expected "host:port", "http://host:port", or "port"` + ); + } + const host = parts[0] || "localhost"; + const port = parseInt(parts[1], 10); + if (isNaN(port) || port <= 0 || port > 65535) { + throw new Error(`Invalid port in cliUrl: ${url}`); + } + return { host, port }; + } + /** + * Starts the CLI server and establishes a connection. + * + * If connecting to an external server (via cliUrl), only establishes the connection. + * Otherwise, spawns the CLI server process and then connects. + * + * This method is called automatically when creating a session if `autoStart` is true (default). + * + * @returns A promise that resolves when the connection is established + * @throws Error if the server fails to start or the connection fails + * + * @example + * ```typescript + * const client = new CopilotClient({ autoStart: false }); + * await client.start(); + * // Now ready to create sessions + * ``` + */ + async start() { + if (this.state === "connected") { + return; + } + this.state = "connecting"; + try { + if (!this.isExternalServer) { + await this.startCLIServer(); + } + await this.connectToServer(); + await this.verifyProtocolVersion(); + this.state = "connected"; + } catch (error) { + this.state = "error"; + throw error; + } + } + /** + * Stops the CLI server and closes all active sessions. + * + * This method performs graceful cleanup: + * 1. Destroys all active sessions with retry logic + * 2. Closes the JSON-RPC connection + * 3. Terminates the CLI server process (if spawned by this client) + * + * @returns A promise that resolves with an array of errors encountered during cleanup. + * An empty array indicates all cleanup succeeded. + * + * @example + * ```typescript + * const errors = await client.stop(); + * if (errors.length > 0) { + * console.error("Cleanup errors:", errors); + * } + * ``` + */ + async stop() { + const errors = []; + for (const session of this.sessions.values()) { + const sessionId = session.sessionId; + let lastError = null; + for (let attempt = 1; attempt <= 3; attempt++) { + try { + await session.destroy(); + lastError = null; + break; + } catch (error) { + lastError = error instanceof Error ? error : new Error(String(error)); + if (attempt < 3) { + const delay = 100 * Math.pow(2, attempt - 1); + await new Promise((resolve) => setTimeout(resolve, delay)); + } + } + } + if (lastError) { + errors.push( + new Error( + `Failed to destroy session ${sessionId} after 3 attempts: ${lastError.message}` + ) + ); + } + } + this.sessions.clear(); + if (this.connection) { + try { + this.connection.dispose(); + } catch (error) { + errors.push( + new Error( + `Failed to dispose connection: ${error instanceof Error ? error.message : String(error)}` + ) + ); + } + this.connection = null; + } + this.modelsCache = null; + if (this.socket) { + try { + this.socket.end(); + } catch (error) { + errors.push( + new Error( + `Failed to close socket: ${error instanceof Error ? error.message : String(error)}` + ) + ); + } + this.socket = null; + } + if (this.cliProcess && !this.isExternalServer) { + try { + this.cliProcess.kill(); + } catch (error) { + errors.push( + new Error( + `Failed to kill CLI process: ${error instanceof Error ? error.message : String(error)}` + ) + ); + } + this.cliProcess = null; + } + this.state = "disconnected"; + this.actualPort = null; + return errors; + } + /** + * Forcefully stops the CLI server without graceful cleanup. + * + * Use this when {@link stop} fails or takes too long. This method: + * - Clears all sessions immediately without destroying them + * - Force closes the connection + * - Sends SIGKILL to the CLI process (if spawned by this client) + * + * @returns A promise that resolves when the force stop is complete + * + * @example + * ```typescript + * // If normal stop hangs, force stop + * const stopPromise = client.stop(); + * const timeout = new Promise((_, reject) => + * setTimeout(() => reject(new Error("Timeout")), 5000) + * ); + * + * try { + * await Promise.race([stopPromise, timeout]); + * } catch { + * await client.forceStop(); + * } + * ``` + */ + async forceStop() { + this.forceStopping = true; + this.sessions.clear(); + if (this.connection) { + try { + this.connection.dispose(); + } catch { + } + this.connection = null; + } + this.modelsCache = null; + if (this.socket) { + try { + this.socket.destroy(); + } catch { + } + this.socket = null; + } + if (this.cliProcess && !this.isExternalServer) { + try { + this.cliProcess.kill("SIGKILL"); + } catch { + } + this.cliProcess = null; + } + this.state = "disconnected"; + this.actualPort = null; + } + /** + * Creates a new conversation session with the Copilot CLI. + * + * Sessions maintain conversation state, handle events, and manage tool execution. + * If the client is not connected and `autoStart` is enabled, this will automatically + * start the connection. + * + * @param config - Optional configuration for the session + * @returns A promise that resolves with the created session + * @throws Error if the client is not connected and autoStart is disabled + * + * @example + * ```typescript + * // Basic session + * const session = await client.createSession(); + * + * // Session with model and tools + * const session = await client.createSession({ + * model: "gpt-4", + * tools: [{ + * name: "get_weather", + * description: "Get weather for a location", + * parameters: { type: "object", properties: { location: { type: "string" } } }, + * handler: async (args) => ({ temperature: 72 }) + * }] + * }); + * ``` + */ + async createSession(config = {}) { + if (!this.connection) { + if (this.options.autoStart) { + await this.start(); + } else { + throw new Error("Client not connected. Call start() first."); + } + } + const response = await this.connection.sendRequest("session.create", { + model: config.model, + sessionId: config.sessionId, + reasoningEffort: config.reasoningEffort, + tools: config.tools?.map((tool) => ({ + name: tool.name, + description: tool.description, + parameters: toJsonSchema(tool.parameters) + })), + systemMessage: config.systemMessage, + availableTools: config.availableTools, + excludedTools: config.excludedTools, + provider: config.provider, + requestPermission: !!config.onPermissionRequest, + requestUserInput: !!config.onUserInputRequest, + hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)), + workingDirectory: config.workingDirectory, + streaming: config.streaming, + mcpServers: config.mcpServers, + customAgents: config.customAgents, + configDir: config.configDir, + skillDirectories: config.skillDirectories, + disabledSkills: config.disabledSkills, + infiniteSessions: config.infiniteSessions + }); + const { sessionId, workspacePath } = response; + const session = new CopilotSession(sessionId, this.connection, workspacePath); + session.registerTools(config.tools); + if (config.onPermissionRequest) { + session.registerPermissionHandler(config.onPermissionRequest); + } + if (config.onUserInputRequest) { + session.registerUserInputHandler(config.onUserInputRequest); + } + if (config.hooks) { + session.registerHooks(config.hooks); + } + this.sessions.set(sessionId, session); + return session; + } + /** + * Resumes an existing conversation session by its ID. + * + * This allows you to continue a previous conversation, maintaining all + * conversation history. The session must have been previously created + * and not deleted. + * + * @param sessionId - The ID of the session to resume + * @param config - Optional configuration for the resumed session + * @returns A promise that resolves with the resumed session + * @throws Error if the session does not exist or the client is not connected + * + * @example + * ```typescript + * // Resume a previous session + * const session = await client.resumeSession("session-123"); + * + * // Resume with new tools + * const session = await client.resumeSession("session-123", { + * tools: [myNewTool] + * }); + * ``` + */ + async resumeSession(sessionId, config = {}) { + if (!this.connection) { + if (this.options.autoStart) { + await this.start(); + } else { + throw new Error("Client not connected. Call start() first."); + } + } + const response = await this.connection.sendRequest("session.resume", { + sessionId, + model: config.model, + reasoningEffort: config.reasoningEffort, + systemMessage: config.systemMessage, + availableTools: config.availableTools, + excludedTools: config.excludedTools, + tools: config.tools?.map((tool) => ({ + name: tool.name, + description: tool.description, + parameters: toJsonSchema(tool.parameters) + })), + provider: config.provider, + requestPermission: !!config.onPermissionRequest, + requestUserInput: !!config.onUserInputRequest, + hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)), + workingDirectory: config.workingDirectory, + configDir: config.configDir, + streaming: config.streaming, + mcpServers: config.mcpServers, + customAgents: config.customAgents, + skillDirectories: config.skillDirectories, + disabledSkills: config.disabledSkills, + infiniteSessions: config.infiniteSessions, + disableResume: config.disableResume + }); + const { sessionId: resumedSessionId, workspacePath } = response; + const session = new CopilotSession(resumedSessionId, this.connection, workspacePath); + session.registerTools(config.tools); + if (config.onPermissionRequest) { + session.registerPermissionHandler(config.onPermissionRequest); + } + if (config.onUserInputRequest) { + session.registerUserInputHandler(config.onUserInputRequest); + } + if (config.hooks) { + session.registerHooks(config.hooks); + } + this.sessions.set(resumedSessionId, session); + return session; + } + /** + * Gets the current connection state of the client. + * + * @returns The current connection state: "disconnected", "connecting", "connected", or "error" + * + * @example + * ```typescript + * if (client.getState() === "connected") { + * const session = await client.createSession(); + * } + * ``` + */ + getState() { + return this.state; + } + /** + * Sends a ping request to the server to verify connectivity. + * + * @param message - Optional message to include in the ping + * @returns A promise that resolves with the ping response containing the message and timestamp + * @throws Error if the client is not connected + * + * @example + * ```typescript + * const response = await client.ping("health check"); + * console.log(`Server responded at ${new Date(response.timestamp)}`); + * ``` + */ + async ping(message) { + if (!this.connection) { + throw new Error("Client not connected"); + } + const result = await this.connection.sendRequest("ping", { message }); + return result; + } + /** + * Get CLI status including version and protocol information + */ + async getStatus() { + if (!this.connection) { + throw new Error("Client not connected"); + } + const result = await this.connection.sendRequest("status.get", {}); + return result; + } + /** + * Get current authentication status + */ + async getAuthStatus() { + if (!this.connection) { + throw new Error("Client not connected"); + } + const result = await this.connection.sendRequest("auth.getStatus", {}); + return result; + } + /** + * List available models with their metadata. + * + * Results are cached after the first successful call to avoid rate limiting. + * The cache is cleared when the client disconnects. + * + * @throws Error if not authenticated + */ + async listModels() { + if (!this.connection) { + throw new Error("Client not connected"); + } + await this.modelsCacheLock; + let resolveLock; + this.modelsCacheLock = new Promise((resolve) => { + resolveLock = resolve; + }); + try { + if (this.modelsCache !== null) { + return [...this.modelsCache]; + } + const result = await this.connection.sendRequest("models.list", {}); + const response = result; + const models = response.models; + this.modelsCache = models; + return [...models]; + } finally { + resolveLock(); + } + } + /** + * Verify that the server's protocol version matches the SDK's expected version + */ + async verifyProtocolVersion() { + const expectedVersion = getSdkProtocolVersion(); + const pingResult = await this.ping(); + const serverVersion = pingResult.protocolVersion; + if (serverVersion === void 0) { + throw new Error( + `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server does not report a protocol version. Please update your server to ensure compatibility.` + ); + } + if (serverVersion !== expectedVersion) { + throw new Error( + `SDK protocol version mismatch: SDK expects version ${expectedVersion}, but server reports version ${serverVersion}. Please update your SDK or server to ensure compatibility.` + ); + } + } + /** + * Gets the ID of the most recently updated session. + * + * This is useful for resuming the last conversation when the session ID + * was not stored. + * + * @returns A promise that resolves with the session ID, or undefined if no sessions exist + * @throws Error if the client is not connected + * + * @example + * ```typescript + * const lastId = await client.getLastSessionId(); + * if (lastId) { + * const session = await client.resumeSession(lastId); + * } + * ``` + */ + async getLastSessionId() { + if (!this.connection) { + throw new Error("Client not connected"); + } + const response = await this.connection.sendRequest("session.getLastId", {}); + return response.sessionId; + } + /** + * Deletes a session and its data from disk. + * + * This permanently removes the session and all its conversation history. + * The session cannot be resumed after deletion. + * + * @param sessionId - The ID of the session to delete + * @returns A promise that resolves when the session is deleted + * @throws Error if the session does not exist or deletion fails + * + * @example + * ```typescript + * await client.deleteSession("session-123"); + * ``` + */ + async deleteSession(sessionId) { + if (!this.connection) { + throw new Error("Client not connected"); + } + const response = await this.connection.sendRequest("session.delete", { + sessionId + }); + const { success, error } = response; + if (!success) { + throw new Error(`Failed to delete session ${sessionId}: ${error || "Unknown error"}`); + } + this.sessions.delete(sessionId); + } + /** + * Lists all available sessions known to the server. + * + * Returns metadata about each session including ID, timestamps, and summary. + * + * @returns A promise that resolves with an array of session metadata + * @throws Error if the client is not connected + * + * @example + * ```typescript + * const sessions = await client.listSessions(); + * for (const session of sessions) { + * console.log(`${session.sessionId}: ${session.summary}`); + * } + * ``` + */ + async listSessions() { + if (!this.connection) { + throw new Error("Client not connected"); + } + const response = await this.connection.sendRequest("session.list", {}); + const { sessions } = response; + return sessions.map((s) => ({ + sessionId: s.sessionId, + startTime: new Date(s.startTime), + modifiedTime: new Date(s.modifiedTime), + summary: s.summary, + isRemote: s.isRemote + })); + } + /** + * Gets the foreground session ID in TUI+server mode. + * + * This returns the ID of the session currently displayed in the TUI. + * Only available when connecting to a server running in TUI+server mode (--ui-server). + * + * @returns A promise that resolves with the foreground session ID, or undefined if none + * @throws Error if the client is not connected + * + * @example + * ```typescript + * const sessionId = await client.getForegroundSessionId(); + * if (sessionId) { + * console.log(`TUI is displaying session: ${sessionId}`); + * } + * ``` + */ + async getForegroundSessionId() { + if (!this.connection) { + throw new Error("Client not connected"); + } + const response = await this.connection.sendRequest("session.getForeground", {}); + return response.sessionId; + } + /** + * Sets the foreground session in TUI+server mode. + * + * This requests the TUI to switch to displaying the specified session. + * Only available when connecting to a server running in TUI+server mode (--ui-server). + * + * @param sessionId - The ID of the session to display in the TUI + * @returns A promise that resolves when the session is switched + * @throws Error if the client is not connected or if the operation fails + * + * @example + * ```typescript + * // Switch the TUI to display a specific session + * await client.setForegroundSessionId("session-123"); + * ``` + */ + async setForegroundSessionId(sessionId) { + if (!this.connection) { + throw new Error("Client not connected"); + } + const response = await this.connection.sendRequest("session.setForeground", { sessionId }); + const result = response; + if (!result.success) { + throw new Error(result.error || "Failed to set foreground session"); + } + } + on(eventTypeOrHandler, handler) { + if (typeof eventTypeOrHandler === "string" && handler) { + const eventType = eventTypeOrHandler; + if (!this.typedLifecycleHandlers.has(eventType)) { + this.typedLifecycleHandlers.set(eventType, /* @__PURE__ */ new Set()); + } + const storedHandler = handler; + this.typedLifecycleHandlers.get(eventType).add(storedHandler); + return () => { + const handlers = this.typedLifecycleHandlers.get(eventType); + if (handlers) { + handlers.delete(storedHandler); + } + }; + } + const wildcardHandler = eventTypeOrHandler; + this.sessionLifecycleHandlers.add(wildcardHandler); + return () => { + this.sessionLifecycleHandlers.delete(wildcardHandler); + }; + } + /** + * Start the CLI server process + */ + async startCLIServer() { + return new Promise((resolve, reject) => { + const args = [ + ...this.options.cliArgs, + "--headless", + "--no-auto-update", + "--log-level", + this.options.logLevel + ]; + if (this.options.useStdio) { + args.push("--stdio"); + } else if (this.options.port > 0) { + args.push("--port", this.options.port.toString()); + } + if (this.options.githubToken) { + args.push("--auth-token-env", "COPILOT_SDK_AUTH_TOKEN"); + } + if (!this.options.useLoggedInUser) { + args.push("--no-auto-login"); + } + const envWithoutNodeDebug = { ...this.options.env }; + delete envWithoutNodeDebug.NODE_DEBUG; + if (this.options.githubToken) { + envWithoutNodeDebug.COPILOT_SDK_AUTH_TOKEN = this.options.githubToken; + } + if (!existsSync(this.options.cliPath)) { + throw new Error( + `Copilot CLI not found at ${this.options.cliPath}. Ensure @github/copilot is installed.` + ); + } + const stdioConfig = this.options.useStdio ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"]; + const isJsFile = this.options.cliPath.endsWith(".js"); + if (isJsFile) { + this.cliProcess = spawn(process.execPath, [this.options.cliPath, ...args], { + stdio: stdioConfig, + cwd: this.options.cwd, + env: envWithoutNodeDebug + }); + } else { + this.cliProcess = spawn(this.options.cliPath, args, { + stdio: stdioConfig, + cwd: this.options.cwd, + env: envWithoutNodeDebug + }); + } + let stdout = ""; + let resolved = false; + if (this.options.useStdio) { + resolved = true; + resolve(); + } else { + this.cliProcess.stdout?.on("data", (data) => { + stdout += data.toString(); + const match = stdout.match(/listening on port (\d+)/i); + if (match && !resolved) { + this.actualPort = parseInt(match[1], 10); + resolved = true; + resolve(); + } + }); + } + this.cliProcess.stderr?.on("data", (data) => { + const lines = data.toString().split("\n"); + for (const line of lines) { + if (line.trim()) { + process.stderr.write(`[CLI subprocess] ${line} +`); + } + } + }); + this.cliProcess.on("error", (error) => { + if (!resolved) { + resolved = true; + reject(new Error(`Failed to start CLI server: ${error.message}`)); + } + }); + this.cliProcess.on("exit", (code) => { + if (!resolved) { + resolved = true; + reject(new Error(`CLI server exited with code ${code}`)); + } else if (this.options.autoRestart && this.state === "connected") { + void this.reconnect(); + } + }); + setTimeout(() => { + if (!resolved) { + resolved = true; + reject(new Error("Timeout waiting for CLI server to start")); + } + }, 1e4); + }); + } + /** + * Connect to the CLI server (via socket or stdio) + */ + async connectToServer() { + if (this.options.useStdio) { + return this.connectViaStdio(); + } else { + return this.connectViaTcp(); + } + } + /** + * Connect via stdio pipes + */ + async connectViaStdio() { + if (!this.cliProcess) { + throw new Error("CLI process not started"); + } + this.cliProcess.stdin?.on("error", (err) => { + if (!this.forceStopping) { + throw err; + } + }); + this.connection = (0, import_node.createMessageConnection)( + new import_node.StreamMessageReader(this.cliProcess.stdout), + new import_node.StreamMessageWriter(this.cliProcess.stdin) + ); + this.attachConnectionHandlers(); + this.connection.listen(); + } + /** + * Connect to the CLI server via TCP socket + */ + async connectViaTcp() { + if (!this.actualPort) { + throw new Error("Server port not available"); + } + return new Promise((resolve, reject) => { + this.socket = new Socket(); + this.socket.connect(this.actualPort, this.actualHost, () => { + this.connection = (0, import_node.createMessageConnection)( + new import_node.StreamMessageReader(this.socket), + new import_node.StreamMessageWriter(this.socket) + ); + this.attachConnectionHandlers(); + this.connection.listen(); + resolve(); + }); + this.socket.on("error", (error) => { + reject(new Error(`Failed to connect to CLI server: ${error.message}`)); + }); + }); + } + attachConnectionHandlers() { + if (!this.connection) { + return; + } + this.connection.onNotification("session.event", (notification) => { + this.handleSessionEventNotification(notification); + }); + this.connection.onNotification("session.lifecycle", (notification) => { + this.handleSessionLifecycleNotification(notification); + }); + this.connection.onRequest( + "tool.call", + async (params) => await this.handleToolCallRequest(params) + ); + this.connection.onRequest( + "permission.request", + async (params) => await this.handlePermissionRequest(params) + ); + this.connection.onRequest( + "userInput.request", + async (params) => await this.handleUserInputRequest(params) + ); + this.connection.onRequest( + "hooks.invoke", + async (params) => await this.handleHooksInvoke(params) + ); + this.connection.onClose(() => { + if (this.state === "connected" && this.options.autoRestart) { + void this.reconnect(); + } + }); + this.connection.onError((_error) => { + }); + } + handleSessionEventNotification(notification) { + if (typeof notification !== "object" || !notification || !("sessionId" in notification) || typeof notification.sessionId !== "string" || !("event" in notification)) { + return; + } + const session = this.sessions.get(notification.sessionId); + if (session) { + session._dispatchEvent(notification.event); + } + } + handleSessionLifecycleNotification(notification) { + if (typeof notification !== "object" || !notification || !("type" in notification) || typeof notification.type !== "string" || !("sessionId" in notification) || typeof notification.sessionId !== "string") { + return; + } + const event = notification; + const typedHandlers = this.typedLifecycleHandlers.get(event.type); + if (typedHandlers) { + for (const handler of typedHandlers) { + try { + handler(event); + } catch { + } + } + } + for (const handler of this.sessionLifecycleHandlers) { + try { + handler(event); + } catch { + } + } + } + async handleToolCallRequest(params) { + if (!params || typeof params.sessionId !== "string" || typeof params.toolCallId !== "string" || typeof params.toolName !== "string") { + throw new Error("Invalid tool call payload"); + } + const session = this.sessions.get(params.sessionId); + if (!session) { + throw new Error(`Unknown session ${params.sessionId}`); + } + const handler = session.getToolHandler(params.toolName); + if (!handler) { + return { result: this.buildUnsupportedToolResult(params.toolName) }; + } + return await this.executeToolCall(handler, params); + } + async executeToolCall(handler, request) { + try { + const invocation = { + sessionId: request.sessionId, + toolCallId: request.toolCallId, + toolName: request.toolName, + arguments: request.arguments + }; + const result = await handler(request.arguments, invocation); + return { result: this.normalizeToolResult(result) }; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { + result: { + // Don't expose detailed error information to the LLM for security reasons + textResultForLlm: "Invoking this tool produced an error. Detailed information is not available.", + resultType: "failure", + error: message, + toolTelemetry: {} + } + }; + } + } + async handlePermissionRequest(params) { + if (!params || typeof params.sessionId !== "string" || !params.permissionRequest) { + throw new Error("Invalid permission request payload"); + } + const session = this.sessions.get(params.sessionId); + if (!session) { + throw new Error(`Session not found: ${params.sessionId}`); + } + try { + const result = await session._handlePermissionRequest(params.permissionRequest); + return { result }; + } catch (_error) { + return { + result: { + kind: "denied-no-approval-rule-and-could-not-request-from-user" + } + }; + } + } + async handleUserInputRequest(params) { + if (!params || typeof params.sessionId !== "string" || typeof params.question !== "string") { + throw new Error("Invalid user input request payload"); + } + const session = this.sessions.get(params.sessionId); + if (!session) { + throw new Error(`Session not found: ${params.sessionId}`); + } + const result = await session._handleUserInputRequest({ + question: params.question, + choices: params.choices, + allowFreeform: params.allowFreeform + }); + return result; + } + async handleHooksInvoke(params) { + if (!params || typeof params.sessionId !== "string" || typeof params.hookType !== "string") { + throw new Error("Invalid hooks invoke payload"); + } + const session = this.sessions.get(params.sessionId); + if (!session) { + throw new Error(`Session not found: ${params.sessionId}`); + } + const output = await session._handleHooksInvoke(params.hookType, params.input); + return { output }; + } + normalizeToolResult(result) { + if (result === void 0 || result === null) { + return { + textResultForLlm: "Tool returned no result", + resultType: "failure", + error: "tool returned no result", + toolTelemetry: {} + }; + } + if (this.isToolResultObject(result)) { + return result; + } + const textResult = typeof result === "string" ? result : JSON.stringify(result); + return { + textResultForLlm: textResult, + resultType: "success", + toolTelemetry: {} + }; + } + isToolResultObject(value) { + return typeof value === "object" && value !== null && "textResultForLlm" in value && typeof value.textResultForLlm === "string" && "resultType" in value; + } + buildUnsupportedToolResult(toolName) { + return { + textResultForLlm: `Tool '${toolName}' is not supported by this client instance.`, + resultType: "failure", + error: `tool '${toolName}' not supported`, + toolTelemetry: {} + }; + } + /** + * Attempt to reconnect to the server + */ + async reconnect() { + this.state = "disconnected"; + try { + await this.stop(); + await this.start(); + } catch (_error) { + } + } +}; + +// src/index.ts +var import_debug = __toESM(require_src()); +var debug = (0, import_debug.default)("copilot-client"); +async function runCopilotSession(config) { + debug("Starting Copilot session with config:", config); + mkdirSync(dirname(config.eventLogFile), { recursive: true }); + const logEvent = (type, data, sessionId) => { + const event = { + timestamp: (/* @__PURE__ */ new Date()).toISOString(), + type, + sessionId, + data + }; + appendFileSync(config.eventLogFile, JSON.stringify(event) + "\n", "utf-8"); + debug("Event logged:", type); + }; + debug("Loading prompt from:", config.promptFile); + const prompt = readFileSync(config.promptFile, "utf-8"); + logEvent("prompt.loaded", { file: config.promptFile, length: prompt.length }); + debug("Creating Copilot client"); + const clientOptions = { + logLevel: config.logLevel ?? "info", + githubToken: config.githubToken, + useLoggedInUser: config.useLoggedInUser + }; + if (config.cliUrl) { + clientOptions.cliUrl = config.cliUrl; + } else { + clientOptions.cliPath = config.cliPath; + clientOptions.cliArgs = config.cliArgs; + clientOptions.port = config.port; + clientOptions.useStdio = config.useStdio ?? true; + clientOptions.autoStart = config.autoStart ?? true; + clientOptions.autoRestart = config.autoRestart ?? true; + } + const client = new CopilotClient(clientOptions); + logEvent("client.created", { + cliPath: config.cliPath, + useStdio: config.useStdio, + logLevel: config.logLevel + }); + debug("Starting Copilot client"); + await client.start(); + logEvent("client.started", {}); + let session = null; + try { + debug("Creating Copilot session"); + session = await client.createSession({ + model: config.session?.model, + reasoningEffort: config.session?.reasoningEffort, + systemMessage: config.session?.systemMessage ? { + mode: "replace", + content: config.session.systemMessage + } : void 0, + mcpServers: config.session?.mcpServers + }); + logEvent("session.created", { + sessionId: session.sessionId, + model: config.session?.model + }, session.sessionId); + debug("Setting up event handlers"); + session.on((event) => { + logEvent(`session.${event.type}`, event.data, session.sessionId); + debug("Session event:", event.type, event.data); + }); + const done = new Promise((resolve, reject) => { + let lastAssistantMessage = null; + session.on("assistant.message", (event) => { + lastAssistantMessage = event.data; + debug("Assistant message:", event.data.content); + }); + session.on("session.idle", () => { + debug("Session became idle"); + resolve(); + }); + session.on("session.error", (event) => { + debug("Session error:", event.data); + reject(new Error(event.data.message || "Session error")); + }); + }); + debug("Sending prompt"); + await session.send({ prompt }); + logEvent("prompt.sent", { prompt }, session.sessionId); + debug("Waiting for session to complete"); + await done; + debug("Session completed successfully"); + logEvent("session.completed", {}, session.sessionId); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + debug("Error during session:", errorMessage); + logEvent("session.error", { error: errorMessage }, session?.sessionId); + throw error; + } finally { + if (session) { + debug("Destroying session"); + try { + await session.destroy(); + logEvent("session.destroyed", {}, session.sessionId); + } catch (error) { + debug("Error destroying session:", error); + } + } + debug("Stopping client"); + try { + const errors = await client.stop(); + if (errors.length > 0) { + debug("Errors during client stop:", errors); + logEvent("client.stopped", { errors: errors.map((e) => e.message) }); + } else { + logEvent("client.stopped", {}); + } + } catch (error) { + debug("Error stopping client:", error); + } + } +} +async function main() { + debug("Reading configuration from stdin"); + const stdinBuffer = []; + await new Promise((resolve, reject) => { + process.stdin.on("data", (chunk) => { + stdinBuffer.push(chunk); + }); + process.stdin.on("end", () => { + resolve(); + }); + process.stdin.on("error", (error) => { + reject(error); + }); + }); + const configJson = Buffer.concat(stdinBuffer).toString("utf-8"); + debug("Received config:", configJson); + let config; + try { + config = JSON.parse(configJson); + } catch (error) { + console.error("Failed to parse configuration JSON:", error); + process.exit(1); + } + debug("Parsed config:", config); + try { + await runCopilotSession(config); + debug("Session completed successfully"); + process.exit(0); + } catch (error) { + console.error("Error running Copilot session:", error); + process.exit(1); + } +} + +export { main, runCopilotSession }; +//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/copilot-client/README.md b/copilot-client/README.md index b9df8e2cbaf..098e57a23dc 100644 --- a/copilot-client/README.md +++ b/copilot-client/README.md @@ -7,6 +7,7 @@ TypeScript client for running GitHub Copilot agentic sessions using the `@github - ES6 JavaScript with TypeScript annotations - Async/await for Node 24 - ESM module format +- Fully bundled with all dependencies included - JSONL event logging with timestamps - Debug package for logging - Configuration from stdin for testability @@ -18,7 +19,10 @@ npm install npm run build ``` -The compiled output will be in the `dist/` directory. +The build uses [tsup](https://tsup.egoist.dev/) to bundle the TypeScript source into a single ESM JavaScript file targeting Node 24 (ES2024). All dependencies are bundled into the output. The compiled output will be in the `dist/` directory: + +- `dist/index.js` - Main library entry point (fully bundled, ~190KB) +- `dist/index.d.ts` - TypeScript type declarations ## Usage diff --git a/copilot-client/package-lock.json b/copilot-client/package-lock.json index 6edc56655a1..d796a2ae277 100644 --- a/copilot-client/package-lock.json +++ b/copilot-client/package-lock.json @@ -17,6 +17,7 @@ "devDependencies": { "@types/debug": "^4.1.12", "@types/node": "^24.0.0", + "tsup": "^8.5.1", "typescript": "^5.9.3", "vitest": "^4.0.18" }, @@ -593,6 +594,27 @@ "copilot-win32-x64": "copilot.exe" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -600,6 +622,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.57.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", @@ -1121,6 +1154,26 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -1131,6 +1184,32 @@ "node": ">=12" } }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", @@ -1141,6 +1220,49 @@ "node": ">=18" } }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -1172,6 +1294,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -1245,6 +1368,18 @@ } } }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1260,6 +1395,46 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -1270,12 +1445,37 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -1295,6 +1495,16 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", @@ -1326,7 +1536,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -1334,6 +1543,28 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -1363,6 +1594,73 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/rollup": { "version": "4.57.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz", @@ -1415,6 +1713,16 @@ "dev": true, "license": "ISC" }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -1439,6 +1747,52 @@ "dev": true, "license": "MIT" }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -1483,12 +1837,90 @@ "node": ">=14.0.0" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tsup": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", + "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tsup/node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1497,6 +1929,13 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", diff --git a/copilot-client/package.json b/copilot-client/package.json index 403c0ab91ed..aca7cf8d41f 100644 --- a/copilot-client/package.json +++ b/copilot-client/package.json @@ -12,7 +12,8 @@ "node": ">=24.0.0" }, "scripts": { - "build": "tsc", + "build": "tsup", + "postbuild": "cp dist/index.js ../actions/setup/js/copilot-client.js", "test": "vitest run", "test:watch": "vitest", "typecheck": "tsc --noEmit", @@ -25,6 +26,7 @@ "devDependencies": { "@types/debug": "^4.1.12", "@types/node": "^24.0.0", + "tsup": "^8.5.1", "typescript": "^5.9.3", "vitest": "^4.0.18" } diff --git a/copilot-client/test-local.sh b/copilot-client/test-local.sh index 01e60360055..b84ad62b2e1 100755 --- a/copilot-client/test-local.sh +++ b/copilot-client/test-local.sh @@ -53,7 +53,7 @@ cat /tmp/copilot-client-test/config.json # Run the client with debug logging echo "" echo "Running copilot-client..." -DEBUG=copilot-client cat /tmp/copilot-client-test/config.json | node dist/cli.js +DEBUG=copilot-client cat /tmp/copilot-client-test/config.json | node -e "import('./dist/index.js').then(m => m.main())" # Check results echo "" diff --git a/copilot-client/tsup.config.ts b/copilot-client/tsup.config.ts new file mode 100644 index 00000000000..2c047898ad5 --- /dev/null +++ b/copilot-client/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: { + index: 'src/index.ts', + }, + format: ['esm'], + target: 'es2024', + platform: 'node', + outDir: 'dist', + dts: true, + sourcemap: true, + clean: true, + bundle: true, + splitting: false, + treeshake: true, + minify: false, + // Bundle all dependencies (no external dependencies) + noExternal: [/.*/], +});